使用eval函数检查PIL中像素状态

3 投票
2 回答
6133 浏览
提问于 2025-04-16 16:12

有没有办法使用PIL中的eval函数来遍历所有像素,同时检查每个像素的值是什么?这个程序会检查一张图片,看看每个像素的RGB值是否符合某个条件,如果符合,就把这个像素变成透明的。PIL中的eval函数似乎可以完成这个任务,但我想知道我的像素转换函数能否检查它当前处理的像素的值?谢谢!

2 个回答

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

原始图像
转换后的图像

原始回答: 是的,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)

撰写回答