Yalantis/uCrop · error · CImgInstanceException

crop(): Empty instance.

Error message

crop(): Empty instance.

What it means

CImg's crop()/get_crop() operates on pixel data of the instance it is called on, so it refuses to run on an empty (zero-dimension or unassigned) image. If is_empty() is true it throws CImgInstanceException with 'crop(): Empty instance.' This guards against computing coordinates on an image with no data.

Source

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

       \param c0 = C-coordinate of the upper-left crop rectangle corner.
       \param x1 = X-coordinate of the lower-right crop rectangle corner.
       \param y1 = Y-coordinate of the lower-right crop rectangle corner.
       \param z1 = Z-coordinate of the lower-right crop rectangle corner.
       \param c1 = C-coordinate of the lower-right crop rectangle corner.
       \param boundary_conditions = Can be { 0=dirichlet | 1=neumann | 2=periodic | 3=mirror }.
    **/
    CImg<T>& crop(const int x0, const int y0, const int z0, const int c0,
                  const int x1, const int y1, const int z1, const int c1,
                  const unsigned int boundary_conditions=0) {
      return get_crop(x0,y0,z0,c0,x1,y1,z1,c1,boundary_conditions).move_to(*this);
    }

    //! Crop image region \newinstance.
    CImg<T> get_crop(const int x0, const int y0, const int z0, const int c0,
                     const int x1, const int y1, const int z1, const int c1,
                     const unsigned int boundary_conditions=0) const {
      if (is_empty())
        throw CImgInstanceException(_cimg_instance
                                    "crop(): Empty instance.",
                                    cimg_instance);
      const int
        nx0 = x0<x1?x0:x1, nx1 = x0^x1^nx0,
        ny0 = y0<y1?y0:y1, ny1 = y0^y1^ny0,
        nz0 = z0<z1?z0:z1, nz1 = z0^z1^nz0,
        nc0 = c0<c1?c0:c1, nc1 = c0^c1^nc0;
      const unsigned int
        _boundary_conditions = nx0>=0 && nx1<width() &&
                               ny0>=0 && ny1<height() &&
                               nz0>=0 && nz1<depth() &&
                               nc0>=0 && nc1<spectrum()?0:boundary_conditions;
      CImg<T> res(1U + nx1 - nx0,1U + ny1 - ny0,1U + nz1 - nz0,1U + nc1 - nc0);
      if (nx0<0 || nx1>=width() || ny0<0 || ny1>=height() || nz0<0 || nz1>=depth() || nc0<0 || nc1>=spectrum())
        switch (_boundary_conditions) {
        case 3 : { // Mirror
          const int w2 = 2*width(), h2 = 2*height(), d2 = 2*depth(), s2 = 2*spectrum();
          cimg_pragma_openmp(parallel for cimg_openmp_collapse(3) cimg_openmp_if(_width>=(cimg_openmp_sizefactor)*16 &&

View on GitHub (pinned to f788b534b4)

Solutions

  1. Check img.is_empty() (or !img) before calling crop() and handle the empty case explicitly.
  2. Verify the image was actually loaded: check the return of load()/constructor and that width()/height() are non-zero before cropping.
  3. Fix the upstream cause — correct the file path/format or the producing step so the image contains data.
  4. If empty input is legitimate, skip the crop or substitute a placeholder image instead of cropping.

Example fix

// before
CImg<unsigned char> img("missing.png"); // load fails, img is empty
img.crop(0,0,99,99); // throws: Empty instance
// after
CImg<unsigned char> img("missing.png");
if (!img.is_empty()) img.crop(0,0,99,99);
Defensive patterns

Strategy: type-guard

Validate before calling

// C++
if (img.is_empty() || !img) {
    // skip or load/repair the image before cropping
    return;
}
img.crop(x0, y0, z0, c0, x1, y1, z1, c1);

Type guard

bool isCroppers = !img.is_empty() && img.width() > 0 && img.height() > 0;

Try / catch

try {
    img.crop(x0, y0, z0, c0, x1, y1, z1, c1);
} catch (const cimg_library::CImgInstanceException& e) {
    // img was empty: log and recover (reload, skip, or placeholder)
}

Prevention

When it happens

Trigger: Calling img.crop(x0,y0,z0,c0,x1,y1,z1,c1) on a CImg that was default-constructed, assigned from a failed load (CImg(filename) with missing file leaves an empty image), or explicitly resized to 0. Also after assign() resets, or when a getter returned an empty image that was passed along un-checked.

Common situations: Image file failed to load (wrong path/format) so the CImg stayed empty; a decode step returned an empty buffer; an optional image that was never initialized flows into a crop call; a filtered pipeline step produced a 0-size result that is then cropped.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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