2009-04-25 4 views
1

J'essaie de porter une fonctionnalité de traitement d'image à partir d'une commande Image Magick (en utilisant le Fx Special Effects Image Operator) vers Python en utilisant PIL. Ma question est que je ne suis pas tout à fait comprendre ce que cet opérateur fx fait:Conversion d'un opérateur ImageMagick FX en code Python pur avec PIL

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

D'un haut niveau, cette commande prend les couleurs d'une image de gradient (gradient.png) et les applique comme la palette de couleurs de l'image d'entrée (input.png), en écrivant dans une image de sortie (output.png).

D'après ce que j'ai compris, u est l'image d'entrée, v est le gradient, et il est en passant par chaque extrême gauche pixel dans le dégradé de haut en bas, en quelque sorte appliquer ses couleurs à l'image d'entrée.

Je ne peux pas comprendre comment faire la même chose par programme avec PIL. La meilleure chose que je suis venu avec était de convertir l'image en une image palettisé (sous-échantillonnage à une maigre 256 couleurs) et en saisissant les couleurs individuellement à partir du gradient avec un objet d'accès au pixel.

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') 

Cela fonctionne, mais comme je l'ai dit, il descend jusqu'à 256 couleurs. Non seulement c'est une façon de faire les choses à la main, il en résulte une image de sortie vraiment merdique . Comment pourrais-je dupliquer la fonctionnalité Magick sans bachoter le résultat en 265 couleurs?

addendum: a oublié de citer la blog where I found the original Magick command

Répondre

1

Je sais que ça fait un mois et vous pourriez a déjà compris. Mais voici la réponse. De la documentation d'ImageMagicK, j'ai pu comprendre ce que l'effet est réellement en train de faire.

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 

Je convertis que dans PIL, et le résultat ressemble exactement comme vous voulez qu'il soit:

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

merci, ça marche beatifully! J'avais imaginé un algorithme similaire (avec beaucoup de claquement de la tête et du clavier, et beaucoup d'aide de la part des imagemagick folk), mais je pense que le vôtre pourrait être plus efficace que le mien de toute façon – EvanK

Questions connexes