2010-09-20 39 views
13

ya he echado un vistazo a esta pregunta: SO question y parecen haber implementado una técnica muy similar para la sustitución de un solo color incluyendo los valores alfa:Python: PIL reemplazar un solo color RGBA

c = Image.open(f) 
c = c.convert("RGBA") 
w, h = c.size 
cnt = 0 
for px in c.getdata(): 
    c.putpixel((int(cnt % w), int(cnt/w)), (255, 0, 0, px[3]))                          cnt += 1 

Sin embargo, esto es muy lento Encontré esta receta en los interwebs, pero no he tenido éxito al usarla hasta ahora: recipe

Lo que intento hacer es tomar varias imágenes PNG que consisten en un solo color, blanco. Cada píxel es 100% blanco con varios valores alfa, incluido alfa = 0. Lo que quiero hacer es básicamente colorear la imagen con un nuevo color configurado, por ejemplo # ff0000 < 00-ff>. Así que mis imágenes iniciales y resultantes se verían así, donde el lado izquierdo es mi imagen inicial y el derecho es mi imagen final (NOTA: el fondo se ha cambiado a un gris claro para que pueda verlo, ya que es realmente transparente y no lo haría) t ser capaz de ver los puntos de la izquierda.)

alt text

Cualquier mejor manera de hacer esto?

Respuesta

32

Si tiene numpy, proporciona una forma mucho, mucho más rápida de operar en imágenes PIL.

Ej:

import Image 
import numpy as np 

im = Image.open('test.png') 
im = im.convert('RGBA') 

data = np.array(im) # "data" is a height x width x 4 numpy array 
red, green, blue, alpha = data.T # Temporarily unpack the bands for readability 

# Replace white with red... (leaves alpha values alone...) 
white_areas = (red == 255) & (blue == 255) & (green == 255) 
data[..., :-1][white_areas.T] = (255, 0, 0) # Transpose back needed 

im2 = Image.fromarray(data) 
im2.show() 

Editar: Es una lenta lunes, así que pensé que me gustaría añadir un par de ejemplos:

sólo para mostrar que está dejando a los valores alfa solo, aquí están los resultados para una versión de la imagen de ejemplo de con un gradiente radial aplicada al canal alpha:

original: alt text

Resultado: alt text

+1

impresionante! ¡Increíble! ¡Increíble! +1 y marcado como "Aceptado". Enorme ahorro de tiempo y los resultados son perfectos. – sberry

+0

@sberry - ¡Me alegra ayudar! –

+0

no debería ser, Rojo, Verde, Azul? white_areas = – Sekai

2

El capítulo del libro en línea de Pythonware PIL para el Image module estipula que putpixel() es lento y sugiere que se puede acelerar mediante la alineación. O dependiendo de la versión de PIL, usando load() en su lugar.

2

Pruebe esto, en esta muestra establecemos el color en negro si el color no es blanco.

#!/usr/bin/python 
from PIL import Image 
import sys 

img = Image.open(sys.argv[1]) 
img = img.convert("RGBA") 

pixdata = img.load() 

# Clean the background noise, if color != white, then set to black. 

for y in xrange(img.size[1]): 
    for x in xrange(img.size[0]): 
     if pixdata[x, y] == (255, 255, 255, 255): 
      pixdata[x, y] = (0, 0, 0, 255) 

puede utilizar el selector de color en GIMP para absorber el color y ver que es de color RGBA

Cuestiones relacionadas