Flask上传图片需用file.read()读取二进制数据,PIL用BytesIO(data)加载,OpenCV用np.frombuffer(data, np.uint8)转数组后cv2.imdecode;处理后返回前须output_buffer.seek(0)并指定mimetype。

Flask 接收上传图片时,request.files 拿到的是流,不能直接传给 cv2.imread 或 PIL.Image.open
OpenCV 和 Pillow 都不接受文件上传的 FileStorage 对象,直接传会报错:TypeError: Expected str, bytes or os.PathLike object, not FileStorage。必须先读取内容,再用内存方式加载。
- 用
file.read()读取二进制数据,然后用io.BytesIO包装成类文件对象 - Pillow:传给
PIL.Image.open(BytesIO(data)) - OpenCV:用
np.frombuffer(data, np.uint8)转为 numpy 数组,再用cv2.imdecode - 别忘了加
file.seek(0)—— 如果你之前调过file.filename或其他属性,内部指针可能已偏移,导致读出来空
用 Pillow 做缩放/裁剪/转格式,要注意 save 的 io.BytesIO 必须 seek(0) 才能返回给前端
Flask 返回图片要用 send_file 或直接构造 Response,但 BytesIO 写完后指针在末尾,不重置就啥也读不到,浏览器收到空响应或损坏图片。
- 缩放示例:
img.resize((w, h), PIL.Image.LANCZOS),注意LANCZOS比默认的NEAREST更清晰 - 保存前务必调
output_buffer.seek(0),否则send_file(output_buffer, ...)返回空白 - 指定
mimetype,比如"image/jpeg",否则浏览器可能无法识别(尤其.webp) - 如果用户上传了
.png但你要转.jpeg,记得img = img.convert("RGB"),否则save(..., "JPEG")会报ValueError: could not save color palette
用 OpenCV 处理完图像后,cv2.imencode 返回的是 tuple,不是 bytes
cv2.imencode(".jpg", img) 返回的是 (True, ndarray),其中 ndarray 是 uint8 类型的一维数组,不是原生 bytes。直接丢给 BytesIO 会出错。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
- 正确做法:
success, encoded_img = cv2.imencode(".jpg", img),然后用encoded_img.tobytes()获取字节 - 别漏掉
success判断,编码失败(如传入空图、通道数异常)时返回False,不检查会导致后续tobytes()报错 - OpenCV 默认 BGR,Pillow 默认 RGB —— 如果混用(比如用 CV 读 + Pillow 显示),颜色会发紫;统一用
cv2.cvtColor(img, cv2.COLOR_BGR2RGB)转下 - WebP 支持有限:
cv2.imencode(".webp", img, [cv2.IMWRITE_WEBP_QUALITY, 95])可以,但老版本 OpenCV 不支持,建议 Pillow 处理 WebP 更稳
部署时常见崩溃点:多线程下 cv2 的全局状态和 Pillow 的字体缓存
Flask 默认多线程(threaded=True),而 cv2 的某些函数(如 cv2.putText)内部有共享字体资源,高并发时可能 segfault;Pillow 的 ImageFont.truetype 缓存也非线程安全。
立即学习“Python免费学习笔记(深入)”;
- 避免在请求中动态加载字体:
ImageFont.truetype("simhei.ttf", 16)放在模块顶层,复用对象 - OpenCV 文字绘制尽量用
cv2.FONT_HERSHEY_SIMPLEX等内置字体,避开putText的 freetype 分支 - 生产环境别用 Flask 自带 server(
app.run()),改用 Gunicorn +--threads 1或--worker-class sync,避免多线程触发 CV 底层冲突 - 如果必须并发处理图像,优先选 Pillow —— 它的纯 Python 实现更可控,OpenCV 更适合单次批量或离线任务

















