Yalantis/uCrop · error · CImgInstanceException
save_video(): Frame [0] is an empty image.
Error message
save_video(): Frame [0] is an empty image.
What it means
Guard in CImgList<T>::save_video(): the first frame of the list (element [0]) is an empty image; the video writer needs valid frame dimensions derived from frame [0] to initialize the stream, so an empty first frame aborts saving.
Solutions
- Validate frames[0].width()>0 && frames[0].height()>0 before saving
- Skip or replace empty frames when populating the list
- Only append frames after confirming the capture succeeded
Example fix
// before
frames.push_back(CImg<unsigned char>()); // empty placeholder
frames.save_video("out.avi", 25);
// after
if (!frame.is_empty()) frames.push_back(frame);
frames.save_video("out.avi", 25); Defensive patterns
Strategy: validation
Validate before calling
// C++ bool valid = !frames.is_empty() && frames[0].width() > 0 && frames[0].height() > 0; if (!valid) return;
Type guard
bool hasSizedFrame(const CImgList<T>& l) { return !l.is_empty() && l[0].width() > 0 && l[0].height() > 0; } Try / catch
try { frames.save_video(fname, fps, codec); }
catch (CImgInstanceException& e) { log("first frame empty, skipping save"); } Prevention
- Never append default-constructed CImg placeholders
- Drop frames where width()==0 || height()==0 at capture time
- Assert frame dimensions when appending
- Validate capture device output before recording
When it happens
Trigger: Calling save_video() where the first frame in the list is a 0-width or 0-height image (default-constructed CImg, or failed frame allocation).
Common situations: Appending default-constructed CImg placeholders into the list; camera delivering an empty first frame before streaming starts.
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
- save_video(): Instance list is empty.
- load_video() : File ' ', arguments 'first_frame'…
- load_video(): File ' ', no video reader slots available…
- load_video(): File ' ', unable to detect format of video…
- load_video(): File ' ', unable to locate frame %u.
AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08).
Data as JSON: /api/errors/d6e3ba4278f31da7.
Report an issue: GitHub.
Appendix: source
Thrown at ucrop/src/main/jni/CImg.h:68584
if (index<0) {
if (!filename)
throw CImgArgumentException(_cimglist_instance
"save_video(): No already open video writer found. You must specify a "
"non-(null) filename argument for the first call.",
cimglist_instance);
else { cimg::mutex(9); cimglist_for(filenames,l) if (!filenames[l]) { index = l; break; } cimg::mutex(9,0); }
if (index<0)
throw CImgIOException(_cimglist_instance
"save_video(): File '%s', no video writer slots available. "
"You have to release some of your previously opened videos.",
cimglist_instance,filename);
if (is_empty())
throw CImgInstanceException(_cimglist_instance
"save_video(): Instance list is empty.",
cimglist_instance);
const unsigned int W = _data?_data[0]._width:0, H = _data?_data[0]._height:0;
if (!W || !H)
throw CImgInstanceException(_cimglist_instance
"save_video(): Frame [0] is an empty image.",
cimglist_instance);
const char
*const _codec = codec && *codec?codec:"h264",
codec0 = cimg::uppercase(_codec[0]),
codec1 = _codec[0]?cimg::uppercase(_codec[1]):0,
codec2 = _codec[1]?cimg::uppercase(_codec[2]):0,
codec3 = _codec[2]?cimg::uppercase(_codec[3]):0;
cimg::mutex(9);
writers[index] = new cv::VideoWriter(filename,_cimg_fourcc(codec0,codec1,codec2,codec3),fps,cv::Size(W,H));
if (!writers[index]->isOpened()) {
delete writers[index];
writers[index] = 0;
cimg::mutex(9,0);
throw CImgIOException(_cimglist_instance
"save_video(): File '%s', unable to initialize video writer with codec '%c%c%c%c'.",
cimglist_instance,filename,
codec0,codec1,codec2,codec3);View on GitHub (pinned to f788b534b4)