Python用PIL將PNG圖像合成gif時如果背景為透明時圖像出現重影的解決辦法


最近在用PIL合成PNG圖像為GIF時,因為需要透明背景,所以就用putpixel的方法替換背景為透明,但是在合成GIF時,圖像出現了重影,在網上查找了GIF的相關資料:GIF相關資料 其中有對GIF幀數處理的說明,需要在GIF圖像的header中設置disposal的處置方法

 

 然后我們可以查看PIL庫中關於GIF的定義文件GifImagePlugin.py

 1 disposal = int(im.encoderinfo.get("disposal", 0))
 2  
 3     if transparent_color_exists or duration != 0 or disposal:
 4         packed_flag = 1 if transparent_color_exists else 0
 5         packed_flag |= disposal << 2
 6         if not transparent_color_exists:
 7             transparency = 0
 8  
 9         fp.write(
10             b"!"
11             + o8(249)  # extension intro
12             + o8(4)  # length
13             + o8(packed_flag)  # packed fields
14             + o16(duration)  # duration
15             + o8(transparency)  # transparency index
16             + o8(0)

其中有一段關於Disposal的定義,如果保存時不設置disposal屬性則默認為0,即不使用處理方法,所以每一張PNG文件都被保留成了背景,也就是我們看到的重影,所以我們在合成GIF時,需要設置disposal值

原圖:

 

 下面是生成透明背景PNG圖像代碼:

 1 from PIL import Image
 2  
 3 img = Image.open("dabai.gif")
 4 try:
 5     flag = 0
 6     while True:
 7         #獲取每一幀
 8         img.seek(flag) 
 9         #保存
10         img.save("pics/{}.png".format(flag))
11         pic = Image.open("pics/{}.png".format(flag))
12         #轉化
13         pic = pic.convert("RGBA")
14         #替換背景為透明
15         color = pic.getpixel((0,0))
16         for i in range(pic.size[0]):
17             for j in range(pic.size[1]):
18                 dot = (i,j)
19                 rgba = pic.getpixel(dot)
20                 if rgba == color:
21                     rgba = rgba[:-1] + (0,)
22                     pic.putpixel(dot, rgba)
23         #保存
24         pic.save("pics/{}.png".format(flag))
25         flag +=1
26 except BaseException as e:
27     pass

合成GIF圖像:

 1 #!/usr/bin/env python
 2 # -*- coding: utf-8 -*-
 3  
 4 from PIL import Image
 5 import os
 6 photo_list = []
 7 #獲取保存的PNG圖像
 8 pic_list = os.listdir("pics/")
 9 #對圖像List排序,防止圖像位置錯亂
10 pic_list.sort(key=lambda x:int(x[:-4]))
11 for k in pic_list:
12     pic_p = Image.open("pics/{}".format(k))
13     photo_list.append(pic_p)
14 #保存圖像,disposal可以為2或者3,但是不能為1或0,切記,其他自定義未嘗試
15 photo_list[0].save("dabai_new.gif", save_all=True, append_images=photo_list[1:],duration=40,transparency=0,loop=0,disposal=3)

合成后圖像,背景已變成透明而且未出現重影


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM