def decode_animation(self, file, filename): # Extract GIF control data. If it's not a GIF, this method will # raise. gif_stream = gif.read(file) delays = [image.delay for image in gif_stream.images] # Get GDK animation iterator file.seek(0) anim = self._load(file, filename, gdkpixbuf.gdk_pixbuf_loader_get_animation) time = GTimeVal(0, 0) iter = gdkpixbuf.gdk_pixbuf_animation_get_iter(anim, byref(time)) frames = [] # Extract each image for control_delay in delays: pixbuf = gdkpixbuf.gdk_pixbuf_animation_iter_get_pixbuf(iter) image = self._pixbuf_to_image(pixbuf) frames.append(AnimationFrame(image, control_delay)) gdk_delay = gdkpixbuf.gdk_pixbuf_animation_iter_get_delay_time(iter) gdk_delay *= 1000 # milliseconds to microseconds # Compare gdk_delay to control_delay for interest only. #print control_delay, gdk_delay / 1000000. if gdk_delay == -1: break us = time.tv_usec + gdk_delay time.tv_sec += us // 1000000 time.tv_usec = us % 1000000 gdkpixbuf.gdk_pixbuf_animation_iter_advance(iter, byref(time)) return Animation(frames)
def _get_gif_delays(self): # GDK pixbuf animations will loop indefinitely if looping is enabled for the # gif, so get number of frames and delays from gif metadata assert self._file is not None self._file.seek(0) gif_stream = gif.read(self._file) return [image.delay for image in gif_stream.images]
def decode_animation(self, file, filename): # Extract GIF control data. If it's not a GIF, this method will # raise. gif_stream = gif.read(file) delays = [image.delay for image in gif_stream.images] # Get GDK animation iterator file.seek(0) anim = self._load(file, filename, gdkpixbuf.gdk_pixbuf_loader_get_animation) time = GTimeVal(0, 0) iter = gdkpixbuf.gdk_pixbuf_animation_get_iter(anim, byref(time)) frames = list() # Extract each image for control_delay in delays: pixbuf = gdkpixbuf.gdk_pixbuf_animation_iter_get_pixbuf(iter) # When attempting to load animated gifs with an alpha channel on # linux gdkpixbuf will normally return a null pixbuf for the final # frame resulting in a segfault: # http://code.google.com/p/pyglet/issues/detail?id=411 # Since it is unclear why exactly this happens, the workaround # below is to start again and extract that frame on its own. if pixbuf == None: file.seek(0) anim = self._load(file, filename, gdkpixbuf.gdk_pixbuf_loader_get_animation) temptime = GTimeVal(0, 0) iter = gdkpixbuf.gdk_pixbuf_animation_get_iter( anim, byref(temptime)) gdkpixbuf.gdk_pixbuf_animation_iter_advance(iter, byref(time)) pixbuf = gdkpixbuf.gdk_pixbuf_animation_iter_get_pixbuf(iter) image = self._pixbuf_to_image(pixbuf) frames.append(AnimationFrame(image, control_delay)) gdk_delay = gdkpixbuf.gdk_pixbuf_animation_iter_get_delay_time( iter) if gdk_delay == -1: break gdk_delay = gdkpixbuf.gdk_pixbuf_animation_iter_get_delay_time( iter) gdk_delay *= 1000 # milliseconds to microseconds # Compare gdk_delay to control_delay for interest only. # print control_delay, gdk_delay / 1000000. us = time.tv_usec + gdk_delay time.tv_sec += us // 1000000 time.tv_usec = us % 1000000 gdkpixbuf.gdk_pixbuf_animation_iter_advance(iter, byref(time)) return Animation(frames)
def decode_animation(self, file, filename): # Extract GIF control data. If it's not a GIF, this method will # raise. gif_stream = gif.read(file) delays = [image.delay for image in gif_stream.images] # Get GDK animation iterator file.seek(0) anim = self._load(file, filename, gdkpixbuf.gdk_pixbuf_loader_get_animation) time = GTimeVal(0, 0) iter = gdkpixbuf.gdk_pixbuf_animation_get_iter(anim, byref(time)) frames = [] # Extract each image for control_delay in delays: pixbuf = gdkpixbuf.gdk_pixbuf_animation_iter_get_pixbuf(iter) image = self._pixbuf_to_image(pixbuf) frames.append(AnimationFrame(image, control_delay)) gdk_delay = gdkpixbuf.gdk_pixbuf_animation_iter_get_delay_time( iter) gdk_delay *= 1000 # milliseconds to microseconds # Compare gdk_delay to control_delay for interest only. #print control_delay, gdk_delay / 1000000. if gdk_delay == -1: break us = time.tv_usec + gdk_delay time.tv_sec += us // 1000000 time.tv_usec = us % 1000000 gdkpixbuf.gdk_pixbuf_animation_iter_advance(iter, byref(time)) return Animation(frames)