def test_write_gif(util, clip_class, opt, loop, with_mask, pixel_format): filename = os.path.join(util.TMP_DIR, "moviepy_write_gif.gif") if os.path.isfile(filename): os.remove(filename) fps = 10 if clip_class == "BitmapClip": original_clip = BitmapClip([["R"], ["G"], ["B"]], fps=fps).with_duration(0.3) else: original_clip = concatenate_videoclips([ ColorClip( (1, 1), color=color, ).with_duration(0.1).with_fps(fps) for color in [(255, 0, 0), (0, 255, 0), (0, 0, 255)] ]) if with_mask: original_clip = original_clip.with_mask( ColorClip((1, 1), color=1, is_mask=True).with_fps(fps).with_duration(0.3)) kwargs = {} if pixel_format is not None: kwargs["pixel_format"] = pixel_format write_gif( original_clip, filename, fps=fps, with_mask=with_mask, program="ffmpeg", logger=None, opt=opt, loop=loop, **kwargs, ) if pixel_format != "invalid": final_clip = VideoFileClip(filename) r, g, b = final_clip.get_frame(0)[0][0] assert r == 252 assert g == 0 assert b == 0 r, g, b = final_clip.get_frame(0.1)[0][0] assert r == 0 assert g == 252 assert b == 0 r, g, b = final_clip.get_frame(0.2)[0][0] assert r == 0 assert g == 0 assert b == 255 assert final_clip.duration == (loop or 1) * round( original_clip.duration, 6)
def write_gif( self, filename, fps=None, program="imageio", opt="nq", fuzz=1, loop=0, dispose=False, colors=None, tempfiles=False, logger="bar", pixel_format=None, ): """Write the VideoClip to a GIF file. Converts a VideoClip into an animated GIF using ImageMagick or ffmpeg. Parameters ---------- filename Name of the resulting gif file, as a string or a path-like object. fps Number of frames per second (see note below). If it isn't provided, then the function will look for the clip's ``fps`` attribute (VideoFileClip, for instance, have one). program Software to use for the conversion, either 'imageio' (this will use the library FreeImage through ImageIO), or 'ImageMagick', or 'ffmpeg'. opt Optimalization to apply. If program='imageio', opt must be either 'wu' (Wu) or 'nq' (Neuquant). If program='ImageMagick', either 'optimizeplus' or 'OptimizeTransparency'. fuzz (ImageMagick only) Compresses the GIF by considering that the colors that are less than fuzz% different are in fact the same. tempfiles Writes every frame to a file instead of passing them in the RAM. Useful on computers with little RAM. Can only be used with ImageMagick' or 'ffmpeg'. progress_bar If True, displays a progress bar pixel_format Pixel format for the output gif file. If is not specified 'rgb24' will be used as the default format unless ``clip.mask`` exist, then 'rgba' will be used. This option is only going to be accepted if ``program=ffmpeg`` or when ``tempfiles=True`` Notes ----- The gif will be playing the clip in real time (you can only change the frame rate). If you want the gif to be played slower than the clip you will use :: >>> # slow down clip 50% and make it a gif >>> myClip.multiply_speed(0.5).to_gif('myClip.gif') """ # A little sketchy at the moment, maybe move all that in write_gif, # refactor a little... we will see. if program == "imageio": write_gif_with_image_io( self, filename, fps=fps, opt=opt, loop=loop, colors=colors, logger=logger, ) elif tempfiles: # convert imageio opt variable to something that can be used with # ImageMagick opt = "optimizeplus" if opt == "nq" else "OptimizeTransparency" write_gif_with_tempfiles( self, filename, fps=fps, program=program, opt=opt, fuzz=fuzz, loop=loop, dispose=dispose, colors=colors, logger=logger, pixel_format=pixel_format, ) else: # convert imageio opt variable to something that can be used with # ImageMagick opt = "optimizeplus" if opt == "nq" else "OptimizeTransparency" write_gif( self, filename, fps=fps, program=program, opt=opt, fuzz=fuzz, loop=loop, dispose=dispose, colors=colors, logger=logger, pixel_format=pixel_format, )