PIL中是否有Image.point()方法能同时操作三个通道?

4 投票
2 回答
2172 浏览
提问于 2025-04-16 09:01

我想写一个点过滤器,这个过滤器是根据每个像素的红色、绿色和蓝色通道来工作的,但看起来这可能不够用,因为point()似乎一次只能处理一个像素的一个通道。我想做的事情是这样的:

def colorswap(pixel):
    """Shifts the channels of the image."""
    return (pixel[1], pixel[2], pixel[0])
image.point(colorswap)

有没有类似的方法,可以让我使用一个接受RGB三元组的过滤器,并输出一个新的三元组呢?

2 个回答

2

根据目前的回答,我猜答案是“没有”。

不过你可以使用numpy来高效地完成这类工作:

def colorswap(pixel):
    """Shifts the channels of the image."""
    return (pixel[1], pixel[2], pixel[0])

def npoint(img, func):
    import numpy as np
    a = np.asarray(img).copy()
    r = a[:,:,0]
    g = a[:,:,1]
    b = a[:,:,2]
    r[:],g[:],b[:] = func((r,g,b))
    return Image.fromarray(a,img.mode)

img = Image.open('test.png')
img2 = npoint(img, colorswap)
img2.save('test2.png')

额外提示:看起来Image类不是只读的,这意味着你可以让你新的npoint函数感觉更像point(不过不推荐这样做,因为可能会让人困惑):

Image.Image.npoint = npoint

img = Image.open('test.png')
img2 = img.npoint(colorswap)
3

你可以使用 load 方法来快速获取所有像素的信息。

def colorswap(pixel):
    """Shifts the channels of the image."""
    return (pixel[1], pixel[2], pixel[0])

def applyfilter(image, func):
    """ Applies a function to each pixel of an image."""
    width,height = im.size
    pixel = image.load()
    for y in range(0, height):
        for x in range(0, width):
            pixel[x,y] = func(pixel[x,y])

applyfilter(image, colorswap)

撰写回答