2009-04-25 68 views
1

我試圖使用PIL將圖像Magick 命令(使用Fx Special Effects Image Operator)的某些圖像處理功能移植到Python。我 的問題是,我不完全理解這是什麼FX運營商正在做:使用PIL將ImageMagick FX運算符轉換爲純Python代碼

convert input.png gradient.png -fx "v.p{0,u*v.h}" output.png 

從一個高的水平,該命令從梯度圖像 (gradient.png)主罰顏色,並將其應用於如調色板(input.png),寫入輸出圖像(output.png)。

從我已經想通了,ü是輸入圖像,v是梯度,並且它是通過 每最左邊的像素梯度會從上到下, 莫名其妙將其顏色應用於輸入圖像。

我無法用頭圍繞如何以編程方式與 PIL做同樣的事情。我想到的最好的辦法是將圖像轉換爲調色板 圖像(向下採樣爲256色),並從像素訪問對象的漸變中單獨獲取顏色 。

import Image 

# open the input image 
input_img = Image.open('input.png') 

# open gradient image and resize to 256px height 
gradient_img = Image.open('gradient.png') 
gradient_img = gradient_img.resize((gradient_img.size[0], 256,)) 

# get pixel access object (significantly quicker than getpixel method) 
gradient_pix = gradient_img.load() 

# build a sequence of 256 palette values (going from bottom to top) 
sequence = [] 
for i in range(255, 0, -1): 
    # from rgb tuples for each pixel row 
    sequence.extend(gradient_pix[0, i]) 

# convert to "P" mode in order to use putpalette() with built sequence 
output_img = input_img.convert("P") 
output_img.putpalette(sequence) 

# save output file 
output_img = output_img.convert("RGBA") 
output_img.save('output.png') 

這有用,但正如我所說的,它下采樣到256色。這不僅是 這是一種凌亂的做事方式,它導致了一個非常糟糕的輸出 圖像。我怎麼能重複Magick的功能,而不會將 的結果填入265色?

編:忘了舉blog where I found the original Magick command

回答

1

我知道它已經一個月左右,你可能已經想通了。但這是答案。

從ImageMagicK文檔中我能夠理解實際效果。

convert input.png gradient.png -fx "v.p{0,u*v.h}" output.png 

v is the second image (gradient.png) 
u is the first image (input.png) 
v.p will get a pixel value 
v.p{0, 0} -> first pixel in the image 
v.h -> the hight of the second image 
v.p{0, u * v.h} -> will read the Nth pixel where N = u * v.h 

我轉換到這PIL,結果看起來就像你希望它是:

import Image 

# open the input image 
input_img = Image.open('input.png') 

# open gradient image and resize to 256px height 
gradient_img = Image.open('gradient.png') 
gradient_img = gradient_img.resize((gradient_img.size[0], 256,)) 

# get pixel access object (significantly quicker than getpixel method) 
gradient_pix = gradient_img.load() 

data = input_img.getdata() 
input_img.putdata([gradient_pix[0, r] for (r, g, b, a) in data]) 
input_img.save('output.png') 
+0

感謝,認爲工程beatifully!我想出了一個類似的算法(頭部和鍵盤敲打得很厲害,並且有很多來自imagemagick民間的幫助),但是我認爲你的實際上可能比我的效率更高 – EvanK 2009-05-24 06:35:10