先把当时的情况摆出来。服务端用 opencv-python 4.10 的 cv2.imdecode 解码前端上传的图片,接口拿到的是 base64 解出来的 bytes,imdecode 经常返回 None,日志里没有任何异常,只看到后面 cv2.cvtColor 抛出的断言失败。同一份数据写到本地文件再 imread 是正常的。
这类报错背后常见的原因有几处,逐个排除就行。上传时按 4KB 分片读取,拼接顺序错了导致文件头不完整。还有一种是base64 解码后残留 data:image/png;base64, 前缀没有剥掉。
另外,bytes 被当成 str 传进 imdecode,走了另一个编码分支。少数情况下是中间件对请求体解压过一次,旧数据里留着 gzip 头。
第一件事是打印开头字节看是不是真图片
python -c "b=open('raw.bin','rb').read();print(len(b), b[:8])"
去掉 base64 前缀后再解码
python -c "import base64;s=open('b64.txt').read().split(',')[-1];open('raw.bin','wb').write(base64.b64decode(s))"
接着用文件方式验证这张图能否正常打开
python -c "import cv2;im=cv2.imread('raw.bin');print(None if im is None else im.shape)"
剩下的就是改成从 numpy 缓冲区解码并检查返回值
python -c "import cv2,numpy as np;b=open('raw.bin','rb').read();im=cv2.imdecode(np.frombuffer(b,np.uint8),cv2.IMREAD_COLOR);print(im is None)"
怎么算真的好了,看的是同一批现象。imdecode 返回的 ndarray 形状为 (1080,1920,3),前端上传的 20 张样本全部解码成功,失败分支会明确写日志。
补一句。imdecode 失败只返回 None 不抛异常,一定要显式判断并当成错误上报,否则问题会拖到业务层才暴露,排查成本翻几倍。如果同一现象隔几天又出现,说明根因没找到,别当偶发处理。
