2011-05-24 108 views
6

我想使用Python圖像庫將PNG32圖像(具有透明度)轉換爲PNG8。 到目前爲止,我已成功轉換爲具有堅實背景的PNG8。使用PIL將PNG32轉換爲PNG8,同時保留透明度

下面是我在做什麼:

from PIL import Image 
im = Image.open("logo_256.png") 
im = im.convert('RGB').convert('P', palette=Image.ADAPTIVE, colors=255) 
im.save("logo_py.png", colors=255) 
+1

PNG32有8位透明度,PNG8只有1位,所以不可能忠實地轉換。你能忍受嗎? – 2011-05-24 17:46:34

+0

是的,因爲它只是一個透明的背景。 – montonero 2011-05-24 17:51:32

+0

請將您的解決方案作爲答案發布;這更符合網站的格式。如果你願意,我會很樂意給它一個贊成票。 – 2011-05-24 18:18:20

回答

12

後在網上一番搜索,這裏是實現的代碼是什麼我問:

from PIL import Image 

im = Image.open("logo_256.png") 

# PIL complains if you don't load explicitly 
im.load() 

# Get the alpha band 
alpha = im.split()[-1] 

im = im.convert('RGB').convert('P', palette=Image.ADAPTIVE, colors=255) 

# Set all pixel values below 128 to 255, 
# and the rest to 0 
mask = Image.eval(alpha, lambda a: 255 if a <=128 else 0) 

# Paste the color of index 255 and use alpha as a mask 
im.paste(255, mask) 

# The transparency index is 255 
im.save("logo_py.png", transparency=255) 

來源:http://nadiana.com/pil-tips-converting-png-gif 雖然代碼也沒有調用im.load(),因而對崩潰我的os/python/pil版本。 (它看起來像是PIL中的錯誤)。

+1

幾年後終於回到這個問題,這裏是我答應的upvote。這是一個很好的解決方案。 – 2013-11-12 18:06:21

+0

你應該接受這個答案:) – 2015-11-16 13:54:49

1

正如馬克贖金提到的,你paletized圖像將只有一個透明程度。

當保存paletized圖像,你必須指定你想成爲透明色這樣其顯色指數:

im.save("logo_py.png", transparency=0) 

將圖像保存爲paletized顏色,並使用第一顏色透明的顏色。

+0

我剛試過這個,但是在新創建的圖像中沒有出現透明顏色。我想我必須找到一種方法來找出在這個步驟中替換透明背景的顏色是什麼:im.convert('RGB') – montonero 2011-05-24 17:58:59

+0

@montonero:可能有多種顏色已被映射到透明顏色,因爲你大大減少了可能的顏色數量。 – martineau 2011-05-25 00:26:12

+0

@martineau我在網上找到的代碼提取了alpha _before_應用convert()命令,因此,在我的情況下,一切都很完美(只有透明背景,儘管我認爲它也應該滿足其他情況。) – montonero 2011-05-25 10:56:18

1

不要使用PIL生成調色板,因爲它無法正確處理RGBA並且量化算法相當有限。

改爲使用pngquant

相關問題