2009-12-26 4 views
18

Comment détecter si une image PNG a un canal alpha transparent ou non PIL?Comment obtenir la valeur alpha d'une image PNG avec PIL?

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

Avec le code ci-dessus, nous savons si une image PNG a un canal alpha non pas mais comment obtenir la valeur alpha?

Je n'ai pas trouvé une clé « transparence » dans le dictionnaire de img.info tel que décrit à PIL's website

J'utilise des paquets Ubuntu et zlib1g, zlibc sont déjà installés.

Répondre

42

Pour obtenir la couche alpha tout ce que vous devez faire d'une image RGBA est:

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

ou

alpha = img.split()[-1] 

Et il y a une méthode pour définir la couche alpha:

img.putalpha(alpha) 

La touche de transparence est uniquement utilisée pour définir e l'indice de transparence en mode palette (P). Si vous voulez couvrir le cas de la transparence du mode de palette aussi bien et couvrir tous les cas, vous pouvez le faire

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

Note: La méthode de conversion est nécessaire lorsque le image.mode est LA, à cause d'un bogue dans PIL.

2

Le img.info concerne l'image dans son ensemble - la valeur alpha d'une image RGBA est par pixel, donc bien sûr, elle ne sera pas dans img.info. La méthode getpixel de l'objet image, étant donné une coordonnée comme argument, retourne un tuple avec les valeurs des (quatre, dans ce cas) bandes pour ce pixel - la dernière valeur du tuple sera alors A, la valeur alpha.

+0

@Alex, merci pour votre réponse, est-il un moyen de déterminer si une image PNG a un fond transparent? – jack

+2

À moins que vous ne le fassiez rarement, 'getpixel' sera très lent. Vous devriez utiliser 'getdata' ou' load' pour un accès haute performance. – 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

Vous pouvez obtenir les données alpha sur l'image entière en une seule fois en convertissant l'image en chaîne avec « un » mode par exemple, cet exemple obtenir des données alpha sur l'image et l'enregistre comme image échelle de gris :)

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

J'ai essayé ceci:

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

ce a renvoyé le résultat que je me attendais. Cependant, j'ai fait quelques calculs pour déterminer la moyenne et l'écart type, et les résultats sont sortis légèrement différents de la fonction fx:mean de imagemagick.

Peut-être que la conversion a modifié certaines des valeurs? Je ne suis pas sûr, mais cela semble relativement trivial.

+0

Vous avez essayé ceci afin qu'il réponde à la question ou vous avez un problème similaire mais ce code ne fonctionne pas comme prévu? Dans ce dernier cas, cela devrait être une nouvelle question. Dans le premier cas, il pourrait avoir besoin d'un montage pour être moins confus? – rene

+0

Oh merci pour la clarification. J'ai essayé ceci, et j'ai ajouté quelque chose pour obtenir ce dont j'avais besoin.C'était quelque chose d'un cas similaire, et le dernier était une nouvelle question, mais je vais avec une approche différente maintenant, car il semble que PIL a un problème avec les images qui sont en mode «P». –

Questions connexes