Python Flask 中通过 POST 方法发送和接收回图像

sha*_*an7 1 python post image flask

我想通过 POST 方法将图像发送到服务器(例如通过 Postman),然后将相同的图像发送回用户。这是我所拥有的,我不知道如何将图像返回给用户并提供一些响应,例如 200, 。

from flask import Flask, request, Response, send_file, jsonify
from PIL import Image
app = Flask(__name__)

@app.route('/')
def index():
    return 'Server Works!'


@app.route('/processing', methods=['POST'])
def process():
    file = request.files['image']
    img = Image.open(file.stream)
    
    return jsonify({'msg': 'success', 'size': [img.width, img.height]})
Run Code Online (Sandbox Code Playgroud)

这可以正确获取图像并发送回一些信息,例如宽度和高度,但我想要的是返回带有响应代码的相同图像。感谢您的建议

fur*_*ras 6

如果您只想发送图像,那么您可以按send_file()原样发送(以字节形式)。然后浏览器就可以直接显示了。

但是如果你想发送带有 JSON 中其他值的图像,那么你必须将其从字节转换为base64并添加到JSON

data = file.stream.read()
data = base64.encodebytes(data)

return jsonify({'msg': 'success', 'size': [img.width, img.height], 'img': data})
Run Code Online (Sandbox Code Playgroud)

稍后您需要 JavaScript 代码将其转换回来并canvas在浏览器中使用显示 - 或者它在 url 中<img>使用创建base64-

对于 jpeg:

<img src="data:image/jpeg;base64,...base64 data...">
Run Code Online (Sandbox Code Playgroud)

对于PNG:

<img src="data:image/png;base64,...base64 data...">
Run Code Online (Sandbox Code Playgroud)

因此您还必须发送图像信息 - JPG 或 PNG。

img.format
Run Code Online (Sandbox Code Playgroud)

以 JSON 格式发送图像的最少工作代码

from flask import Flask, request, jsonify
from PIL import Image
import base64

app = Flask(__name__)

@app.route('/')
def index():
    return '''Server Works!<hr>
<form action="/processing" method="POST" enctype="multipart/form-data">
<input type="file" name="image">
<button>OK</button>
</form>    
'''

@app.route('/processing', methods=['POST'])
def process():
    file = request.files['image']
    
    img = Image.open(file.stream)
    
    data = file.stream.read()
    #data = base64.encodebytes(data)
    data = base64.b64encode(data).decode()   

    return jsonify({
                'msg': 'success', 
                'size': [img.width, img.height], 
                'format': img.format,
                'img': data
           })
    
if __name__ == '__main__':
    app.run(debug=True)
Run Code Online (Sandbox Code Playgroud)

如果您想在更改后发送图像(而不写入磁盘),则需要使用io.Bytes()将对象转换PIL.Image为内存中的压缩文件。

我还展示了如何直接在 HTML 中使用 base64 图像

@app.route('/processing', methods=['POST'])
def process():
    file = request.files['image']
    
    img = Image.open(file.stream)
    img = img.convert('L')   # ie. convert to grayscale

    #data = file.stream.read()
    #data = base64.b64encode(data).decode()
    
    buffer = io.BytesIO()
    img.save(buffer, 'png')
    buffer.seek(0)
    
    data = buffer.read()
    data = base64.b64encode(data).decode()
    
    #return jsonify({
    #            'msg': 'success', 
    #            'size': [img.width, img.height], 
    #            'format': img.format,
    #            'img': data
    #       })

    return f'<img src="data:image/png;base64,{data}">'
Run Code Online (Sandbox Code Playgroud)