使用PIL将二进制字符串转换为图像

8

所以,我的目的是让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创建一个像素与二进制字符串匹配的图像?

它应该看起来像这样。: screenshot

到目前为止,我得到了以下关于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个回答

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')

但是这次的it测试表明使用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

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)

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