解码Base64编码的裁剪人脸图像时出现黑屏数据损坏问题
解决Base64编码解码人脸图像后黑屏损坏的问题
嘿,我一眼就瞅出问题出在哪了——你解码后得到的只是一堆一维的字节数组,根本没还原成原图像的形状和通道结构,OpenCV完全不知道该怎么解析这堆数据,自然就输出黑屏啦。咱们一步步来修复这个问题:
问题根源
你的代码里,编码时把numpy.ndarray转成字节串没问题,但解码后只做了numpy.fromstring(),得到的是一维数组,而OpenCV的imwrite需要的是和原图像一致的二维(灰度图)或三维(彩色图)数组。直接把一维数组丢给它,它没法识别图像的尺寸和通道,生成的文件自然损坏。
修复方案
核心就是编码时记录图像形状,解码后还原形状,具体步骤如下:
1. 编码阶段:保存图像的形状信息
在把图像转成Base64之前,先获取原图像的shape(包含高度、宽度、通道数),这个信息是解码后还原图像的关键。
2. 解码阶段:还原图像的形状
拿到解码后的字节数组后,用numpy.reshape()把它恢复成原图像的形状,再传给OpenCV保存。
修改后的代码示例
import cv2 import numpy as np import base64 import json def create_learn_msg(db_name, person_name, last_location, images, labels): json_string = {} # 处理图像2的编码和解码测试 original_img = images[1] cv2.imwrite('faces/original-image.png', original_img) print(type(original_img)) # <type 'numpy.ndarray'> # 记录原图像的形状 img_shape = original_img.shape # 转成字节串并编码(用tobytes替代tostring,更规范) image_string = original_img.tobytes() encode_string = base64.b64encode(image_string) # 解码测试 decode_string = base64.b64decode(encode_string) # 用frombuffer替代fromstring(numpy新版本已弃用fromstring) decode_image = np.frombuffer(decode_string, dtype=np.uint8) # 还原成原图像的形状 decode_image = decode_image.reshape(img_shape) print(type(decode_image)) # <type 'numpy.ndarray'> cv2.imwrite('faces/decode-image.png', decode_image) # 构建JSON数据时,建议把形状信息也带上,方便接收方解码 json_string['data'] = { 'type': "learn", 'db_name': db_name, 'person_name': person_name, 'last_location': last_location, 'image1': base64.b64encode(images[0].tobytes()).decode('utf-8'), # 转成字符串避免JSON序列化问题 'image1_shape': images[0].shape, 'image2': base64.b64encode(original_img.tobytes()).decode('utf-8'), 'image2_shape': img_shape, 'label1': labels[0], 'label2': labels[1] } return json.dumps(json_string)
额外注意点
- 用
tobytes()替代tostring():tostring()是numpy的旧方法,现在官方推荐用tobytes(),语义更清晰。 - 用
frombuffer()替代fromstring():fromstring()在numpy 1.19+版本已被弃用,frombuffer()兼容性更好。 - Base64编码后转成字符串:直接把
base64.b64encode()的结果(字节类型)放到JSON里可能会有序列化问题,所以用.decode('utf-8')转成字符串再存储。
这样修改后,解码后的图像就能正确还原,不会再出现黑屏损坏的情况啦!
内容的提问来源于stack exchange,提问作者Farshid616
相关产品推荐
相关产品推荐

