Yalantis/uCrop · error · CImgInstanceException

save_ffmpeg_external(): Invalid instance dimensions for file

Error message

save_ffmpeg_external(): Invalid instance dimensions for file '%s'.

What it means

ffmpeg encodes a sequence of images that must all have identical dimensions; save_ffmpeg_external() verifies every list frame has the same X,Y,Z sizes as frame [0] and throws this instance exception when they differ.

Solutions

  1. Normalize all frames to one size (e.g. frames[l].resize(W,H)) before saving
  2. Ensure every appended frame comes from the same capture geometry
  3. Split differently-sized sequences into separate lists/files
  4. Check _data[l].is_sameXYZ(_data[0]) yourself before calling

Example fix

// before
frames.push_back(cam2_frame); // different resolution
frames.save_ffmpeg_external("out.mp4");
// after
cam2_frame.resize(frames[0].width(), frames[0].height());
frames.push_back(cam2_frame);
frames.save_ffmpeg_external("out.mp4");
Defensive patterns

Strategy: validation

Validate before calling

// C++
bool uniform = true;
cimglist_for(frames, l) if (!frames[l].is_sameXYZ(frames[0])) { uniform = false; break; }
if (!uniform) normalizeSizes(frames);

Type guard

bool uniformDims(const CImgList<T>& l) { cimglist_for(l,i) if (!l[i].is_sameXYZ(l[0])) return false; return true; }

Try / catch

try { frames.save_ffmpeg_external(fname, fps, codec); }
catch (CImgInstanceException& e) { normalizeSizes(frames); frames.save_ffmpeg_external(fname, fps, codec); }

Prevention

When it happens

Trigger: Calling save_ffmpeg_external() on a list whose frames have mismatched width/height/depth — e.g. mixed camera resolutions, appended frames of different sizes, or frames with non-zero depth (volume images).

Common situations: Recording from multiple cameras into one list; frames resized/cropped inconsistently; accidentally including 3D volumes in the list.

Related errors


AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08). Data as JSON: /api/errors/6a427d177e918188. Report an issue: GitHub.

Appendix: source

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

    **/
    const CImgList<T>& save_ffmpeg_external(const char *const filename, const unsigned int fps=25,
                                            const char *const codec=0, const unsigned int bitrate=2048) const {
      if (!filename)
        throw CImgArgumentException(_cimglist_instance
                                    "save_ffmpeg_external(): Specified filename is (null).",
                                    cimglist_instance);
      if (is_empty()) { cimg::fempty(0,filename); return *this; }

      const char
        *const ext = cimg::split_filename(filename),
        *const _codec = codec?codec:
        !cimg::strcasecmp(ext,"flv")?"flv":
        !cimg::strcasecmp(ext,"mp4")?"h264":"mpeg2video";

      CImg<charT> command(1024), filename_tmp(256), filename_tmp2(256);
      CImgList<charT> filenames;
      cimglist_for(*this,l) if (!_data[l].is_sameXYZ(_data[0]))
        throw CImgInstanceException(_cimglist_instance
                                    "save_ffmpeg_external(): Invalid instance dimensions for file '%s'.",
                                    cimglist_instance,
                                    filename);
      do {
        cimg_snprintf(filename_tmp,filename_tmp._width,"%s%c%s",
                      cimg::temporary_path(),cimg_file_separator,cimg::filenamerand());
        cimg_snprintf(filename_tmp2,filename_tmp2._width,"%s_000001.ppm",filename_tmp._data);
      } while (cimg::path_exists(filename_tmp2));
      unsigned int frame = 1;
      cimglist_for(*this,l) {
        CImg<T>& src = _data[l];
        cimg_forZ(src,z) {
          cimg_snprintf(filename_tmp2,filename_tmp2._width,"%s_%.6u.ppm",filename_tmp._data,frame);
          CImg<charT>::string(filename_tmp2).move_to(filenames);
          CImg<T> _src = src._depth>1?src.get_slice(z):src.get_shared();
          if (_src._width%2 || _src._height%2) // Force output to have an even number of columns and rows
            _src.assign(_src.get_resize(_src._width + (_src._width%2),_src._height + (_src._height%2),1,-100,0),false);
          if (_src._spectrum!=3) // Force output to be one slice, in color

View on GitHub (pinned to f788b534b4)