views.py:
from PIL import Image
img_list =os.listdir(final_path)
frontend_images = []
for images in img_list:
frontend_path = final_path+str(images)
image = Image.open(frontend_path)
frontend_images.append(image)
print(frontend_images)
return render(request,'images.html',{'images':frontend_images})
I am sending the images to the frontend for displaying in frontend
images.html
{% for img in images %}
<img src='{{img}}'/>
{% endfor %}
Its not displayed in frontend is there other approach to retrieve images from directory and display it in frontend
Related
I will preface by saying this is my first time working with flask & HTML to build a web app, so I may be using the wrong terminology in some places, apologies in advance.
I have used these two previous questions as reference for what i'm doing:
Flask render a word cloud
Passing a matplotlib figure to HTML (flask)
I am working a web app that allows a user to input a movie, and a wordcloud is returned.
The user starts on /search, where they input a movie name, I then redirect to /search_results where a list of movies with similar names are shown, the user selects the right film and submits. This part of the journey is all working fine, from here I take the movie name, I then apply a function I have built in python that creates a wordcloud based on this film name (in my code below this is what the function wordcloud_generator(1,session['search_value']) is doing in the fig route). The output of the wordcloud_generator() function is:
...
img = BytesIO()
wordcloud.to_image().save(img, 'PNG')
img.seek(0)
return img
I want to save this image to a route "/fig/<wordcloud_img>" and then be able to call it in the src of an img tag in the route "/images/<wordcloud_img>".
When running through this I get the error of at the point that I submit the movie name from /search_results and redirect to 'images'. Error: werkzeug.routing.BuildError: Could not build url for endpoint 'images'. Did you forget to specify values ['wordcloud_img']?
After this if I navigate manually to "localhost:5000/fig/wordcloud_img" then my function seems to run and the image is shown, and then if I manually navigate to "localhost:5000/images/wordcloud_img" the image is properly surfaced in the html.
It seems like I am doing this in the wrong order somehow and the function isn't running/generating the image before I try to access it on the /images source.
Routes
def search():
if request.method == 'POST':
movie_search = request.form['search_text']
session['returned_movies'], session['search_links'] = search_function(search_term = movie_search)
return redirect(url_for('search_result'))
return render_template('search.html',title='Search')
#app.route("/search_result", methods=['GET', 'POST'])
def search_result():
if request.method == 'POST':
movie = request.form['movie']
session['search_value'] = session['search_links'][session['returned_movies'].index(movie)]
return redirect(url_for('images'))
return render_template('search_results.html',title='Search Results')
#app.route("/images/<wordcloud_img>")
def images(wordcloud_img):
return render_template("wordcloud.html")
#app.route("/fig/<wordcloud_img>")
def fig(wordcloud_img):
img = wordcloud_generator(1,session['search_value'])
return send_file(img, mimetype='image/png')
wordcloud.html
{% extends "layout.html" %}
{% block content %}
<div>
{% if session['search_value'] %}
<p>Searching for a movie: {{ session['search_value'] }}</p>
{% else %}
<p>Oops, no movie selected </p>
{% endif %}
<body>
<img src="{{ url_for('fig', wordcloud_img = 'wordcloud_img') }}" alt="Image Placeholder" height="100">
</body>
</div>
{% endblock content %}
The problem is that you are not passing the image to the 'images' function that displays the template with the image. In your 'search_result' function, you will need to pass the wordcloud_image to the 'images' function like so:
return redirect(url_for('images'), wordcloud_img=your_image)
(replacing your_image with the actual image variable)
In your images route, you would then need to pass this received image to the template:
return render_template("wordcloud.html", wordcloud_img=wordcloud_img)
Then in your template, you can use this wordcloud_img variable like this:
<img src="{{ url_for('fig', wordcloud_img=wordcloud_img) }}" alt="Image Placeholder" height="100">
I want to read some local images(.jpg) from a local file path, then display those images on a web page(127.0.0.1:8000) by using flask and python3.I have already display single image on web page by use the following code:
from flask import Flask,render_template
app = Flask(__name__)
def return_img_stream(img_local_path):
import base64
img_stream = ''
with open(img_local_path, 'rb') as img_f:
img_stream = img_f.read()
img_stream = base64.b64encode(img_stream).decode()
return img_stream
#app.route('/')
def hello_world():
img_path = 'D:\\1111\\1.jpg'
img_stream = return_img_stream(img_path)
return render_template('index.html',img_stream=img_stream)
if __name__ == '__main__':
app.run(debug=True,host='127.0.0.1',port=8080)
How should I modify return_img_stream and hello_world function to use flask read multi images stream and send it to 'index.html' template?
EDIT:
If you would have images in folder static then you could send only list with filenames and use for-loop in template to generate tags like <img src="/static/1.jpg">
#app.route('/')
def hello_world():
#filenames = os.listdir('static')
filenames = ['1.jpg', '2.jpg']
return render_template('index.html', filenames=filenames)
template
{% for name in filenames %}
<img src="/static/{{ name }}">
{% endfor %}
If you need to use base64 then you have to use for-loop in Flask
#app.route('/')
def hello_world():
#filenames = os.listdir('D:\\1111')
#filenames = [os.path.join('D:\\1111', name) for name in filenames]
filenames = ['D:\\1111\\1.jpg', 'D:\\1111\\2.jpg']
images = []
for img_path in filenames:
img_stream = return_img_stream(img_path)
images.append(img_stream)
return render_template('index.html', images=images)
template
{% for img in images %}
<img src="data:image/jpeg;base64, {{ img }}">
{% endfor %}
EDIT:
If you would merge all images to create single image then you would need modules like pillow or opencv to convert jpg to raw image, merge them, convert it back to single jpg.
EDIT:
If you want to add images with some text (ie. with filename) then you have to create list with pairs (image, text) and {% for img, txt in images %} and put text using {{ txt }}
#app.route('/')
def hello_world():
#filenames = os.listdir('D:\\1111')
#filenames = [os.path.join('D:\\1111', name) for name in filenames]
filenames = ['D:\\1111\\1.jpg', 'D:\\1111\\2.jpg']
images = []
for img_path in filenames:
img_stream = return_img_stream(img_path)
images.append( [img_stream, img_path ])
return render_template('index.html', images=images)
template
{% for img, txt in images %}
filename: {{ txt }}<br/>
<img src="data:image/jpeg;base64, {{ img }}">
{% endfor %}
But if you mean text on image then it may need pillow to edit images and put text on images.
Or you will have to learn CSS for positioning elements in HTML.
<style>
div.image { ... }
div.image span { ... }
</style>
{% for img, txt in images %}
<div class="image">
<span>filename: {{ txt }}</span>
<img src="data:image/jpeg;base64, {{ img }}">
<div>
{% endfor %}
This is how I wrote the gallery function which is supposed to display images stored in MongoDB using GridFS:
#app.route('/gallery/<username>')
def gallery(username):
user = db.users.find_one({'username': username})
images = user['images']
for img in images:
image = grid_fs.get(img)
base64_data = codecs.encode(image.read(), 'base64')
image = base64_data.decode('utf-8')
return render_template('gallery.html')
How am I supposed to write the HTML document in order for the photos to be displayed?
First, you need to return data to template:
return render_template('gallery.html', **images)
And then you can use it in your template like this:
{% for img in images %}
<img src="data:image/png;base64, {{ img }}">
{% endfor %}
I am new to Flask framework and I am trying to dispaly a few images like wordcloud, graphs and piecharts generated in the program on flask. I'm trying to store the images generated in image list and then return it. Then use that in the HTML file to display each image. Over here I am just entering the wordcloud generation section and the app.route part.
from wordcloud import WordCloud
import base64
images = []
def analyse(df)
# genrate a word cloud image
wordcloud = WordCloud(
background_color='white',
max_words=200,
max_font_size=40,
scale=3,
random_state=42
).generate(str(df["Review"]))
figfile3 = BytesIO()
plt.savefig(figfile3, format='png')
figfile3.seek(0) # rewind to beginning of file
wordcloudimg = base64.b64encode(figfile3.getvalue())
images.append(wordcloudimg)
return images
df["Review"] has textual reviews.
#app.route('/')
def finaldef():
images = analyse(df)
return render_template('pages.html', image=images)
if __name__ == "__main__":
app.run(debug=True)
A section of the pages HTML file is
{% block head %}
<title>Pages</title>
{% endblock %}
{% block body %}
<h1>Images</h1>
{% for i in image %}
<img src="data:image/png;base64,{{ i }}" width="500">
{% endfor %}
{% endblock %}
The output comes as image symbols but not the wordcloud that I had generated.
I would really appreciate the help.
Thank You
I'll take a guess, as I haven't been able to test with the word cloud library.
base64.b64encode returns an object of type bytes.
The fix might simply be to decode the return value of this, so you get type str. Modify your code to do this:
wordcloudimg = base64.b64encode(figfile3.getvalue()).decode('utf-8')
i am using google app engine with django to make a small application that it has these features
upload images ,
show images ,
minipulate images (rotate)
well after finishing part 1 , now i am somewhere stuck in part 2 where i need to show images.
i did everything i retrieved the image keys, but the images are not showing.
only the titles of the images i saved in the datastore.
here is my code:
<ul>
{% for image in image.all %}
<li>{{ image.title }} </li>
<li> <img src="/pictures/models.{{image.key}}"/> </li>
{% endfor %}
</ul>
Assuming
You uploaded the images to the blobstore
image.key is the blobstore key
You have a handler named BlobstoreImageHandler for /pictures/models\.(.*)/
Then you'd do something like
class BlobstoreImageHandler(blobstore.handler.BlobstoreDownloadHandler):
def get(self, resource):
resourse = str(urllib.unquote(resource))
blob_info = blobstore.BlobInfo.get(resource)
self.send_blob(blob_info)
which is straight out of http://code.google.com/appengine/docs/python/blobstore/overview.html#Serving_a_Blob