def load_animation(im): if im.format == 'GIF' and im.mode == 'P': # TODO: Pillow has bug with gif animation # https://github.com/python-pillow/Pillow/labels/GIF raise NotImplementedError('Pillow has bug with gif animation, ' 'fallback to GdkPixbuf') anime = anime_tools.AnimeFrameBuffer(im.n_frames, loop=im.info['loop']) background = im.info.get('background', None) if isinstance(background, tuple): background = pixel2int(color) frameiter = ImageSequence.Iterator(im) for n, frame in enumerate(frameiter): anime.add_frame(n, pil_to_pixbuf(frame), int(frame.info.get('duration', 0)), background=background) return anime.create_animation()
return pil_to_pixbuf(im, keep_orientation=True) except: pass if not enable_anime: return GdkPixbuf.Pixbuf.new_from_file(path) if (pixbuf := GdkPixbuf.PixbufAnimation.new_from_file(path)).is_static_image(): return pixbuf.get_static_image() if n_frames is None: # not recognized by PIL or not animation return pixbuf if n_frames < 2: # only one frame return pixbuf # assume PIL and GdkPixbuf count frames in same way. anime = anime_tools.AnimeFrameBuffer(n_frames, loop=loop) frame_iter = pixbuf.get_iter(cur := GLib.TimeVal()) for n in range(n_frames): frame = (frame_ref := frame_iter.get_pixbuf()).copy() frame_ref.copy_options(frame) cur.tv_usec += (delay := frame_iter.get_delay_time()) * 1000 while not frame_iter.advance(cur): cur.tv_usec += (delay := delay + frame_iter.get_delay_time()) * 1000 anime.add_frame(n, frame, delay) if n == n_frames - 1: # end of animation break return anime.create_animation()