发送 OpenCV 图像并使用 base64 解码:为什么不兼容?

Send OpenCV image and decode using base64: why not compatible?

我需要将图像编码为二进制文件,将其发送到服务器并再次解码回图像。 解码方式为:

def decode_from_bin(bin_data):
    bin_data = base64.b64decode(bin_data)
    image = np.asarray(bytearray(bin_data), dtype=np.uint8)
    img = cv2.imdecode(image, cv2.IMREAD_COLOR)

    return img

我们使用 OpenCV 对图像进行编码:

def encode_from_cv2(img_name):
    img = cv2.imread(img_name, cv2.IMREAD_COLOR)  # adjust with EXIF
    bin = cv2.imencode('.jpg', img)[1]
    return str(base64.b64encode(bin))[2:-1] # Raise error if I remove [2:-1]

您可以 运行 使用:

raw_img_name = ${SOME_IMG_NAME}

encode_image = encode_from_cv2(raw_img_name)
decode_image = decode_from_bin(encode_image)

cv2.imshow('Decode', decode_image)
cv2.waitKey(0)

我的问题是:为什么我们必须从 base64 编码中去除前两个字符?

我们来分析一下里面发生了什么encode_from_cv2.

base64.b64encode(bin) 的输出是一个 bytes 对象。 当您将它传递给 str(base64.b64encode(bin)) 中的 str 时,str 函数会创建 bytes 对象的“可打印”版本,请参阅 .

实际上 str 代表打印时看到的 bytes 对象,即前导 b' 和尾随 '。 例如

>>> base64.b64encode(bin)
b'/9j/4AAQSkZJRgABAQAAAQABAAD'
>>> str(base64.b64encode(bin))
"b'/9j/4AAQSkZJRgABAQAAAQABAAD'"

这就是为什么您需要删除这些字符以获得编码字符串。

一般来说,这不是将 bytes 对象转换为字符串的最佳方法,因为需要一种编码来指定如何将 bytes 解释为字符。这里的 str 函数使用默认的 ASCII 编码。

this answer 中所述,您可以替换 str(base64.b64encode(bin))[2:-1]str(base64.b64encode(bin), "utf-8") 去掉切片。