Yalantis/uCrop · error · CImgIOException

load_gif_external(): Failed to open file '%s'.

Error message

load_gif_external(): Failed to open file '%s'.

What it means

load_gif_external() tries GraphicsMagick, then ImageMagick, then CImg's generic load_other() fallback. If all attempts fail, the list stays empty and it throws this CImgIOException. Typically the external convert/magick/gm binary is missing or fails to decode the GIF, and the generic loader cannot handle the file either.

Source

Thrown at ucrop/src/main/jni/CImg.h:67514

    //! Load an image from a video file using the external tool 'ffmpeg' \newinstance.
    static CImgList<T> get_load_ffmpeg_external(const char *const filename) {
      return CImgList<T>().load_ffmpeg_external(filename);
    }

    //! Load gif file, using ImageMagick or GraphicsMagick's external tools.
    /**
      \param filename Filename to read data from.
    **/
    CImgList<T>& load_gif_external(const char *const filename) {
      if (!filename || !cimg::is_file(filename))
        throw CImgArgumentException(_cimglist_instance
                                    "load_gif_external(): Specified filename is (null) or does not exist.",
                                    cimglist_instance);
      if (!_load_gif_external(filename,false))
        if (!_load_gif_external(filename,true))
          try { assign(CImg<T>().load_other(filename)); } catch (CImgException&) { assign(); }
      if (is_empty())
        throw CImgIOException(_cimglist_instance
                              "load_gif_external(): Failed to open file '%s'.",
                              cimglist_instance,filename);
      return *this;
    }

    CImgList<T>& _load_gif_external(const char *const filename, const bool use_graphicsmagick=false) {
      CImg<charT> command(1024), filename_tmp(256), filename_tmp2(256);
      do {
        cimg_snprintf(filename_tmp,filename_tmp._width,"%s%c%s",
                      cimg::temporary_path(),cimg_file_separator,cimg::filenamerand());
        if (use_graphicsmagick) cimg_snprintf(filename_tmp2,filename_tmp2._width,"%s.png.0",filename_tmp._data);
        else cimg_snprintf(filename_tmp2,filename_tmp2._width,"%s-0.png",filename_tmp._data);
      } while (cimg::path_exists(filename_tmp2));
      if (use_graphicsmagick) cimg_snprintf(command,command._width,"%s convert \"%s\" \"%s.png\"",
                                            cimg::graphicsmagick_path(),
                                            CImg<charT>::string(filename)._system_strescape().data(),
                                            CImg<charT>::string(filename_tmp)._system_strescape().data());
      else cimg_snprintf(command,command._width,"\"%s\" -coalesce \"%s\" \"%s.png\"",

View on GitHub (pinned to f788b534b4)

Solutions

  1. Install ImageMagick (or GraphicsMagick) and ensure cimg::magick_path()/cimg::graphicsmagick_path() resolves to the binary.
  2. Verify with 'magick identify file.gif' (or 'gm identify') that the tools can decode the file.
  3. Pre-decode the GIF to PNG frames with your own tool and load them with load_png, or split animated GIFs beforehand.
  4. Check the file integrity (e.g. 'file x.gif', re-export from an editor) if tools are installed but decoding still fails.

Example fix

// before
list.load_gif_external("anim.gif"); // no ImageMagick in container

// after
// Dockerfile: RUN apt-get install -y imagemagick
cimg::magick_path("/usr/bin/magick");
list.load_gif_external("anim.gif");
Defensive patterns

Strategy: fallback

Validate before calling

// ensure ImageMagick is available before the external GIF path
bool magickAvailable() {
  return cimg::system(
    CImg<char>::string(cimg::magick_path()) + " -version") == 0;
}

Try / catch

try {
  list.load_gif_external(file);
} catch (CImgIOException&) {
  // last-resort generic loader or manual pre-decode
  try { list.assign(CImg<unsigned char>().load_other(file)); }
  catch (CImgException&) { /* unhandleable */ }
}

Prevention

When it happens

Trigger: load_gif_external() on a system without ImageMagick/GraphicsMagick installed (or not found at cimg::magick_path()/graphicsmagick_path()), or with a corrupt/unsupported file that also defeats load_other().

Common situations: Minimal Docker/CI images lacking ImageMagick; magick_path misconfigured; GIF variants (e.g. huge or malformed frames) rejected by all loaders; Android native builds with no external tools at all.

Understand the failure class

Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.

Related errors


AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08). Data as JSON: /api/errors/2f2cc28eaee88cfe. Report an issue: GitHub.