2009-04-25 14 views
1

PILを使用してPythonにImage Magick コマンド(Fx Special Effects Image Operatorを使用)からいくつかの画像処理機能を移植しようとしています。マイ 問題私は完全にこのFX事業者が何をしているのか理解していないよということです。ImageMagick FX演算子をPILで純粋なPythonコードに変換する

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

をハイレベルから、このコマンドは、勾配画像 (gradient.png)から色を取り、カラーパレットとしてそれらを適用します入力画像の (input.png)、出力画像(output.png)への書き込み。私は考え出したものから

uが入力画像で、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色にダウンサンプリングします。 これはハムハンドのやり方だけでなく、実際には駄目な出力になります。 image。 の結果を265色に詰め込むことなくMagickの機能を複製するにはどうすればいいですか?

補遺:は、私はそれが約一ヶ月をされている知っている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にあることを変換し、その結果は、あなたがそれになりたい正確に次のようになります。beatifully作品

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

おかげで、!私は同様のアルゴリズム(頭とキーボードの多くの打撃、そしてimagemagickフォークからの多くの助けを借りて)を考え出しましたが、私はあなたのものが実際に私よりも効率的かもしれないと思います – EvanK

関連する問題