Python實現(xiàn)GIF動圖加載和降幀的方法詳解
最近在使用pygame開發(fā)游戲,練習(xí)python編程。但遇到了一個問題,就是如何載入已有的GIF動圖增強游戲的效果,在csdn搜索了一下,發(fā)現(xiàn)相關(guān)的文章比較少,缺少實例。于是自己研究了相關(guān)內(nèi)容,找到了解決方案。本篇文章用游戲編程實例介紹pygame如何載入GIF動圖。
一、準備一份透明背景的GIF動畫素材
首先在網(wǎng)絡(luò)上找一張背景透明的GIF動圖,注意需要背景透明的,不然在游戲中就會顯示一個矩形圖片,會擋住游戲的背景。以下就是百度圖片搜索找到的背景透明的GIF動圖。
百度圖片搜索的素材
二、使用pillow庫對GIF動圖進行解幀
使用pillow庫的Image、ImageSequence包對圖片進行解幀后發(fā)現(xiàn),這張下載的GIF圖片包含了10幀圖片,圖片以png格式保存在./images/bird/文件夾下面,文件名以gif1、gif2......等為后綴名。
GIF解幀后的文件情況
參考代碼:
from PIL import Image, ImageSequence class GameGifSprite(pygame.sprite.Sprite): """ 小鳥游戲精靈 """ def __init__(self, image_name, speed=1): # 調(diào)用父類的初始化方法 super().__init__() # 使用pillow的image打開GIF動圖 pillow_image = Image.open(image_name) index = 1 # 使用pillow的ImageSequence獲取GIF動圖所有幀對應(yīng)的迭代器 for frame in ImageSequence.all_frames(pillow_image): # 以png格式保存在./images/bird/文件夾下面,文件名以gif1、gif2......等為后綴名 frame.save(f"./images/bird/gif{index}.png", quality=100) index = index + 1
三、使用pygame.image.load()讀取所有解出來的幀并存入列表
然后使用pygame.image.load()按文件名字順序讀取這10張圖片,并把返回的10個圖像對象添加到列表中。
1)all_frame為GIF動圖所包含的所有幀數(shù),這里index循環(huán)結(jié)束后為11,由于數(shù)組從0開始計算,所以為11-2=9。
2)now_frame為當前游戲的幀,一開始設(shè)置為0。
3)gif_images為存儲GIF動圖的幀列表。
4)循環(huán)讀取所有幀,添加到gif_images[]中。
5)游戲開始時設(shè)置顯示第一幀圖片。
參考代碼:
# 定義對象的屬性 # 1.all_frame為GIF動圖所包含的所有幀數(shù),這里index循環(huán)結(jié)束后為11,由于數(shù)組從0開始計算,所以為11-2=9 self.all_frame = index - 2 # 2.now_frame為當前游戲的幀,一開始設(shè)置為0 self.now_frame = 0 # 3.gif_images為存儲GIF動圖的幀列表 self.gif_images = [] # 4.循環(huán)讀取所有幀,添加到gif_images[]中 for i in range(1, index): self.gif_images.append(pygame.image.load(f"./images/bird/gif{i}.png")) # 5.游戲開始時設(shè)置顯示第一幀圖片 self.image = self.gif_images[self.now_frame]
四、在精靈類的update()方法中循環(huán)播放列表中的幀
pygame在每次畫面刷新時會調(diào)用每個精靈類的update()方法,所以我們只要在該方法下實現(xiàn)循環(huán)播放這10幀圖片就可以實現(xiàn)含有GIF圖片精靈的播放。以下是游戲運行效果圖:
游戲運行效果圖
1)當播放到gif最后一幀時,重置為gif第一幀
2)畫面每次刷新更新gif的下一幀
參考代碼:
def update(self): # 在屏幕的水平方向上移動 self.rect.x -= self.speed # 當播放到gif最后一幀時,重置為gif第一幀 if self.now_frame < self.all_frame: # 畫面每次刷新更新gif的下一幀 self.now_frame = self.now_frame + 1 else: self.now_frame = 1
五、避免精靈幀率過快對精靈進行降幀
實現(xiàn)GIF在游戲中顯示后又產(chǎn)生了一個新問題,由于游戲設(shè)置是60FPS幀率播放的,那么顯示這張GIF圖片時就過快了,我們需要對精靈對象降低幀率,這里使用了我自己寫的公式。
1)self.now_frame = self.now_frame + 1改為self.now_frame = self.now_frame + self.FPS
2)update()方法中增加self.image = self.gif_images[math.floor(self.now_frame)],使用math.floor向下取整達到降幀的效果
PS:當sefl.FPS設(shè)置為0.25時則相當于把幀率降低了4倍,現(xiàn)在看上去就正常多了。
降幀后的效果圖
參考代碼:
def update(self): # 在屏幕的水平方向上移動 self.rect.x -= self.speed # 當播放到gif最后一幀時,重置為gif第一幀 if self.now_frame < self.all_frame: # 畫面每次刷新更新gif的一下一幀 self.now_frame = self.now_frame + self.FPS else: self.now_frame = 1 # 設(shè)置pygame當前顯示的gif幀 # 使用math.floor向下取整達到降幀的效果 self.image = self.gif_images[math.floor(self.now_frame)]
到此這篇關(guān)于Python實現(xiàn)GIF動圖加載和降幀的方法詳解的文章就介紹到這了,更多相關(guān)Python動圖加載降幀內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python 利用PyAutoGUI快速構(gòu)建自動化操作腳本
我們經(jīng)常遇到需要進行大量重復(fù)操作的時候,比如:網(wǎng)頁上填表,對 web 版本 OA 進行操作,自動化測試或者給新系統(tǒng)首次添加數(shù)據(jù)等,今天就利用PyAutoGUI構(gòu)建自動化操作腳本完成這些重復(fù)的需求2021-05-05解決Python中pandas讀取*.csv文件出現(xiàn)編碼問題
很多朋友在使用Python中pandas讀取csv文件時,出現(xiàn)編碼格式問題,接下來通過本文給大家分享解決Python中pandas讀取*.csv文件出現(xiàn)編碼問題,需要的朋友可以參考下2019-07-07使用 python pyautogui實現(xiàn)鼠標鍵盤控制功能
pyautogui是一個可以控制鼠標和鍵盤的python庫,類似的還有pywin32。這篇文章主要介紹了python中的pyautogui實現(xiàn)鼠標鍵盤控制功能,需要的朋友可以參考下2019-08-08