2009-12-26 70 views
18

如何檢測PNG圖像是否具有透明alpha通道或不使用PIL?如何用PIL獲取PNG圖像的alpha值?

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

通過上面的代碼,我們知道PNG圖像是否有alpha通道,但不知道如何獲得alpha值?

截至PIL's website

描述我使用的是Ubuntu和我的zlib1g沒有發現img.info字典中的「透明度」鍵,zlibc包已安裝。

回答

42

爲了得到一個RGBA圖像,所有你需要做的Alpha層:

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

alpha = img.split()[-1] 

而且有設置alpha層的方法:

img.putalpha(alpha) 

透明鍵僅用於定義e調色板模式(P)中的透明度索引。如果你想覆蓋調色板模式透明度情況下,也並涵蓋所有情況下,你可以做到這一點

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

注:需要轉換方法,當image.mode是LA,因爲PIL中的錯誤。

2

img.info是關於圖像的整體 - RGBA圖像中的alpha值是每個像素,所以當然不會在img.info。圖像對象的getpixel方法在給定座標作爲參數的情況下返回一個元組,該元組的值(該例中爲四個),該元組的最後值將爲A,即alpha值。

+0

@Alex,感謝您的回答,有沒有方法可以確定PNG圖像是否具有透明背景? – jack 2009-12-26 07:50:46

+2

除非你很少這樣做,'getpixel'會非常慢。您應該使用'getdata'或'load'進行高性能訪問。 – carl 2009-12-26 09:45:33

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

可以通過轉換圖像串如本例中的「A」模式獲取阿爾法數據進行圖像的獲取alpha數據出整幅圖像的一氣呵成,並將其保存爲灰度圖像:)

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

我嘗試這樣做:

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

此返回我所期待的結果。但是,我做了一些計算來確定平均值和標準偏差,結果與imagemagick的fx:mean函數略有不同。

也許轉換改變了一些值?我不確定,但它似乎相對微不足道。

+0

你試過這個,所以它回答了這個問題,或者你有類似的問題,但是這個代碼不能按預期工作?在後一種情況下,這應該是一個新問題。在前一種情況下,可能需要編輯才能減少混淆? – rene 2017-01-12 19:15:08

+0

哦謝謝澄清。我嘗試了這一點,並添加了一些東西來獲得我需要的東西。這是一個類似的情況,後者是一個新問題,但我現在採用不同的方法,因爲它似乎像PIL對於處於'P'模式的圖像存在問題。 – 2017-01-12 19:16:43