这是用pygame制作的动态图片显示程序。
"""本程序定义了一个GIFImage类,这个类是Matthew编写,10年前的类,现在运行不了。 修改后可以, modifyed by lixingqiu@2019/4/8""" import pygame from PIL import Image from pygame.locals import * import time class GIFImage(object): def __init__(self, filename): self.filename = filename self.image = Image.open(filename) self.frames = [] self.get_frames() self.cur = 0 self.ptime = time.time() self.running = True self.breakpoint = len(self.frames)-1 self.startpoint = 0 self.reversed = False def get_rect(self): return pygame.rect.Rect((0,0), self.image.size) def get_frames(self): image = self.image pal = image.getpalette() base_palette = [] for i in range(0, len(pal), 3): rgb = pal[i:i+3] base_palette.append(rgb) all_tiles = [] try: while 1: if not image.tile: image.seek(0) if image.tile: all_tiles.append(image.tile[0][3][0]) image.seek(image.tell()+1) except EOFError: image.seek(0) all_tiles = tuple(set(all_tiles)) try: while 1: try: duration = image.info["duration"] except: duration = 100 duration *= .001 # 转换成毫秒 cons = False x0, y0, x1, y1 = (0, 0) + image.size if image.tile: tile = image.tile else: image.seek(0) tile = image.tile if len(tile) > 0: x0, y0, x1, y1 = tile[0][1] if all_tiles: if all_tiles in ((6,), (7,)): cons = True pal = image.getpalette() palette = [] for i in range(0, len(pal), 3): rgb = pal[i:i+3] palette.append(rgb) elif all_tiles in ((7, 8), (8, 7)): pal = image.getpalette() palette = [] for i in range(0, len(pal), 3): rgb = pal[i:i+3] palette.append(rgb) else: palette = base_palette else: palette = base_palette pi = pygame.image.fromstring(image.tobytes(), image.size, image.mode) pi.set_palette(palette) if "transparency" in image.info: pi.set_colorkey(image.info["transparency"]) pi2 = pygame.Surface(image.size, SRCALPHA) if cons: for i in self.frames: pi2.blit(i[0], (0,0)) pi2.blit(pi, (x0, y0), (x0, y0, x1-x0, y1-y0)) self.frames.append([pi2, duration]) image.seek(image.tell()+1) except EOFError: pass def render(self, screen, pos): if self.running: if time.time() - self.ptime > self.frames[self.cur][1]: if self.reversed: self.cur -= 1 if self.cur < self.startpoint: self.cur = self.breakpoint else: self.cur += 1 if self.cur > self.breakpoint: self.cur = self.startpoint self.ptime = time.time() screen.blit(self.frames[self.cur][0], pos) def seek(self, num): self.cur = num if self.cur < 0: self.cur = 0 if self.cur >= len(self.frames): self.cur = len(self.frames)-1 def set_bounds(self, start, end): """设置起始帧和结束帧""" if start < 0: start = 0 if start >= len(self.frames): start = len(self.frames) - 1 if end < 0: end = 0 if end >= len(self.frames): end = len(self.frames) - 1 if end < start: end = start self.startpoint = start self.breakpoint = end def pause(self): self.running = False def play(self): self.running = True def rewind(self): self.seek(0) def fastforward(self): self.seek(self.length()-1) def get_height(self): return self.image.size[1] def get_width(self): return self.image.size[0] def get_size(self): return self.image.size def length(self): return len(self.frames) def reverse(self): self.reversed = not self.reversed def reset(self): self.cur = 0 self.ptime = time.time() self.reversed = False def copy(self): new = GIFImage(self.filename) new.running = self.running new.breakpoint = self.breakpoint new.startpoint = self.startpoint new.cur = self.cur new.ptime = self.ptime new.reversed = self.reversed return new def event_check(): """事件检测函数""" for event in pygame.event.get(): if event.type == QUIT: return False return True def main(): pygame.init() lixingqiu = GIFImage("李兴球/8.gif") width,height = lixingqiu.get_size() screen = pygame.display.set_mode((width, height)) # 当事件检测返回真则继续while循环 while event_check(): lixingqiu.render(screen, (0, 0)) # 渲染gif图 pygame.display.flip() # 刷新显示 pygame.quit() # 关闭窗口 if __name__ == "__main__": main()