如何通过WebSocket从JavaScript前端向Flask后端发送图片?
问题解决方法
客户端修改
直接发送File对象会因Socket.IO无法序列化而失败,必须将文件转成可序列化的格式后再发送,以下是两种可行方案:
方案1:二进制数组传输
async function handleSubmit(event) { event.preventDefault(); if (!file.value.length) return; const selectedFile = file.files[0]; const reader = new FileReader(); reader.onload = (e) => { // 将ArrayBuffer转为Uint8Array后发送 const arrayBuffer = e.target.result; const uint8Array = new Uint8Array(arrayBuffer); socket.emit('socket_request', uint8Array); }; reader.readAsArrayBuffer(selectedFile); }
方案2:Base64字符串传输
async function handleSubmit(event) { event.preventDefault(); if (!file.value.length) return; const selectedFile = file.files[0]; const reader = new FileReader(); reader.onload = (e) => { // 发送Base64编码后的字符串 const base64Data = e.target.result; socket.emit('socket_request', base64Data); }; reader.readAsDataURL(selectedFile); }
服务器端对应处理
根据客户端发送的格式,在服务器端做对应解析:
对应方案1(二进制数组)
import cv2 import numpy as np @socket_io.on('socket_request') def foo(arg): # 将二进制数据转为numpy数组,解码为OpenCV格式图片 nparr = np.frombuffer(arg, np.uint8) img = cv2.imdecode(nparr, cv2.IMREAD_COLOR) # 示例:处理后返回原图片(可替换为自定义逻辑) image = cv2.imencode('.png', img)[1].tobytes() emit('socket_respond', image, broadcast=False)
对应方案2(Base64字符串)
import cv2 import numpy as np import base64 @socket_io.on('socket_request') def foo(arg): # 去除Base64前缀,解码为二进制数据 base64_data = arg.split(',')[1] img_bytes = base64.b64decode(base64_data) # 转为numpy数组并解码为图片 nparr = np.frombuffer(img_bytes, np.uint8) img = cv2.imdecode(nparr, cv2.IMREAD_COLOR) # 处理后返回 image = cv2.imencode('.png', img)[1].tobytes() emit('socket_respond', image, broadcast=False)
核心原因说明
Socket.IO默认消息序列化机制不支持File对象,必须将文件转换为二进制数组或字符串这类可直接序列化的格式,服务器端再反向解析为OpenCV可处理的图片数据。
内容的提问来源于stack exchange,提问作者S.Y. Kim
相关产品推荐
相关产品推荐

