Yalantis/uCrop · warning

save_jpeg(): Instance is volumetric, only the first slice…

Error message

save_jpeg(): Instance is volumetric, only the first slice will be saved in file '%s'.

What it means

JPEG stores a single 2D image; save_jpeg() cannot write volumes. When _depth>1 the library warns that only the first slice (z=0) is saved and proceeds, so the remaining slices are silently lost (unless the no-libjpeg fallback path redirects to save_other, which has the same limitation).

Solutions

  1. Save a chosen slice: volume.get_slice(z).save_jpeg("slice.jpg").
  2. Use save_tiff (multi-page) or save_cimg to keep the whole volume in one file.
  3. Loop over z and write one JPEG per slice with a numbered filename scheme.
  4. If quality matters, prefer lossless formats (PNG/TIFF) instead of JPEG for volume slices.

Example fix

// before
volume.save_jpeg("out.jpg"); // only slice 0 saved
// after
for (int z = 0; z < volume.depth(); ++z)
  volume.get_slice(z).save_jpeg(cimg::format("out_z%04d.jpg", z), 95);
Defensive patterns

Strategy: validation

Validate before calling

if (img.depth() > 1) throw std::logic_error("JPEG stores one slice; save slices individually or use TIFF");
img.save_jpeg(path, quality);

Type guard

bool is2D(const CImg<T>& im) { return im.depth() == 1; }

Prevention

When it happens

Trigger: CImg::save_jpeg() or save("file.jpg") on a volumetric image (_depth>1), e.g. medical volumes, 3D simulation stacks, or image sequences kept in one CImg instance.

Common situations: Exporting 3D stacks to JPEG for previews; save() dispatching on .jpg/.jpeg extension for volume data; z-stack processing pipelines exporting the wrong variable.

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/ff2616177884e34b. Report an issue: GitHub.

Appendix: source

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

      \param quality Image quality (in %)
    **/
    const CImg<T>& save_jpeg(const char *const filename, const unsigned int quality=100) const {
      return _save_jpeg(0,filename,quality);
    }

    //! Save image as a JPEG file \overloading.
    const CImg<T>& save_jpeg(std::FILE *const file, const unsigned int quality=100) const {
      return _save_jpeg(file,0,quality);
    }

    const CImg<T>& _save_jpeg(std::FILE *const file, const char *const filename, const unsigned int quality) const {
      if (!file && !filename)
        throw CImgArgumentException(_cimg_instance
                                    "save_jpeg(): Specified filename is (null).",
                                    cimg_instance);
      if (is_empty()) { cimg::fempty(file,filename); return *this; }
      if (_depth>1)
        cimg::warn(_cimg_instance
                   "save_jpeg(): Instance is volumetric, only the first slice will be saved in file '%s'.",
                   cimg_instance,
                   filename?filename:"(FILE*)");

#ifndef cimg_use_jpeg
      if (!file) return save_other(filename,quality);
      else throw CImgIOException(_cimg_instance
                                 "save_jpeg(): Unable to save data in '(*FILE)' unless libjpeg is enabled.",
                                 cimg_instance);
#else
      unsigned int dimbuf = 0;
      J_COLOR_SPACE colortype = JCS_RGB;

      switch (_spectrum) {
      case 1 : dimbuf = 1; colortype = JCS_GRAYSCALE; break;
      case 2 : dimbuf = 3; colortype = JCS_RGB; break;
      case 3 : dimbuf = 3; colortype = JCS_RGB; break;
      default : dimbuf = 4; colortype = JCS_CMYK; break;

View on GitHub (pinned to f788b534b4)