Yalantis/uCrop · error · CImgArgumentException

render(): Empty specified image.

Error message

render(): Empty specified image.

What it means

CImgDisplay::render(const CImg<T>&) throws CImgArgumentException when the source image is empty. Rendering requires valid pixel data to copy into the display buffer; an empty image has none. Note render() also silently returns if the display itself is empty, so this exception specifically signals an empty image argument.

Solutions

  1. Guard the render call with if (img) render(img).
  2. Verify the image producer (load, crop, append) returned a non-empty image each frame.
  3. If the display may also be empty, prefer display(img) which handles empty displays via assign(img).

Example fix

// before
for (...) disp.render(frames[i]); // throws on failed decode
// after
if (frames[i]) disp.render(frames[i]); else disp.paint();
Defensive patterns

Strategy: validation

Validate before calling

if (img && !disp.is_empty()) disp.render(img).paint();

Type guard

bool renderable(const cimg_library::CImg<T>& img, const cimg_library::CImgDisplay& d) { return (bool)img && !d.is_empty(); }

Try / catch

try { disp.render(img); }
catch (cimg_library::CImgArgumentException &e) { fprintf(stderr, "%s", e.what()); }

Prevention

When it happens

Trigger: Calling render(img) directly, or indirectly via display(img) on a non-empty display, with an img whose _width/_height are 0.

Common situations: Rendering frames in a loop where a decode step failed on some iteration; passing a cropped sub-image that ended up zero-sized; using an image constructed with CImg(w=0,h=0).

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

Appendix: source

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

                                     (int)_width,(int)_height);
      }
      SDL_UpdateTexture(_texture,0,_data,_width*sizeof(unsigned int));
      SDL_RenderClear(_renderer);
      SDL_FRect rect;
      rect.x = rect.y = 0;
      rect.w = (float)_width;
      rect.h = (float)_height;
      SDL_RenderTexture(_renderer,_texture,0,&rect);
      SDL_RenderPresent(_renderer);
      _paint_request = false;
      SDL3_attr.unlock();
      return *this;
    }

    template<typename T>
    CImgDisplay& render(const CImg<T>& img) {
      if (!img)
        throw CImgArgumentException(_cimgdisplay_instance
                                    "render(): Empty specified image.",
                                    cimgdisplay_instance);

      if (is_empty()) return *this;
      if (img._depth!=1) return render(img.get_projections2d((img._width - 1)/2,(img._height - 1)/2,
                                                             (img._depth - 1)/2));
      cimg::SDL3_attr &SDL3_attr = cimg::SDL3_attr::ref();
      SDL3_attr.lock();
      const T
        *data1 = img._data,
        *data2 = (img._spectrum>=2)?img.data(0,0,0,1):data1,
        *data3 = (img._spectrum>=3)?img.data(0,0,0,2):data1;

      unsigned int
        *const ndata = (img._width==_width && img._height==_height)?_data:
        new unsigned int[(size_t)img._width*img._height],
        *ptrd = ndata;

View on GitHub (pinned to f788b534b4)