如何将PIL图像转换为Base64编码字符串

9
在过去的几个小时中,我一直在尝试创建一张图片的Base64字符串,但是它无法正常工作。
ship_color = (0,100,100,255)
img = Image.new("RGBA", (100,100))
for i in range(20):
   for j in range(20):
       img.putpixel((40 + i, 40 + j), ship_color)
img.save("tmp.png", format = "PNG")
im = open("tmp.png", "rb").read()
print(im)
base = base64.b64encode(im)
print(base)

当我尝试从字符串创建图像时,我会遇到异常:

img2 = Image.frombytes("RGBA", (100, 100), base)
ValueError: not enough image data

其他在线的Base64解码服务也会出现错误,因此该Base64字符串本身似乎不正确。

示例图像字符串(来自open().read()):

b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00d\x00\x00\x00d\x08\x02\x00\x00\x00\xff\x80\x02\x03\x00\x00\x00lIDATx\x9c\xed\xd0\xd1\t\x800\x10\x05\xc1h\xad)+\xc5Z\xc3\x8a\x10"3\xff\xc7;v\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x008\xc7\xb5my\xce\xf7\xb7k}\xf7GpoY=\x94X\x81X\x81X\x81X\x81X\x81X\x81X\x81X\x81X\x81X\x81X\x81X\x81X\x81X\x81X\x81X\x81X\x81X\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0S\x0fX\xb7\x02(\x90HP\xa2\x00\x00\x00\x00IEND\xaeB`\x82'

示例base64字符串:

b'iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAIAAAD/gAIDAAAAbElEQVR4nO3Q0QmAMBAFwWitKSvFWsOKECIz/8c7dgwAAAAAAAAAAAAAADjHtW15zve3a333R3BvWT2UWIFYgViBWIFYgViBWIFYgViBWIFYgViBWIFYgViBWIFYgVgAAAAAAAAAAAAAAPBTD1i3AiiQSFCiAAAAAElFTkSuQmCC'

你的代码哪里进行了base64编码数据的操作? - Alastair McCormack
@AlastairMcCormack所说的是,你正在使用base64.b64decode(im)编码图像。 - Robert
@Robert,我的错,方法不对^^ 但是b64encode仍然会出现相同的异常。 - Vlad de Elstyr
那么现在你解码的部分在哪里? - Alastair McCormack
您的字符串解码正常,在bash提示符中:echo“iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAIAAAD/gAIDAAAAbElEQVR4nO3Q0QmAMBAFwWitKSvFWsOKECIz/8c7dgwAAAAAAAAAAAAAADjHtW15zve3a333R3BvWT2UWIFYgViBWIFYgViBWIFYgViBWIFYgViBWIFYgViBWIFYgVgAAAAAAAAAAAAAAPBTD1i3AiiQSFCiAAAAAElFTkSuQmCC”| base64 -D> test.png。 您需要进行编码解码 - Alastair McCormack
2个回答

15

在解码之前,您需要进行base64 编码

您可以通过使用内存文件,即io.BytesIO(),而无需创建临时文件来实现此目的。

in_mem_file = io.BytesIO()
img.save(in_mem_file, format = "PNG")
# reset file pointer to start
in_mem_file.seek(0)
img_bytes = in_mem_file.read()

base64_encoded_result_bytes = base64.b64encode(img_bytes)
base64_encoded_result_str = base64_encoded_result_bytes.decode('ascii')

谢谢,现在它已经运行正常了。最后问题出在Python中字节表示的b''前缀,所以我首先需要将其转换为字符串,然后再切掉前几个字符。 对于任何好奇的人: base = base64.b64encode(im) base.decode() base = str(base) base = base[2:len(base)- 1] 对我起作用。 - Vlad de Elstyr
不,不是那样做。你只需要使用'ascii'将字节对象解码为文本。结果是一个str。请参见更新的答案。 - Alastair McCormack
节省了我大量的时间。谢谢! - Hvitis

0

Image.frombytes() 不会从 base64 编码的字符串中创建图像,请参阅文档

如果您想要反转编码,请使用:

img2 = base64.b64decode(base)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接