使用Pillow和Python 3从RGB列表创建图像

时间:2018-01-16 11:03:57

标签: python image python-imaging-library pillow stringio

我有一个RGB数据列表:

cdata=[R1, G1, B1, R2, G2, B2,..., Rn, Gn, Bn]

其中每个值介于0到255之间。

我正在尝试使用Pillow 5.0.0将此数组重建为图像。 在Python 2下,我能够以这种方式将值列表转换为字节串:

        cdata2 = []
        gidx = len(cdata)//3
        bidx = len(cdata)//3*2
        for i in range(len(cdata)//3):
            cdata2.append(cdata[i])
            cdata2.append(cdata[i+gidx])
            cdata2.append(cdata[i+bidx])

        data = ""
        for c in cdata2:
            data += chr(c)

        im = Image.frombytes("RGB", (420, 560), data)

然后在base64中重新编码'im'并在HTML模板中将其显示为PNG。

不幸的是,这在Python 3中不起作用,我遇到了错误:

UnicodeEncodeError: 'charmap' codec can't encode characters in position 42099-42101: character maps to <undefined>

此外,Pillow 5文档现在建议使用

im = Image.open(StringIO(data))

但无法使用上面构建的字符串。有没有更聪明的方法来做到这一点?非常感谢您的帮助。

3 个答案:

答案 0 :(得分:4)

以下是使用predicate.and(entity.tags.eqAll(<whatever>)); 的示例。这只是使用纯Python,没有Numpy。如果您正在使用Numpy创建RGB值,那么您可以使用frombytes方法将Numpy数据转换为PIL图像。

这里重要的一步是将RGB值列表转换为Image.fromarray对象,这可以通过将其传递给bytes构造函数来轻松完成。

bytes

<强>输出

hue & saturation demo image

答案 1 :(得分:3)

使用Image.frombytesImage.open用于打开编码图像(如jpg或png),而不是原始RGB数据。

使用bytes构造函数构建所需的字节数据是微不足道的:

img_bytes = bytes([R1, G1, B1, R2, G2, B2,..., Rn, Gn, Bn])

然后我们可以像这样创建一个图像:

im = Image.frombytes("RGB", (width, height), img_bytes)

答案 2 :(得分:1)

如果你想拥有不错的Python2和Python3兼容代码,你可以使用struct或array module:

# Works from Python 2.5 (maybe earlier) to Python 3.x
import struct
cdata = [...]
bindata = struct.pack("<%dB" % len(cdata), *cdata)
# And then use PIL's Image.frombytes() to construct the Image() from bindata

或者:

import array
cdata = [...]
a = array.array("B", cdata)
bindata = a.tostring()
# And then use PIL's Image.frombytes() to construct the Image() from bindata
# This should be faster than struct, but I didn't test it for speed