2009-12-26 50 views
18

¿Cómo detectar si una imagen PNG tiene un canal alfa transparente o no usa PIL?¿Cómo obtener el valor alfa de una imagen PNG con PIL?

img = Image.open('example.png', 'r') 
has_alpha = img.mode == 'RGBA' 

Con el código anterior sabemos si una imagen PNG tiene un canal alfa no pero ¿cómo obtener el valor alfa?

no he encontrado una clave de 'transparencia' en el diccionario de img.info como se describe al PIL's website

estoy usando Ubuntu y zlib1g, paquetes zlibc ya están instalados.

Respuesta

42

Para obtener la capa alfa de una imagen RGBA todo lo que tiene que hacer es:

red, green, blue, alpha = img.split() 

o

alpha = img.split()[-1] 

y hay un método para establecer la capa alfa:

img.putalpha(alpha) 

La clave de transparencia solo se utiliza para definir e el índice de transparencia en el modo de paleta (P). Si desea cubrir el caso transparencia modo de paleta, así y cubrir todos los casos se podía hacer esto

if img.mode in ('RGBA', 'LA') or (img.mode == 'P' and 'transparency' in img.info): 
    alpha = img.convert('RGBA').split()[-1] 

Nota: Se necesita el método de conversión cuando el image.mode es LA, debido a un error en el PIL.

2

img.info es sobre la imagen como un todo - el valor alfa en una imagen RGBA es por píxel, por lo que, por supuesto, no estará en img.info. El método getpixel del objeto imagen, dado una coordenada como argumento, devuelve una tupla con los valores de las (cuatro, en este caso) bandas para ese píxel - el último valor de la tupla será A, el valor alfa.

+0

@Alex, gracias por su respuesta, ¿hay alguna manera de determinar si una imagen PNG tiene un fondo transparente? – jack

+2

A menos que raramente estés haciendo esto, 'getpixel' será muy lento. Deberías usar 'getdata' o' load' para un acceso de alto rendimiento. – carl

3
# python 2.6+ 

import operator, itertools 

def get_alpha_channel(image): 
    "Return the alpha channel as a sequence of values" 

    # first, which band is the alpha channel? 
    try: 
     alpha_index= image.getbands().index('A') 
    except ValueError: 
     return None # no alpha channel, presumably 

    alpha_getter= operator.itemgetter(alpha_index) 
    return itertools.imap(alpha_getter, image.getdata()) 
4

Usted puede obtener los datos alfa de la imagen entera de una sola vez mediante la conversión de la imagen a modo de cadena con 'A' por ejemplo este ejemplo alfa obtener datos de la imagen y la guarda como imagen en escala de grises :)

from PIL import Image 

imFile="white-arrow.png" 
im = Image.open(imFile, 'r') 
print im.mode == 'RGBA' 

rgbData = im.tostring("raw", "RGB") 
print len(rgbData) 
alphaData = im.tostring("raw", "A") 
print len(alphaData) 

alphaImage = Image.fromstring("L", im.size, alphaData) 
alphaImage.save(imFile+".alpha.png") 
1

yo probamos este:

from PIL import Image 
import operator, itertools 

def get_alpha_channel(image): 
    try: 
     alpha_index = image.getbands().index('A') 
    except ValueError: 
     # no alpha channel, so convert to RGBA 
     image = image.convert('RGBA') 
     alpha_index = image.getbands().index('A') 
    alpha_getter = operator.itemgetter(alpha_index) 
    return itertools.imap(alpha_getter, image.getdata()) 

esto devuelve el resultado que esperaba. Sin embargo, hice algunos cálculos para determinar la media y la desviación estándar, y los resultados salieron ligeramente diferentes de la función fx:mean de imagemagick.

¿Tal vez la conversión cambió algunos de los valores? No estoy seguro, pero parece relativamente trivial.

+0

¿Has probado esto para que responda la pregunta o tienes un problema similar pero este código no funciona como se esperaba? En el último caso, esta debería ser una nueva pregunta. En el primer caso, ¿podría necesitar una edición para ser menos confuso? – rene

+0

¡Gracias por la aclaración! Intenté esto y agregué algo para obtener lo que necesitaba.Era algo así como un caso similar, y el último era una pregunta nueva, pero ahora voy con un enfoque diferente porque parece que el PIL tiene un problema con las imágenes que están en modo 'P'. –

Cuestiones relacionadas