Yalantis/uCrop · error · CImgIOException

load_imagemagick_external(): Failed to load file '%s' with e

Error message

load_imagemagick_external(): Failed to load file '%s' with external command 'magick/convert'.

What it means

CImg's load_imagemagick_external() shells out to ImageMagick ('magick'/'convert') to convert an unsupported format (e.g. TIFF, GIF, PDF) to PNM/PNG, then parses the temp file. This CImgIOException is thrown when the conversion command succeeded and produced a temp file, but parsing that temp file with load_pnm/load_other failed (the catch block around the load).

Source

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

                      "png"
#else
                      "pnm"
#endif
                      );
        std::FILE *file = popen(command,"r");
        if (file) {
          const unsigned int omode = cimg::exception_mode();
          cimg::exception_mode(0);
          try {
#ifdef cimg_use_png
            load_png(file);
#else
            load_pnm(file);
#endif
          } catch (...) {
            pclose(file);
            cimg::exception_mode(omode);
            throw CImgIOException(_cimg_instance
                                  "load_imagemagick_external(): Failed to load file '%s' with "
                                  "external command 'magick/convert'.",
                                  cimg_instance,
                                  filename);
          }
          pclose(file);
          return *this;
        }
      }
#endif
      do {
        cimg_snprintf(filename_tmp,filename_tmp._width,"%s%c%s.%s",
                      cimg::temporary_path(),
                      cimg_file_separator,
                      cimg::filenamerand(),
#ifdef cimg_use_png
                      "png"
#else

View on GitHub (pinned to f788b534b4)

Solutions

  1. Run 'magick convert <input> out.pnm' manually with the same input to see the real ImageMagick error and fix the delegate/policy it reports.
  2. Verify the temp directory (TMPDIR/TMP) is writable and has free space so the intermediate file is complete.
  3. Check ImageMagick's policy.xml and delegate configuration are intact and allow the target format.
  4. Pre-convert the file yourself with magick to a supported format (PNG/PNM) and load that directly with CImg<T>::load().
  5. Confirm the 'magick'/'convert' binary is a real ImageMagick 7 (or matching 6) install, not a shim that returns success spuriously.

Example fix

// before: blind external load
img.load_imagemagick_external("scan.pdf");
// after: check file decodes first / pre-convert
if (!cimg::is_file("scan.pdf")) throw ...
CImg<unsigned char> img;
try { img.load_imagemagick_external("scan.pdf"); }
catch (CImgIOException&) { cimg::system("magick scan.pdf scan.png"); img.load("scan.png"); }
Defensive patterns

Strategy: try-catch

Validate before calling

if (!cimg::is_file(path)) throw std::invalid_argument("missing input");
if (cimg::system("magick -version","magick")!=0) throw std::runtime_error("ImageMagick unavailable");

Type guard

bool loadableByMagick(const char* p){ return p && cimg::is_file(p) && cimg::fsize(p)>0; }

Try / catch

try { img.load_imagemagick_external(path); }
catch (CImgIOException& e) {
  // fallback: pre-convert then native load
  if (cimg::system((std::string("magick ")+path+" tmp_out.png").c_str())==0)
    img.load("tmp_out.png");
  else throw;
}

Prevention

When it happens

Trigger: Calling CImg<T>::load_imagemagick_external(filename) (or a load() that routes to it) where 'magick convert <tmp> <file>' runs without a nonzero exit but the generated temporary image cannot be decoded by load_pnm/load_other — e.g. magick produced an empty or zero-byte temp file, or wrote a format the built-in parsers cannot read.

Common situations: ImageMagick delegates failing silently (e.g. broken ghostscript delegate for PDFs), disk-full so the temp file is truncated, security policies (policy.xml) blocking a coder so magick exits 0 but writes nothing, or a converted file with a corrupted/unsupported intermediate format.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


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