I want to write a point filter that is based on the red, green and blue channels for each pixel, but it appears that this might fall short of point()
's abilities -- it开发者_如何学Go seems that it operates on a single pixel in a single channel at a time. I'd like to do something like this:
def colorswap(pixel):
"""Shifts the channels of the image."""
return (pixel[1], pixel[2], pixel[0])
image.point(colorswap)
Is there an equivalent method that lets me use a filter that takes in a 3-tuple of RGB values and output a new 3-tuple?
You can use the load
method to get fast access to all the pixels.
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)
Based on the responses to date, I'd guess the answer is 'no'.
But you could always employ numpy to do this kind of work efficiently:
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')
Bonus: It looks like the Image class is not read-only, which means you can make your new npoint
function feel even more like point
(not recommended unless like confusing people):
Image.Image.npoint = npoint
img = Image.open('test.png')
img2 = img.npoint(colorswap)
精彩评论