Yalantis/uCrop · warning

save_other(): File '%s', saving a volumetric image with an e

Error message

save_other(): File '%s', saving a volumetric image with an external call to ImageMagick only writes the first image slice.

What it means

Same family as the GraphicsMagick variant: when save_other() delegates to an external ImageMagick process (save_imagemagick_external), a volumetric image (_depth>1) is flattened to the first slice because the temp file handed to the 'convert' binary contains only slice 0. CImg warns and continues; deeper slices are lost.

Source

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

      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 by
       <a href="http://www.imagemagick.org">ImageMagick</a>.
       It must be installed for the method to succeed.
    **/
    const CImg<T>& save_imagemagick_external(const char *const filename, const unsigned int quality=100) const {
      if (!filename)
        throw CImgArgumentException(_cimg_instance
                                    "save_imagemagick_external(): Specified filename is (null).",
                                    cimg_instance);
      if (is_empty()) { cimg::fempty(0,filename); return *this; }
      if (_depth>1)
        cimg::warn(_cimg_instance
                   "save_other(): File '%s', saving a volumetric image with an external call to "
                   "ImageMagick only writes the first image slice.",
                   cimg_instance,filename);
#ifdef cimg_use_png
#define _cimg_sie_extension1 "png"
#define _cimg_sie_extension2 "png"
#else
#define _cimg_sie_extension1 "pgm"
#define _cimg_sie_extension2 "ppm"
#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_sie_extension1:_cimg_sie_extension2);
      } while (cimg::path_exists(filename_tmp));
#ifdef cimg_use_png
      save_png(filename_tmp);
#else

View on GitHub (pinned to f788b534b4)

Solutions

  1. Rebuild with native codec macros (cimg_use_png, cimg_use_jpeg, cimg_use_tiff) to avoid the external path
  2. Write each slice separately: img.get_slice(z).save_* per z
  3. Use save_cimg() or a volumetric format (TIFF) for 3D data

Example fix

// before
volume.save_other("out.jpg");       // external convert, only slice 0
// after
for (int z = 0; z < volume.depth(); ++z)
  volume.get_slice(z).save_jpeg(cimg::format("out_%03d.jpg", z));
Defensive patterns

Strategy: validation

Validate before calling

if (img.depth() > 1)
  for (int z = 0; z < img.depth(); ++z) img.get_slice(z).save(cimg::format("out_%03d.jpg", z));
else
  img.save("out.jpg");

Type guard

bool is_2d(const cimg_library::CImg<T>& img) { return img.depth() == 1; }

Try / catch

try { img.save("out.jpg"); } catch (CImgException& e) { /* handle */ }

Prevention

When it happens

Trigger: Calling save_other()/save_imagemagick_external() with _depth>1 and no native codec compiled (no cimg_use_png/cimg_use_jpeg), so CImg invokes the ImageMagick 'convert' command.

Common situations: Minimal Linux builds lacking libpng/libjpeg so external ImageMagick is used; saving z-stacks to PNG/JPEG; choosing formats not natively compiled into CImg.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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