PyGame模块分别pygame.image
只能处理非动画GIF。
但是在 PyGame 主页上介绍了GIFImage库:
该库将 GIF 动画播放添加到 pygame。
另一种选择是使用库将 GIF 逐帧加载到列表中。
例如使用 Pillow库(pip install Pillow)。
编写一个函数,可以将 PIL 图像转换为 apygame.Surface
并使用 PIL 库逐帧加载 GIF:(
另请参见使用 Pillow和PIL 和 pygame.image提取动画 GIF 的帧)
from PIL import Image, ImageSequence
def pilImageToSurface(pilImage):
mode, size, data = pilImage.mode, pilImage.size, pilImage.tobytes()
return pygame.image.fromstring(data, size, mode).convert_alpha()
def loadGIF(filename):
pilImage = Image.open(filename)
frames = []
if pilImage.format == 'GIF' and pilImage.is_animated:
for frame in ImageSequence.Iterator(pilImage):
pygameImage = pilImageToSurface(frame.convert('RGBA'))
frames.append(pygameImage)
else:
frames.append(pilImageToSurface(pilImage))
return frames
或者使用OpenCV / opencv-python库和VideoCapture
编写一个函数,可以将 cv2pygame.image
图像转换为 apygame.Surface
并使用该库逐帧加载 GIF:(
另请参见Read GIF files in Python and How do I convert an OpenCV (cv2) image (BGR and BGRA) to一个 pygame.Surface 对象)
import cv2
def cv2ImageToSurface(cv2Image):
size = cv2Image.shape[1::-1]
format = 'RGBA' if cv2Image.shape[2] == 4 else 'RGB'
cv2Image[:, :, [0, 2]] = cv2Image[:, :, [2, 0]]
surface = pygame.image.frombuffer(cv2Image.flatten(), size, format)
return surface.convert_alpha() if format == 'RGBA' else surface.convert()
def loadGIF(filename):
gif = cv2.VideoCapture(filename)
frames = []
while True:
ret, cv2Image = gif.read()
if not ret:
break
pygameImage = cv2ImageToSurface(cv2Image)
frames.append(pygameImage)
return frames
另请参阅加载动画 GIF和一个简单的动画 gif 查看器示例:
import pygame
import cv2
def cv2ImageToSurface(cv2Image):
size = cv2Image.shape[1::-1]
format = 'RGBA' if cv2Image.shape[2] == 4 else 'RGB'
cv2Image[:, :, [0, 2]] = cv2Image[:, :, [2, 0]]
surface = pygame.image.frombuffer(cv2Image.flatten(), size, format)
return surface.convert_alpha() if format == 'RGBA' else surface.convert()
def loadGIF(filename):
gif = cv2.VideoCapture(filename)
frames = []
while True:
ret, cv2Image = gif.read()
if not ret:
break
pygameImage = cv2ImageToSurface(cv2Image)
frames.append(pygameImage)
return frames
pygame.init()
window = pygame.display.set_mode((500, 500))
clock = pygame.time.Clock()
gifFrameList = loadGIF(r"rubber_ball.gif")
currentFrame = 0
run = True
while run:
clock.tick(20)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
window.fill(0)
rect = gifFrameList[currentFrame].get_rect(center = (250, 250))
window.blit(gifFrameList[currentFrame], rect)
currentFrame = (currentFrame + 1) % len(gifFrameList)
pygame.display.flip()