flask框架上传图片问题归档


这里post接收数据后,并没有保存成文件,而是全部在内存中操作,减少文件IO有利于提高使用效率,如有需要,可以通过cv2.imwirite()方法实现持久化

  • flask接收post方法传递json数据,包含base64编码的图像
@app.route('/imagePredictJSON',methods=['Post'])
def imagePredictJSON():
    data = request.json
    try:
        base64str = data['data']['image'].split(',')[1]
        image = base64_to_image(base64str)
        pred_2 = predict_frame(image)
    except Exception as e:
        print(e)
        abort(500)
    finally:
        return jsonify({"status":0, "message":"success","data":{"count":len(pred_2),"results":pred_2}})

记住几个知识点,

  1. json数据通过request.json获得
  2. 需要将头部去除,base64前面的是头部,说明了文件类型,通过base64_str.split(‘,’)[1]获取图片数据,这部分也可以放到前端完成
  3. base64转成cv2图像函数需要另写,为
def base64_to_image(base64_code):
    # base64解码
    img_data = base64.b64decode(base64_code)
    # 转换为np数组
    img_array = np.fromstring(img_data, np.uint8)
    # 转换成opencv可用格式
    img = cv2.imdecode(img_array, cv2.COLOR_RGB2BGR)
    return img
  • flask接收post方法表单数据
@app.route('/imagePredict',methods=['post'])
def imagePredict():
    img  = request.files['image']
    print(type(img))
    img = Image.open(img.stream)
    img = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)
    pred_2 = predict_frame(img)
    return jsonify({"status":0, "message":"success","data":{"count":len(pred_2),"results":pred_2}})

这里的知识点是:

1.form上传的文件通过request.files[‘filed_name’]得到,得到的是一个文件流

2.Image方法是PIL提供的,需要引入 :from PIL import Image

3.文件流写入到内存后,需要通过cvtColor将文件的数组转换成cv2的格式,便于后面调用

  • flask接口返回图片流

这里情况有点特殊,我做的项目是前端上传一张图,请求接口之后想要返回处理后的图,用于演示,为了不产生实体文件,直接在内存中处理完了就返回前端。所以这里只能使用post方法,

from flask import Flask, send_file, render_template, Response, jsonify, request, abort
from PIL import Image
import cv2
@app.route('/imageTest',methods=['post'])
def imagePredictTest():
    # img = cv2.imread('./data/4.jpg')
    img  = request.files['image']
    img = Image.open(img.stream)
    img = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)
    pred_2,image = predict_frame(img)
    print(image)
    ret, jpeg = cv2.imencode('.jpg', image)
    frame = jpeg.tobytes()
    return Response( (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n'),
            mimetype='multipart/x-mixed-replace; boundary=frame')

这里的知识点是:

1.request中拿到的是文件流,需要把流读到内存中要使用Image.open(img.stream)方法

2.上述方法得到的是一个图片类型的实例,需要进一步转为cv2的图片类型,img = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)

3.cv2的图像不能直接返回给前端,前端需要二进制的jpeg格式的或者其它,这里以jpeg为例,需要cv2编码成jpg格式,然后构造一个二进制的返回消息

返回前端


文章作者: 无名小卒
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 无名小卒 !
  目录