Return multiple image files with Flask

谁说我不能喝 提交于 2021-02-18 07:59:32

问题


First I've searched a lot and didn't find a straight forward answer to my question yet.

I'm writing a new program which accepts an image and then find similar images to it and then extract image names from a database. I've created a simple response with the name of these image files as a JSON format with Flask in python3. I need to display these images with its name under it as a web page with a response in Flask. The major problem is the number of images are not fixed and may vary, sometimes it became as 10 and sometimes as 0. Actually, I'm not familiar with Flask or HTML, but I need to do it. Here is my sample code which response the image names as an array:

from flask import Flask, jsonify, request, redirect, send_file
import numpy
import os
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}

app = Flask(__name__)


def allowed_file(filename):
    return '.' in filename and \
           filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS


@app.route('/', methods=['GET', 'POST'])
def upload_image():
    # Check if a valid image file was uploaded
    if request.method == 'POST':
        if 'file' not in request.files:
            return redirect(request.url)

        file = request.files['file']

        if file.filename == '':
            return redirect(request.url)

        if file and allowed_file(file.filename):
            # The image file seems valid! Detect faces and return the result.
            return detect_faces_in_image(file)

    # If no valid image file was uploaded, show the file upload form:
    return '''
    <!doctype html>
    <title>Face System</title>
    <h1>Upload a picture and see if it's a picture of database!</h1>
    <form method="POST" enctype="multipart/form-data">
      <input type="file" name="file">
      <input type="submit" value="Upload">
    </form>
    '''


def detect_faces_in_image(file_stream):
    ...     #some coding to create the founded_file_names
    out=founded_file_names      #array of desired file names
    return jsonify(out)
if __name__ == "__main__":
    app.run(host='0.0.0.0', port=5001, debug=True)

Thanks.


回答1:


First things first, please don't hardcode HTML into your python file. Make a templates/ directory, and put all of this html into a file, lets say homepage.html. You can then use return render_template('homepage.html') to render the html.


Now, for the main question.

The major problem is the number of images are not fixed and may vary, sometimes it became as 10 and sometimes as 0.

That won't be a problem if you use Jinja, which is included in flask. If you're not familiar with it, have a look at the docs.

Looking at your code, the best way to do it would be the following: after the user submitted his image, you can show another page, lets say results.html(which you should put in templates/), and then show the pics there.

from flask import Flask, jsonify, request, redirect, send_file
import numpy
import os
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}

app = Flask(__name__)


def allowed_file(filename):
    return '.' in filename and \
           filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS


@app.route('/', methods=['GET', 'POST'])
def upload_image():
    # Check if a valid image file was uploaded
    if request.method == 'POST':
        if 'file' not in request.files:
            return redirect(request.url)

        file = request.files['file']
        if file.filename == '':
            return redirect(request.url)

        if file and allowed_file(file.filename):
            # The image file seems valid!
            # Get the filenames and pass the on to the results.html page
            return render_template(
                'results.html', results=detect_faces_in_image(file)
            )

    # If no valid image file was uploaded, show the file upload form:
    return render_template('homepage.html')


def detect_faces_in_image(file_stream):
    # .. do something here ...
    return file_names_found # list of the filenames, no need for JSON

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=5001, debug=True)

Now, the front end. Here is a rough draft of what results.html could look like:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Results</title>
</head>
<body>
    {% if results %}
        <table>
            <tbody>
            {% for img_name in results %}
                <tr>
                    <td>{{ img_name }}</td>
                    <td><img src="/pathtoyourimg" alt="{{ img_name }}"></td>
                </tr>
            {% endfor %}
            </tbody>
        </table>
    {% else %}
        No results :(
    {% endif %}
</body>
</html>

You can see that the Jinja syntax is very similar to python (if/else, for .. in ..). To use a variable, you must surround it with {{ }}. What HTML file does is:

  • check whether results if an empty list
    • if it is, display 'no results :('
    • if it isn't, then display a html table. for each result, we make a row (<tr>) and display the name on the left, and the image on the right

You should store all of your images in a folder named static/ next to the python script. If you do so, src="/pathtoyourimg" becomes src="static/{{ img_name }}"



来源:https://stackoverflow.com/questions/44728047/return-multiple-image-files-with-flask

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!