PIL中是否有Image.point()方法能同时操作三个通道?
我想写一个点过滤器,这个过滤器是根据每个像素的红色、绿色和蓝色通道来工作的,但看起来这可能不够用,因为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)