1

Image Magickコマンド( Fx Special Effects Image Operatorを使用)からPILを使用してPythonにいくつかの画像処理機能を移植しようとしています。私の問題は、このfxオペレーターが何をしているのかを完全には理解していないということです。

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色にダウンサンプリングします。これは物事を行うための手間のかかる方法であるだけでなく、非常にくだらない出力画像になります。結果を265色に詰め込むことなく、Magick機能を複製するにはどうすればよいですか?

補遺:元のMagickコマンドを見つけたブログを引用するのを忘れました

4

1 に答える 1

1

約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')
于 2009-05-14T23:25:31.173 に答える