code: def write_gif(
      clip,
      filename,
      fps=None,
      with_mask=True,
      program="ImageMagick",
      opt="OptimizeTransparency",
      fuzz=1,
      loop=0,
      dispose=True,
      colors=None,
      pixel_format=None,
      logger="bar",
  ):
      """Write the VideoClip to a GIF file, without temporary files.
  
      Converts a VideoClip into an animated GIF using ImageMagick
      or ffmpeg.
  
  
      Parameters
      ----------
  
      clip : moviepy.video.VideoClip.VideoClip
        The clip from which the frames will be extracted to create the GIF image.
  
      filename : str
        Name of the resulting gif file.
  
      fps : int, optional
        Number of frames per second. If it isn't provided, then the function will
        look for the clip's ``fps`` attribute.
  
      with_mask : bool, optional
        Includes the mask of the clip in the output (the clip must have a mask
        if this argument is ``True``).
  
      program : str, optional
        Software to use for the conversion, either ``"ImageMagick"`` or
        ``"ffmpeg"``.
  
      opt : str, optional
        ImageMagick only optimalization to apply, either ``"optimizeplus"`` or
        ``"OptimizeTransparency"``. Doesn't takes effect if ``program="ffmpeg"``.
  
      fuzz : float, optional
        ImageMagick only compression option which compresses the GIF by
        considering that the colors that are less than ``fuzz`` different are in
        fact the same.
  
      loop : int, optional
        Repeat the clip using ``loop`` iterations in the resulting GIF.
  
      dispose : bool, optional
        ImageMagick only option which, when enabled, the ImageMagick binary will
        take the argument `-dispose 2`, clearing the frame area with the
        background color, otherwise it will be defined as ``-dispose 1`` which
        will not dispose, just overlays next frame image.
  
      colors : int, optional
        ImageMagick only option for color reduction. Defines the maximum number
        of colors that the output image will have.
  
      pixel_format : str, optional
        FFmpeg 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. Doesn't takes effect if
        ``program="ImageMagick"``.
  
      logger : str, optional
        Either ``"bar"`` for progress bar or ``None`` or any Proglog logger.
  
  
      Examples
      --------
  
      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).write_gif('myClip.gif')
      """
      #
      # We use processes chained with pipes.
      #
      # if program == 'ffmpeg'
      # frames --ffmpeg--> gif
      #
      # if program == 'ImageMagick' and optimize == (None, False)
      # frames --ffmpeg--> bmp frames --ImageMagick--> gif
      #
      #
      # if program == 'ImageMagick' and optimize != (None, False)
      # frames -ffmpeg-> bmp frames -ImagMag-> gif -ImagMag-> better gif
      #
  
      delay = 100.0 / fps
      logger = proglog.default_bar_logger(logger)
      if clip.mask is None:
          with_mask = False
      if not pixel_format:
          pixel_format = "rgba" if with_mask else "rgb24"
  
      cmd1 = [
          FFMPEG_BINARY,
          "-y",
          "-loglevel",
          "error",
          "-f",
          "rawvideo",
          "-vcodec",
          "rawvideo",
          "-r",
          "%.02f" % fps,
          "-s",
          "%dx%d" % (clip.w, clip.h),
          "-pix_fmt",
          (pixel_format),
          "-i",
          "-",
      ]
  
      popen_params = cross_platform_popen_params(
          {
              "stdout": sp.DEVNULL,
              "stderr": sp.DEVNULL,
              "stdin": sp.DEVNULL,
          }
      )
  
      if program == "ffmpeg":
          if loop:
              clip = loop_fx(clip, n=loop)
  
          popen_params["stdin"] = sp.PIPE
          popen_params["stdout"] = sp.DEVNULL
  
          proc1 = sp.Popen(
              cmd1
              + [
                  "-pix_fmt",
                  (pixel_format),
                  "-r",
                  "%.02f" % fps,
                  filename,
              ],
              **popen_params,
          )
      else:
          popen_params["stdin"] = sp.PIPE
          popen_params["stdout"] = sp.PIPE
  
          proc1 = sp.Popen(
              cmd1 + ["-f", "image2pipe", "-vcodec", "bmp", "-"],
              **popen_params,
          )
  
      if program == "ImageMagick":
          cmd2 = [
              IMAGEMAGICK_BINARY,
              "-delay",
              "%.02f" % (delay),
              "-dispose",
              "%d" % (2 if dispose else 1),
              "-loop",
              "%d" % loop,
              "-",
              "-coalesce",
          ]
  
          if opt in [False, None]:
              popen_params["stdin"] = proc1.stdout
              popen_params["stdout"] = sp.DEVNULL
              proc2 = sp.Popen(cmd2 + [filename], **popen_params)
  
          else:
              popen_params["stdin"] = proc1.stdout
              popen_params["stdout"] = sp.PIPE
              proc2 = sp.Popen(cmd2 + ["gif:-"], **popen_params)
  
          if opt:
              cmd3 = (
                  [
                      IMAGEMAGICK_BINARY,
                      "-",
                      "-fuzz",
                      "%d" % fuzz + "%",
                      "-layers",
                      opt,
                  ]
                  + (
                      ["-colors", "%d" % colors]
                      if colors is not None
                      else []
                  )
                  + [filename]
              )
  
              popen_params["stdin"] = proc2.stdout
              popen_params["stdout"] = sp.DEVNULL
              proc3 = sp.Popen(cmd3, **popen_params)
  
      # We send all the frames to the first process
      logger(message="MoviePy - Building file  %s" % filename)
      logger(message="MoviePy - - Generating GIF frames.")
      try:
          for t, frame in clip.iter_frames(
              fps=fps, logger=logger, with_times=True, dtype="uint8"
          ):
              if with_mask:
                  mask = 255 * clip.mask.get_frame(t)
                  frame = np.dstack([frame, mask]).astype("uint8")
              proc1.stdin.write(frame.tobytes())
  
      except IOError as err:
          error = (
              "[MoviePy] Error: creation of %s failed because "
              "of the following error:\n\n%s.\n\n."
              % (filename, str(err))
          )
  
          if program == "ImageMagick":
              error += (
                  "This can be due to the fact that "
                  "ImageMagick is not installed on your computer, or "
                  "(for Windows users) that you didn't specify the "
                  "path to the ImageMagick binary. Check the documentation."
              )
  
          raise IOError(error)
      if program == "ImageMagick":
          logger(message="MoviePy - - Optimizing GIF with ImageMagick.")
      proc1.stdin.close()
      proc1.wait()
      if program == "ImageMagick":
          proc2.wait()
          if opt:
              proc3.wait()
      logger(message="MoviePy - - File ready: %s." % filename)
  
file_path: moviepy/moviepy/video/io/gif_writers.py
imports: import os
  import subprocess
  import numpy
  import proglog
  from moviepy.config import FFMPEG_BINARY, IMAGEMAGICK_BINARY
  from moviepy.decorators import requires_duration, use_clip_fps_by_default
  from moviepy.tools import cross_platform_popen_params, subprocess_call
  from moviepy.video.fx.loop import loop
label_desc: Use image node_id 2 for calling a global function with example usage: write_gif(clip, filename, fps, with_mask, program, opt, fuzz, loop, dispose, colors, pixel_format, logger) without return types