Преобразование оператора ImageMagick FX в чистый код Python с помощью PIL - PullRequest
1 голос
/ 25 апреля 2009

Я пытаюсь перенести некоторые функции обработки изображений из Image Magick команда (используя Fx Special Effects Image Operator ) для Python с использованием PIL . мой проблема в том, что я не совсем понимаю, что делает этот оператор FX:

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

С высокого уровня эта команда берет цвета из градиентного изображения ( градиент.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 цветов. Не только это неуклюжий способ делать вещи, это приводит к действительно дрянному выводу образ. Как я мог продублировать функционал Magick, не забивая результат в 265 цветов?

приложение: забыл процитировать блог , в котором я нашел оригинальную команду Magick

1 Ответ

1 голос
/ 15 мая 2009

Я знаю, что прошло около месяца, и вы, возможно, уже поняли это. Но вот ответ.

Из документации 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')
...