2012-05-21 12 views
12

Jak mam sprawdzić, czy GIF jest przezroczysty (nawet częściowo)?Ustalanie, czy GIF jest przezroczysty w Pythonie

Dokonałem tego z plikami PNG, otwierając obraz za pomocą PIL i sprawdzając tryb obrazu. Ale GIF-y mają ten sam tryb niezależnie.

Co do fałszywych trafień, nie mam nic przeciwko temu, że całkowicie nieprzejrzysty plik GIF zostanie oznaczony jako przezroczysty (zakładając, że jest to rzadki przypadek), ale mam na myśli, jeśli przezroczysty plik GIF zostanie oznaczony jako nieprzezroczysty.

Jeśli chodzi o biblioteki, wolę rozwiązanie, które wykorzystuje PIL, a nie coś innego, ale cokolwiek działa.

+1

Dla 8-bitowego PNG założę się, że twoja obecna metoda nie działa, przez cały czas powróci tryb ''P' '. W takim przypadku musisz traktować ją podobnie jak GIF. –

Odpowiedz

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

Zobacz here na jak przejrzystość współpracuje z GIF (i 8-bit, palettized, PNG).

Pamiętaj, że Twój fałszywy pozytywny przypadek jest możliwy: możliwe: GIF może zdefiniować kolor jako przezroczysty, ale go nie użyć. Wyobrażam sobie jednak, że byłoby to dość rzadkie - dlaczego rzucić jakiś kolor, aby uzyskać przezroczystość i nie używać go? (Twój fałszywy wynik negatywny nie jest możliwy.)

Mimo to, jeśli chcesz sprawdzić, czy przezroczystość jest rzeczywiście używana, możesz utworzyć dwie wersje obrazu, w których przezroczysty kolor jest odwzorowany na różne kolory (np. Czarny i biały), a następnie porównaj je. Jeśli występują jakiekolwiek różnice, obraz korzysta z przezroczystości. Tak:

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

Można użyć podobnego podejścia, aby zobaczyć, czy 24-bitowy PNG faktycznie korzysta z kanału alfa, wklejając go na białe i czarne tło i porównanie wyników.