如何将前端FormData中的图片转换为Flask后端的numpy数组?
解决Flask后端将FormData图片转为numpy数组并传入模型的问题
我最近在做一个前端上传图片到Flask后端,再用模糊画质提升模型处理的功能,但卡在了把FormData里的图片转换成numpy数组这一步——试了转bytes、cv2读取各种方法都没搞定。附上前后端代码,求大佬给个清晰的解决方向!
前端现有代码
const fd = new FormData(); fd.append("project", this.imgUrl); const options = { method: "POST", body: fd, }; // delete options.headers["Content-Type"]; fetch("http://172.16.1.34:1234/api/test", options) .then(res => res) .then(res => { console.log(res); }) .catch(err => console.log(err));
后端现有代码
def test(): # if request.method == 'POST': # print('Here') # print(request.files) # something = request.form['project'] # print(something) # # print(type(something)) # print(len(something)) # img = cv2.imread(something) # image = process_image(img) # print("im here") if request.method == 'POST': print("inside") photo = request.form['project'] print(photo) # try: # delete_files("./temp_results") # except: # pass # filename = secure_filename(image.filename) # image.save(os.path.join(app.config['UPLOAD_FOLDER'], filename)) # # img_name = os.listdir("./temp_results")[0] # # image = cv2.imread('./temp_results/' + img_name) # print(image.shape) # # processed_image = process_image(image) # scipy.misc.imsave("./temp_results/temp.png", processed_image) return jsonify({'Hello': True}) # scipy.misc.imsave(image,'./temp_results/temp.png') # return send_file("./temp_results/temp.png", attachment_filename='temp.png')
问题根源&解决步骤
1. 前端先传对文件!
你现在前端append的是this.imgUrl——这应该是图片的URL字符串,不是实际的文件数据!FormData要传File对象才能让后端正确解析成文件。
修正后的前端代码(假设你用文件选择框获取图片):
// 假设你的文件选择框id是"imageUpload" const fileInput = document.getElementById("imageUpload"); const selectedFile = fileInput.files[0]; if (!selectedFile) { console.log("请先选择图片!"); return; } const fd = new FormData(); fd.append("project", selectedFile); // 传File对象,不是URL! const options = { method: "POST", body: fd }; // 必须保留这行:删除手动设置的Content-Type,FormData会自动生成带boundary的正确头 delete options.headers["Content-Type"]; fetch("http://172.16.1.34:1234/api/test", options) .then(res => res.json()) .then(res => { console.log(res); }) .catch(err => console.log(err));
2. 后端正确读取文件并转numpy数组
后端现在用request.form['project']是错的——上传的文件存在request.files里,不是form。而且不能直接用cv2.imread(它读的是文件路径),要从内存中的字节数据解码。
修正后的后端核心代码:
import cv2 import numpy as np from flask import request, jsonify # 你的模糊画质提升模型函数 def process_image(img): # 这里替换成你实际的模型处理逻辑 # 示例:临时用边缘检测代替 return cv2.Canny(img, 100, 200) @app.route('/api/test', methods=['POST']) def test(): if request.method == 'POST': # 检查是否有文件上传 if 'project' not in request.files: return jsonify({'error': '没有上传文件'}), 400 photo = request.files['project'] if photo.filename == '': return jsonify({'error': '未选择文件'}), 400 # 读取文件字节数据 img_bytes = photo.read() # 将字节转为numpy数组,再用cv2解码成图像 np_array = np.frombuffer(img_bytes, np.uint8) img = cv2.imdecode(np_array, cv2.IMREAD_COLOR) # 检查图像是否解码成功 if img is None: return jsonify({'error': '图像解码失败'}), 400 # 传入模型处理 processed_img = process_image(img) # 这里可以返回处理后的结果,比如图像的形状或者编码后的图片 return jsonify({ 'success': True, 'original_shape': img.shape, 'processed_shape': processed_img.shape })
3. 避坑提醒
- 前端不要手动设置
Content-Type: multipart/form-data:FormData会自动生成带boundary的正确请求头,手动设置会导致后端无法解析文件。 - 后端用
cv2.imdecode而不是imread:imread是从磁盘文件读取,而我们要处理的是内存中的上传文件字节。 - 一定要检查解码后的
img是否为None:如果前端传的不是有效图片,解码会失败,提前判断避免模型报错。
内容的提问来源于stack exchange,提问作者Yash Gaur
相关产品推荐
相关产品推荐

