PIL 使用 eval 函数检查像素是否开启

3
有没有办法使用PIL中的eval函数遍历所有像素并检查每个值?该程序通过图像以查看每个像素是否为某种rgb,如果是,则将该像素变为透明。 PIL中的eval函数似乎可以完成此任务,但是我的转换像素的功能能够检查它所在的像素的值吗?谢谢提前。
2个回答

11

更新:啊,我明白你想做什么了。这里有一个只使用PIL的示例。它将所有白色像素转换为带有50%透明度的红色:

import Image

img = Image.open('stack.png').convert('RGBA')
width, _ = img.size
for i, px in enumerate(img.getdata()):
    if px[:3] == (255, 255, 255):
        y = i / width
        x = i % width
        img.putpixel((x, y), (255, 0, 0, 127))

img.save('stack-red.png')

original
converted

原始回答: 是的,Image.eval() 函数允许您传入一个函数来评估每个像素,并允许您确定新的像素值:

import Image
img1 = Image.open('foo.png')
# replace dark pixels with black
img2 = Image.eval(img1, lambda px: 0 if px <= 64 else px)

2
新的像素值?嗯,我不是完全理解这个函数,抱歉...但我能理解的是,它检查像素是否小于64,如果是,则将其转换为零?我是对的吗?如果是这样,那么如何设置像素值从绿色变化?如何找到图像的“像素值”? - Nick
我添加了一个例子,应该更接近你所寻找的。 - samplebias
如果性能是一个问题:putpixel 不比 img.getdata() 上的 __setitem__ 慢得多吗?换句话说:d=img.getdata() for i,px in enumerate(d): ... d[i] = (255,0,0,127) - Paul
此外,它似乎没有执行getitem,就像Paul所说的那样。属性错误。 - Nick
@samplebias 或许值得一提的是,在 Python 3.x 中,y = i / width 必须改为 y = i // width - sougonde

3
不,eval不会将RGB元组传递给函数。它会将函数映射到每个波段。但是,您可以使用eval处理每个波段,然后使用ImageChops操作逻辑地组合这些波段,并获得像素元组特定的掩码。
顺便说一下,如果您愿意,这可以在NumPy中更加清洁和高效地完成。
import numpy as np
import Image
import ImageChops
im_and = ImageChops.lighter

im = Image.open('test.png')
a = np.array(im)

R,G,B,A = im.split()

color_matches = []
for level,band in zip((255,255,255), (R,G,B)):
    b = Image.eval(band, lambda px: 255-(255*(px==level)))
    color_matches.append(b)

r,g,b = color_matches
mask = im_and(r, im_and(g, b))
im.putalpha(mask)
im.save('test2.png')

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