将二进制字符串转换为图像使用PIL
我想做的是用PIL这个库根据一串二进制字符串创建一张图片。
先说一下背景:
from PIL import Image
value = "0110100001100101011011000110110001101111"
vdiv = [value[i:i+8] for i in range(0, len(value), 8)]
这段代码会把二进制字符串转换成一个字节列表,像这样:['01101000', '01100101',.....]
def diff(inp):
if inp == '1':
return (0,0,0)
if inp == '0':
return (255,255,255)
else:
pass
这段代码会为每个对应的位返回一个颜色元组。如果我调用:
for i in vdiv:
for i2 in i:
print diff(i2)
它会打印出每个字节中每个位的颜色元组,像这样:(0,0,0) (0,0,0) (255,255,255)...
我想知道的是,怎么让PIL创建一张图片,让每个像素的颜色和这个二进制字符串相匹配呢?
这张图片应该是这样的::
这是我目前为PIL写的代码:
img = Image.new( 'RGB', (8,len(vdiv)), "white")
pixels = img.load()
##
for x in range(img.size[0]):
for y in range(img.size[1]):
for i in vdiv:
for i2 in i:
pixels[x,y] = diff(i2) #Creates a black image. What do?
##
img.show()
让我困惑的是那段for x in range
的部分。我有点迷茫。
2 个回答
1
对于每个像素只有1位的图像:
im = Image.new('1', (image_width, image_height), "black")
cmap = {'0': 0,
'1': 1}
data = [cmap[letter] for letter in data_bin]
im.putdata(data)
5
你可以使用 img.putdata
方法:
import Image
value = "0110100001100101011011000110110001101111"
cmap = {'0': (255,255,255),
'1': (0,0,0)}
data = [cmap[letter] for letter in value]
img = Image.new('RGB', (8, len(value)//8), "white")
img.putdata(data)
img.show()
如果你有安装 NumPy,可以使用 Image.fromarray
方法:
import Image
import numpy as np
value = "0110100001100101011011000110110001101111"
carr = np.array([(255,255,255), (0,0,0)], dtype='uint8')
data = carr[np.array(map(int, list(value)))].reshape(-1, 8, 3)
img = Image.fromarray(data, 'RGB')
img.save('/tmp/out.png', 'PNG')
不过这次的时间测试显示,使用 putdata
方法会更快:
value = "0110100001100101011011000110110001101111"*10**5
def using_fromarray():
carr = np.array([(255,255,255), (0,0,0)], dtype='uint8')
data = carr[np.array(map(int, list(value)))].reshape(-1, 8, 3)
img = Image.fromarray(data, 'RGB')
return img
def using_putdata():
cmap = {'0': (255,255,255),
'1': (0,0,0)}
data = [cmap[letter] for letter in value]
img = Image.new('RGB', (8, len(value)//8), "white")
img.putdata(data)
return img
In [79]: %timeit using_fromarray()
1 loops, best of 3: 1.67 s per loop
In [80]: %timeit using_putdata()
1 loops, best of 3: 632 ms per loop