{"record":{"id":"8ed35ccadb8a7ac1","repo":"Yalantis/uCrop","slug":"save-video-skip-empty-frame-d-for-file-s","errorCode":null,"errorMessage":"save_video(): Skip empty frame %d for file '%s'.","messagePattern":"save_video\\(\\): Skip empty frame (.+?) for file '(.+?)'\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"ucrop/src/main/jni/CImg.h","lineNumber":68616,"sourceCode":"            cimg::mutex(9,0);\n            throw CImgIOException(_cimglist_instance\n                                  \"save_video(): File '%s', unable to initialize video writer with codec '%c%c%c%c'.\",\n                                  cimglist_instance,filename,\n                                  codec0,codec1,codec2,codec3);\n          }\n          CImg<charT>::string(filename).move_to(filenames[index]);\n          sizes(index,0) = W;\n          sizes(index,1) = H;\n          cimg::mutex(9,0);\n        }\n\n        if (!is_empty()) {\n          const unsigned int W = sizes(index,0), H = sizes(index,1);\n          cimg::mutex(9);\n          cimglist_for(*this,l) {\n            CImg<T> &src = _data[l];\n            if (src.is_empty())\n              cimg::warn(_cimglist_instance\n                         \"save_video(): Skip empty frame %d for file '%s'.\",\n                         cimglist_instance,l,filename);\n            if (src._spectrum>3)\n              cimg::warn(_cimglist_instance\n                         \"save_video(): Frame %u has incompatible dimension (%u,%u,%u,%u). \"\n                         \"Some image data may be ignored when writing frame into video file '%s'.\",\n                         cimglist_instance,l,src._width,src._height,src._depth,src._spectrum,filename);\n            cimg_forZ(src,z) {\n              CImg<T> _src = src._depth>1?src.get_slice(z):src.get_shared();\n              if (_src._width==W && _src._height==H && _src._spectrum==3)\n                writers[index]->write(CImg<ucharT>(_src)._cimg2cvmat());\n              else {\n                CImg<ucharT> __src(_src,false);\n                __src.channels(0,std::min(__src._spectrum - 1,2U)).resize(W,H);\n                __src.resize(W,H,1,3,__src._spectrum==1);\n                writers[index]->write(__src._cimg2cvmat());\n              }\n            }","sourceCodeStart":68598,"sourceCodeEnd":68634,"githubUrl":"https://github.com/Yalantis/uCrop/blob/f788b534b48c144edf786c8cddbf0e029e637804/ucrop/src/main/jni/CImg.h#L68598-L68634","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Filter or skip empty images before building the list passed to save_video","Convert frames with spectrum>3 to 3 channels (e.g. keep first three channels or channels(0,2)) before saving","Track frame indices externally rather than relying on list positions after removals","Check each frame with is_empty() and spectrum in a validation pass before writing"],"exampleFix":"// before\nframes.save_video(\"out.mp4\", 30);\n// after\nCImgList<unsigned char> clean;\ncimglist_for(frames, l) {\n  if (!frames[l].is_empty())\n    clean.insert(frames[l].get_channels(0, frames[l].spectrum() >= 3 ? 2 : frames[l].spectrum() - 1));\n}\nclean.save_video(\"out.mp4\", 30);","handlingStrategy":"validation","validationCode":"bool ok = !frame.is_empty() && frame.spectrum() <= 3; // check each frame before save_video\ncimglist_for(frames, l) if (frames[l].is_empty() || frames[l].spectrum() > 3) { /* fix or drop */ }","typeGuard":"bool videoReady(const CImg<T>& im) { return !im.is_empty() && im.spectrum() >= 1 && im.spectrum() <= 3; }","tryCatchPattern":null,"preventionTips":["Validate every frame (non-empty, <=3 channels) before save_video","Convert spectrum>3 images with get_channels(0,2)","Avoid leaving empty slots in lists destined for video writing"],"tags":["cimg","video","empty-frame","channel-mismatch"],"backgroundTag":"empty-required-field","analyzedSha":"f788b534b48c144edf786c8cddbf0e029e637804","analyzedAt":"2026-09-08T08:36:04.887Z","contentChangedAt":"2026-09-08T08:36:04.887Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}