我哪里错了?我想从字节创建一个基本的白色图片
from PIL import Image
if __name__ == "__main__":
data = [chr(1)] * 8192
data = "".join(data)
im = Image.frombytes('1', (128,64), data, 'raw')
im = im.convert("RGB")
im.save("image.png", "PNG")
但我明白了:
在模式1
中,每个字节代表8个像素(如果宽度不除以8,则每行末尾可能有零填充)。因此,要获得白色图像,您必须仅传入字节b'\xff'
data = b'\xff' * 1024
im = Image.frombytes('1', (128,64), data)
即使Pillow文档说这个模式中每个字节有一个像素,至少对于frombytes
和tobytes
方法来说也是如此。
除了\xff
(全白)或\x00
(全黑)之外的任何其他重复输入都会给出某种细条纹图案,就像你问题中那样。
只需使用Image.new
代替:
im = Image.new(mode='RGB', size=(128,64), color=(255,255,255))
如果你真的想从字节中创建它,它将是这样的:
Image.frombytes(mode='RGB', size=(128,64), data=b'\xff'*128*64*3)
编辑:Image.frombytes
需要字节,而不是整数列表。要将整数列表转换为正确的类型,请使用以下命令:
>>> bytes([0,1,2]) # Python 3
b'\x00\x01\x02'
>>> bytes(bytearray([0,1,2])) # Python 2
'\x00\x01\x02'
编辑2:mode ='1'或文档有bug(参见注释线程)。假设你有一个0和1的列表,1024个元素长,并且你想将它转换为128x64单色图像(每像素一位),那么你将不得不手动打包字节:
bits = [int(not (y%13 and x%7)) for x in range(64) for y in range(128)]
# asymmetric grid
octets = [bits[i:i+8] for i in range(0, len(bits), 8)]
def bits2byte(bits8):
result = 0
for bit in bits8:
result <<= 1
result |= bit
return result
data = bytes(bytearray([bits2byte(octet) for octet in octets]))
im = Image.frombytes(mode='1', size=(128,64), data=data)
im.show()
结果: