2012-05-21 18 views
12

Come dovrei verificare se una GIF è trasparente (anche parzialmente)?Determinare se una GIF è trasparente in Python

Ho ottenuto questo risultato con i PNG aprendo l'immagine con PIL e controllando la modalità dell'immagine. Ma le GIF hanno la stessa modalità a prescindere.

Per quanto riguarda i falsi positivi, non mi importa se un GIF completamente opaco viene contrassegnato come trasparente (supponendo che si tratti di un caso raro), ma mi dispiace se un GIF trasparente viene contrassegnato come opaco.

Per quanto riguarda le biblioteche, preferirei una soluzione che utilizza PIL piuttosto che qualcos'altro, ma qualsiasi cosa funzioni.

+1

Per un PNG a 8 bit, scommetto che il tuo metodo attuale non funziona, restituirà la modalità '' P'' tutto il tempo. In tal caso dovrai trattarlo come una GIF. –

risposta

17
img = Image.open(filename) 
if img.mode == "RGBA" or "transparency" in img.info: 
    # image uses transparency 

Vedi here per come la trasparenza funziona con GIF (e 8-bit, palettized, PNG).

Si noti che il caso di falsi positivi è possibile: una GIF potrebbe definire un colore trasparente ma non utilizzarlo. Immagino che sarebbe abbastanza raro, però - perché buttare via un colore per trasparenza e non usarlo? (Il tuo falso negativo non è possibile.)

Tuttavia, se è necessario sapere se la trasparenza è effettivamente utilizzata, è possibile creare due versioni dell'immagine in cui il colore trasparente è mappato su diversi colori (ad esempio, bianco e nero) e poi confrontarli. Se ci sono delle differenze, l'immagine usa la trasparenza. In questo modo:

def uses_transparency(filename): 
    img = Image.open(filename) 
    trans = img.info.get("transparency", None) 
    if trans is not None: 
     trans *= 3 # convert color number to palette table index 
     palette = img.getpalette() 
     imgs = [] 
     for bg in [0, 255]: # map transparent color first to black, then white 
      palette[trans:trans+3] = [bg] * 3 
      img.putpalette(palette) 
      imgs.append(img.convert("L")) 
     return bool(ImageChops.difference(*imgs).getbbox()) 

È possibile utilizzare un approccio simile per vedere se un PNG a 24 bit in realtà utilizza il canale alfa, incollandolo su sfondi bianchi e neri e confrontando i risultati.

Problemi correlati