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

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

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

disposal = int(im.encoderinfo.get("disposal", 0))

    if transparent_color_exists or duration != 0 or disposal:
        packed_flag = 1 if transparent_color_exists else 0
        packed_flag |= disposal << 2
        if not transparent_color_exists:
            transparency = 0

        fp.write(
            b"!"
            + o8(249)  # extension intro
            + o8(4)  # length
            + o8(packed_flag)  # packed fields
            + o16(duration)  # duration
            + o8(transparency)  # transparency index
            + o8(0)
        )

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

原圖:

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

from PIL import Image

img = Image.open("dabai.gif")
try:
    flag = 0
    while True:
        #獲取每一幀
        img.seek(flag) 
        #保存
        img.save("pics/{}.png".format(flag))
        pic = Image.open("pics/{}.png".format(flag))
        #轉化
        pic = pic.convert("RGBA")
        #替換背景爲透明
        color = pic.getpixel((0,0))
        for i in range(pic.size[0]):
            for j in range(pic.size[1]):
                dot = (i,j)
                rgba = pic.getpixel(dot)
                if rgba == color:
                    rgba = rgba[:-1] + (0,)
                    pic.putpixel(dot, rgba)
        #保存
        pic.save("pics/{}.png".format(flag))
        flag +=1
except BaseException as e:
    pass

合成GIF圖像:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

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

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

發佈了8 篇原創文章 · 獲贊 0 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章