Yalantis/uCrop · warning

save_video(): Skip empty frame

Error message

save_video(): Skip empty frame %d for file '%s'.

What it means

While writing a video stream, save_video() iterates the list and warns for each empty frame encountered, skipping it in the output. Additionally, frames with more than 3 channels (spectrum>3) warn about incompatible dimensions with data possibly ignored. The video is still produced but with fewer/different frames than the list contains.

Solutions

  1. Filter or skip empty images before building the list passed to save_video
  2. Convert frames with spectrum>3 to 3 channels (e.g. keep first three channels or channels(0,2)) before saving
  3. Track frame indices externally rather than relying on list positions after removals
  4. Check each frame with is_empty() and spectrum in a validation pass before writing

Example fix

// before
frames.save_video("out.mp4", 30);
// after
CImgList<unsigned char> clean;
cimglist_for(frames, l) {
  if (!frames[l].is_empty())
    clean.insert(frames[l].get_channels(0, frames[l].spectrum() >= 3 ? 2 : frames[l].spectrum() - 1));
}
clean.save_video("out.mp4", 30);
Defensive patterns

Strategy: validation

Validate before calling

bool ok = !frame.is_empty() && frame.spectrum() <= 3; // check each frame before save_video
cimglist_for(frames, l) if (frames[l].is_empty() || frames[l].spectrum() > 3) { /* fix or drop */ }

Type guard

bool videoReady(const CImg<T>& im) { return !im.is_empty() && im.spectrum() >= 1 && im.spectrum() <= 3; }

Prevention

When it happens

Trigger: Appending or loading frames where some CImg entries are empty (failed loads, default-constructed entries, assign()ed slots); feeding multi-spectral (4+ channel) images into a video writer that supports at most 3 (RGB/BGR) channels.

Common situations: Partially failed batch loads leaving holes in a CImgList; multispectral/hyperspectral image lists written directly to video; frames erased by index while keeping list positions.

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

Appendix: source

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

            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);
          }
          CImg<charT>::string(filename).move_to(filenames[index]);
          sizes(index,0) = W;
          sizes(index,1) = H;
          cimg::mutex(9,0);
        }

        if (!is_empty()) {
          const unsigned int W = sizes(index,0), H = sizes(index,1);
          cimg::mutex(9);
          cimglist_for(*this,l) {
            CImg<T> &src = _data[l];
            if (src.is_empty())
              cimg::warn(_cimglist_instance
                         "save_video(): Skip empty frame %d for file '%s'.",
                         cimglist_instance,l,filename);
            if (src._spectrum>3)
              cimg::warn(_cimglist_instance
                         "save_video(): Frame %u has incompatible dimension (%u,%u,%u,%u). "
                         "Some image data may be ignored when writing frame into video file '%s'.",
                         cimglist_instance,l,src._width,src._height,src._depth,src._spectrum,filename);
            cimg_forZ(src,z) {
              CImg<T> _src = src._depth>1?src.get_slice(z):src.get_shared();
              if (_src._width==W && _src._height==H && _src._spectrum==3)
                writers[index]->write(CImg<ucharT>(_src)._cimg2cvmat());
              else {
                CImg<ucharT> __src(_src,false);
                __src.channels(0,std::min(__src._spectrum - 1,2U)).resize(W,H);
                __src.resize(W,H,1,3,__src._spectrum==1);
                writers[index]->write(__src._cimg2cvmat());
              }
            }

View on GitHub (pinned to f788b534b4)