Yalantis/uCrop · error · CImgIOException
save_graphicsmagick_external(): Failed to save file
Error message
save_graphicsmagick_external(): Failed to save file '%s' with external command 'gm'.
What it means
CImg::save_graphicsmagick_external() shells out to the GraphicsMagick 'gm convert' executable to write the image to a format CImg does not natively support. This error is thrown when either the 'gm' system command returns a non-zero exit status, or the command 'succeeds' but the expected output file does not exist afterwards. It means the external GraphicsMagick invocation failed to produce the target file.
Solutions
- Install GraphicsMagick or verify cimg::graphicsmagick_path() points to a valid 'gm' executable (test by running the command manually).
- Check that the output directory exists and is writable by the process.
- Simplify: run the constructed 'gm convert ...' command by hand to see the real error message.
- Use CImg's native save() for formats it supports, or save to a temporary supported format first.
- Verify the target format/extension is supported by the installed GraphicsMagick version.
Example fix
// before
img.save_graphicsmagick_external("out.png", 100);
// after
if (cimg::path_exists(cimg::graphicsmagick_path()) || !std::system("gm version > /dev/null 2>&1"))
img.save_graphicsmagick_external("out.png", 100);
else
img.save_png("out.png"); // fallback to native save Defensive patterns
Strategy: try-catch
Validate before calling
bool gmAvailable() { return std::system("gm version > /dev/null 2>&1") == 0; }
if (!gmAvailable()) { /* fallback to native save */ }
if (!cimg::path_exists(outputDir)) { /* create or error out early */ } Try / catch
try {
img.save_graphicsmagick_external(filename, quality);
} catch (CImgIOException& e) {
std::fprintf(stderr, "gm save failed: %s", e.what());
img.save_png(fallbackName); // native fallback
} Prevention
- Install GraphicsMagick in every deployment environment and verify with 'gm version'.
- Set/verify the GraphicsMagick path configuration before saving.
- Check output directory writability before calling save.
- Prefer CImg native save() for supported formats to avoid the external dependency.
When it happens
Trigger: Calling save_graphicsmagick_external(filename, quality) when: the 'gm' binary is not installed or cimg::graphicsmagick_path() points to a missing/wrong path; the command fails due to bad permissions, unsupported format, or a bad quality value; or 'gm' exits 0 but fails to write the requested output filename (e.g. unwritable directory).
Common situations: Deploying to an environment (e.g. Android NDK builds, Docker containers) where GraphicsMagick is not installed; graphicsmagick_path env var (CIMG_GRAPHICS MAGICK_PATH) misconfigured; output directory lacks write permission; requested format extension not understood by the installed gm version.
Related errors
- save_imagemagick_external(): Failed to save file
- save_other(): Failed to save file
- save_medcon_external(): Failed to save file
- cimg::load_network(): Failed to load file
- load_graphicsmagick_external(): Failed to load file
AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08).
Data as JSON: /api/errors/d4f8212ee51ee66b.
Report an issue: GitHub.
Appendix: source
Thrown at ucrop/src/main/jni/CImg.h:63747
#endif
CImg<charT> command(1024), filename_tmp(256);
do {
cimg_snprintf(filename_tmp,filename_tmp._width,"%s%c%s.%s",
cimg::temporary_path(),cimg_file_separator,cimg::filenamerand(),
_spectrum==1?_cimg_sge_extension1:_cimg_sge_extension2);
} while (cimg::path_exists(filename_tmp));
#ifdef cimg_use_png
save_png(filename_tmp);
#else
save_pnm(filename_tmp);
#endif
cimg_snprintf(command,command._width,"\"%s\" convert -quality %u \"%s\" \"%s\"",
cimg::graphicsmagick_path(),quality,
CImg<charT>::string(filename_tmp)._system_strescape().data(),
CImg<charT>::string(filename)._system_strescape().data());
if (cimg::system(command,cimg::graphicsmagick_path())!=0)
throw CImgIOException(_cimg_instance
"save_graphicsmagick_external(): Failed to save file '%s' with external command 'gm'.",
cimg_instance,
filename);
if (!cimg::path_exists(filename))
throw CImgIOException(_cimg_instance
"save_graphicsmagick_external(): Failed to save file '%s' with external command 'gm'.",
cimg_instance,
filename);
std::remove(filename_tmp);
return *this;
}
//! Save image using ImageMagick's external binary.
/**
\param filename Filename, as a C-string.
\param quality Image quality (expressed in percent), when the file format supports it.
\note This method uses \c convert, an external executable binary provided byView on GitHub (pinned to f788b534b4)