【问题标题】:How to convert Python numpy array to base64 output如何将 Python numpy 数组转换为 base64 输出
【发布时间】:2017-09-04 18:14:41
【问题描述】:

我基本上需要做this,但是用 Python 而不是 Javascript。我从 socketio 连接接收到一个 base64 编码的字符串,将其转换为 uint8 并处理它,然后需要将其转换为 base64 字符串,以便我可以将其发回。

所以,到目前为止,我已经得到了这个(我正在从 socketio 服务器获取data 字典):

import pickle
import base64
from io import BytesIO
from PIL import Image

base64_image_string = data["image"]
image = Image.open(BytesIO(base64.b64decode(base64_image_string)))
img = np.array(image)

如何反转这个过程以从img 回到base64_image_string

更新:
我已经通过以下方式解决了这个问题(继续上面的代码 sn-p):

pil_img = Image.fromarray(img)
buff = BytesIO()
pil_img.save(buff, format="JPEG")
new_image_string = base64.b64encode(buff.getvalue()).decode("utf-8")

有点令人困惑,new_image_stringbase64_image_string 不完全相同,但从 new_image_string 渲染的图像看起来相同,所以我很满意!

【问题讨论】:

  • 看来saveJPEG是一个损失函数。然后解码的图像字符串不再等同于原始图像。
  • @MeadowMuffins 使用另一种无损格式,例如 PNG

标签: python arrays base64


【解决方案1】:

我相信既然numpy.arrays 支持缓冲协议,你只需要以下内容:

processed_string = base64.b64encode(img)

所以,例如:

>>> encoded = b"aGVsbG8sIHdvcmxk"
>>> img = np.frombuffer(base64.b64decode(encoded), np.uint8)
>>> img
array([104, 101, 108, 108, 111,  44,  32, 119, 111, 114, 108, 100], dtype=uint8)
>>> img.tobytes()
b'hello, world'
>>> base64.b64encode(img)
b'aGVsbG8sIHdvcmxk'
>>>

【讨论】:

  • 这太棒了!但是,当我反序列化时,我的 3-D numpy 数组只显示为 1-D - 我必须 reshape 使用数组携带的原始形状的值,还是有办法绕过 reshape?谢谢!
  • 这很丑,但我最终做了:payload = ('nparr',img.shape,base64.b64encode(img.copy(order='C'))) 并相应地反序列化。有没有解决的办法?非常感谢!
  • @jtlz2 没有,但是您是否考虑过像numpy.save 这样的另一种序列化方法?
  • 谢谢,我试过这条路线(见stackoverflow.com/a/43925741/1021819)——但最后我认为通过网络使用base64比使用字节串更安全。您对哪个更可取有看法吗?
  • @jtlz2 抱歉,但我并没有真正关注。 Base64 产生一个字节串。它在什么意义上更安全? numpy.save 跨平台的便携性要高得多,可以处理诸如字节顺序之类的事情以及盒子的形状。如果我选择没有任意限制,我无疑会使用 numpy.save 而不是 base64 编码。它可能更快,而且内存占用肯定更少
【解决方案2】:

我也有同样的问题。经过一番搜索和尝试,我的最终解决方案与您的几乎相同。

唯一的区别是base64编码的字符串是png格式的数据,所以我需要把它从RGBA改成RGBchannels才转换成np.array:

image = image.convert ("RGB")
img = np.array(image)

在逆过程中,你将数据视为JPEG格式,这可能是new_image_stringbase64_image_string不完全相同的原因?

【讨论】:

    【解决方案3】:

    来自http://www.programcreek.com/2013/09/convert-image-to-string-in-python/

    import base64
    
    with open("t.png", "rb") as imageFile:
        str = base64.b64encode(imageFile.read())
        print str
    

    是二进制读取

    https://docs.python.org/2/library/base64.html

    【讨论】:

    • 等等,你为什么要把numpy数组转换成utf-8?
    • base64 字母表是 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=" Base64 ist ein Verfahren zur Kodierung von 8-Bit-Binärdaten (z. B. ausführbare Programme, ZIP-Dateien oder Bilder)这意味着 Base 64 是一种编码 8 位二进制数据(即可执行文件、ZIP 文件或图像)的标准
    • ...是的,那又怎样?
    • 这是一个字节数组(uint8)。请参阅我发布的示例。无论如何,我不确定您为什么认为转换为 utf8 会有所帮助...
    • 好吧,我不知道 numpy 数组是按字节构造的,因为通常我将它们与浮点、整数等组合数据类型一起使用...
    猜你喜欢
    • 1970-01-01
    • 2012-01-17
    • 1970-01-01
    • 2012-01-23
    • 2021-05-15
    • 2019-12-10
    • 1970-01-01
    • 2021-12-18
    • 1970-01-01
    相关资源
    最近更新 更多