Yalantis/uCrop · error · CImgInstanceException
_cimg2cvmat() : Invalid number of channels (should be '1' or
Error message
_cimg2cvmat() : Invalid number of channels (should be '1' or '3+').
What it means
_cimg2cvmat() cannot represent a CImg with exactly 2 channels (spectrum == 2), since cv::Mat has no 2-channel mapping in this bridge; it accepts 1 (gray) or 3+ (color/multi-channel) channel images. The image is otherwise valid, so this is a shape-incompatibility error between CImg and OpenCV.
Source
Thrown at ucrop/src/main/jni/CImg.h:60033
if (src.channels()==1) return CImg<ucharT>(src.ptr(),src.cols,src.rows,1,1);
else if (src.channels()==3) { // BGR
CImg<ucharT> res(src.cols,src.rows,1,src.channels());
const unsigned char *ptrs = src.ptr();
unsigned char *pR = res.data(), *pG = res.data(0,0,0,1), *pB = res.data(0,0,0,2);
cimg_forXY(res,x,y) { *(pB++) = *(ptrs++); *(pG++) = *(ptrs++); *(pR++) = *(ptrs++); }
return res;
}
return CImg<ucharT>(src.ptr(),src.channels(),src.cols,src.rows,1,true).get_permute_axes("yzcx");
}
// Convert a CImg<T> to a cv::Mat.
cv::Mat _cimg2cvmat() const {
if (is_empty())
throw CImgInstanceException(_cimg_instance
"_cimg2cvmat() : Instance image is empty.",
cimg_instance);
if (_spectrum==2)
throw CImgInstanceException(_cimg_instance
"_cimg2cvmat() : Invalid number of channels (should be '1' or '3+').",
cimg_instance);
if (_depth!=1)
throw CImgInstanceException(_cimg_instance
"_cimg2cvmat() : Invalid number of slices (should be '1').",
cimg_instance);
int mat_type = -1;
if (pixel_type()==cimg::type<unsigned char>::string()) mat_type = CV_8UC1;
if (pixel_type()==cimg::type<char>::string()) mat_type = CV_8SC1;
if (pixel_type()==cimg::type<unsigned short>::string()) mat_type = CV_16UC1;
if (pixel_type()==cimg::type<short>::string()) mat_type = CV_16SC1;
if (pixel_type()==cimg::type<int>::string()) mat_type = CV_32SC1;
if (pixel_type()==cimg::type<float>::string()) mat_type = CV_32FC1;
if (pixel_type()==cimg::type<double>::string()) mat_type = CV_64FC1;
if (mat_type<0)
throw CImgInstanceException(_cimg_instance
"_cvmat2cimg() : pixel type '%s' is not supported.",
cimg_instance,pixel_type());View on GitHub (pinned to f788b534b4)
Solutions
- Pad the image to 3 channels (e.g. duplicate or add a zero channel) before conversion.
- Split the two channels and convert each as a single-channel cv::Mat.
- Fix upstream construction so the image has 1, 3, or 4 channels.
Example fix
// before: 2-channel image cv::Mat m = img2ch.get_cvmat(); // throws // after cimg_forXY(img2ch,x,y) img2ch(x,y,0,2) = 0; // pad to 3 channels CImg<unsigned char> img3(img2ch, "xyzc", 3); // or append_channel cv::Mat m = img3.get_cvmat();
Defensive patterns
Strategy: validation
Validate before calling
if (img.spectrum() == 2) throw std::runtime_error("2-channel image not convertible to cv::Mat; pad or split channels"); Try / catch
try { cv::Mat m = img.get_cvmat(); }
catch (CImgInstanceException& e) { /* pad/split channels and retry */ } Prevention
- Keep OpenCV-interop images at 1, 3, or 4 channels
- Audit channel counts when slicing/merging channels
- Document that CImg<->Mat bridge rejects spectrum==2
When it happens
Trigger: Converting a CImg whose _spectrum was set to 2 — e.g. an image constructed with spectrum=2, a two-band multispectral image, or after slicing channel ranges that yield exactly two channels.
Common situations: Working with two-channel data (e.g. L+a, depth+mask pairs, dual-band scientific imagery) and calling get_cvmat() directly; accidentally computing channels=2 in a constructor call.
Related errors
- [cimg_appname_math_parser] CImg<%s>::%s: %s: Type of first a
- [" cimg_appname "_math_parser] CImg<%s>::%s: %s: Type of fir
- [cimg_appname_math_parser] CImg<%s>::%s: %s: Type of first a
- [" cimg_appname "_math_parser] CImg<%s>::%s: %s: Input vecto
- [" cimg_appname "_math_parser] CImg<%s>::%s: %s%s %s%s (of t
AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08).
Data as JSON: /api/errors/55b9c5630c46e580.
Report an issue: GitHub.