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.

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)

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.