【问题标题】:Convert string of base64 back to base64 bytes将base64字符串转换回base64字节
【发布时间】:2018-06-24 22:41:25
【问题描述】:

我使用 OpenCV 上传了一张图片,然后使用 base64b64encode 使用 base64 编码对其进行编码。

>>> import cv2
>>> import base64
>>> image = cv2.cvtColor(cv2.imread("some_image.jpg"), cv2.COLOR_BGR2RGB)
>>> image_64 = base64.b64encode(image)
>>> image_64
b'//////////////////...
>>> type(image_64)
<class 'bytes'>

然后我使用str() 方法将其转换为字符串。这将创建一个编码图像的字符串。

>>> image_64str = str(image_64)
>>> image_64str
b'//////////////////...
>>> type(image_64str)
<class 'str'>

它们(&lt;class 'bytes'&gt; 类型和&lt;class 'str'&gt;)看起来很相似。我尝试使用base64b64decodedecode() 函数对它们进行解码。但是,当我解码image_64str时出现错误。

>>> image_64str.decode()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute 'decode'
>>> base64.b64decode(image_64str)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/base64.py", line 87, in b64decode
    return binascii.a2b_base64(s)
binascii.Error: Incorrect padding

我完全理解错误试图告诉我什么。但我的问题是,如何将编码图像 (image_64str) 的字符串转换回字节?

我尝试在字符串上再次使用base64 的'b64encode`。但是,它返回一个错误。

>>> str_to_b64 = base64.b64encode(image_64str)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/base64.py", line 58, in b64encode
    encoded = binascii.b2a_base64(s, newline=False)
TypeError: a bytes-like object is required, not 'str'

请告诉是否有人注意到我遗漏了什么。我正在使用 Python 3.6。提前致谢。

编辑:为我的问题添加更多描述。

我能够启用 AWS API Gateway 二进制支持。我的目的是通过 POST 请求将图像作为二进制数据传递给 API,并将其转换为 PIL 对象,以便我可以使用 AWS Lambda 在后端处理它。使用 API Gateway,二进制数据使用 base64 二进制编码。

我使用 python 的open 函数将图像作为二进制数据打开(我想通过 API 传递两个图像)。然后我用我用字典来保存这两个图像的二进制数据,比如

data = {"data1": img_binary_data_1, "data2": img_binary_data_2}

我使用 python request 库发送 POST 请求。我可以在post 函数中传递的参数之一是data,所以我使用它传递了图像数据。

我能够发送请求。在 Lambda 后端,我想将二进制数据转换为 PIL 对象以进行进一步处理。但是,数据似乎被打包成 JSON 格式,并且 base64 编码的二进制图像已被转换为 python 字符串。我通过打印 AWS CloudWatch 日志中的数据确认了这一点。

我尝试使用.decode(),但基础here 无法解码字符串。

我能够使用b64decode() 解码字符串,返回一个字节对象。但是,当尝试将其转换为 PIL 对象时,例如

img = imread(io.BytesIO(base64.b64decode(b64_string)))

我收到一个错误提示

OSError: cannot identify image file &lt;_io.BytesIO object at 0x1101dadb0&gt;

我尝试了this link 的一些解决方案,但显然你不能用字节对象来做到这一点。

我尝试过使用PIL.frombufferPIL.frombytes。但是,当我非常确定图像的尺寸(在本例中为 (256, 256))时,它们返回了 not enough data 值。

所以我的问题是,如何将 base64 图像转换为 PIL 对象? 我希望这有助于更好地理解我的问题。提前致谢。

【问题讨论】:

  • image_64str.encode() 应该返回正确的字节表示吗?
  • 你为什么要把它转换成字符串?
  • @LaneTerry running image_64str.encode() 对编码图像的字符串进行编码。如果我尝试解码它,它会返回编码图像的字符串和编码图像本身。
  • @IgnacioVazquez-Abrams 我正在尝试将其传递给 AWS API Gateway。我仍在尝试找出 AWS 二进制支持,所以我认为我可以使用 url 查询字符串参数将二进制数据作为字符串传递。
  • @Imperator123 在您的示例中,您没有在字符串上调用 .encode() 。抱歉我的英语不清楚,但我想说.encode() 方法将返回字符串的字节表示。但是,鉴于您的上述响应,您能否不将数据作为八位字节流通过 API Gateway 传递并在 API Gateway 后面的实现中处理它?

标签: python python-3.x base64 aws-api-gateway


【解决方案1】:

Base64 是一种二进制 -> 字符编码,因此对图像进行编码是有意义的,您会得到 text 字节,其中一组 6 位被视为一个字符。

现在即使上面的字节是字符,它们也不是 python 字符串,因为 python 字符串是 utf-8。

当您将字节转换为字符串时,它会将它们转换为 utf-8 并弄乱 base64 填充(仅允许使用 = 进行填充),您得到的是一个 python 字符串。

现在解码时会出现错误,因为它不再是 base64 编码。 您也不能将字符串编码为 base64 是字节 -> char 并且字符串不是字节。

为什么还要将编码字节转换为字符串?对您的用例进行更多描述会有所帮助。

【讨论】:

    猜你喜欢
    • 2016-10-21
    • 2021-12-12
    • 1970-01-01
    • 2012-07-21
    • 2014-12-22
    • 2016-10-21
    • 1970-01-01
    • 2017-07-22
    • 2014-11-05
    相关资源
    最近更新 更多