Yalantis/uCrop · error · CImgInstanceException
RGBtoCMY(): Instance is not a RGB image.
Error message
RGBtoCMY(): Instance is not a RGB image.
What it means
RGBtoCMY() converts RGB channels to CMY in place and requires exactly 3 channels; CImg throws CImgInstanceException when _spectrum!=3. The three channel planes are accessed directly, so any other channel count is invalid input for this operation.
Source
Thrown at ucrop/src/main/jni/CImg.h:37402
R = (Y + 1.140f*V)*255,
G = (Y - 0.395f*U - 0.581f*V)*255,
B = (Y + 2.032f*U)*255;
p1[N] = (T)cimg::cut(R,0,255),
p2[N] = (T)cimg::cut(G,0,255),
p3[N] = (T)cimg::cut(B,0,255);
}
return *this;
}
//! Convert pixel values from YUV to RGB color spaces \newinstance.
CImg<Tuchar> get_YUVtoRGB() const {
return CImg< Tuchar>(*this,false).YUVtoRGB();
}
//! Convert pixel values from RGB to CMY color spaces.
CImg<T>& RGBtoCMY() {
if (_spectrum!=3)
throw CImgInstanceException(_cimg_instance
"RGBtoCMY(): Instance is not a RGB image.",
cimg_instance);
T *p1 = data(0,0,0,0), *p2 = data(0,0,0,1), *p3 = data(0,0,0,2);
const longT whd = (longT)width()*height()*depth();
cimg_pragma_openmp(parallel for cimg_openmp_if_size(whd,2048))
for (longT N = 0; N<whd; ++N) {
const Tfloat
R = (Tfloat)p1[N],
G = (Tfloat)p2[N],
B = (Tfloat)p3[N],
C = 255 - R,
M = 255 - G,
Y = 255 - B;
p1[N] = (T)cimg::cut(C,0,255),
p2[N] = (T)cimg::cut(M,0,255),
p3[N] = (T)cimg::cut(Y,0,255);
}View on GitHub (pinned to f788b534b4)
Solutions
- Guard with if (img.spectrum()==3).
- Convert grayscale to RGB: img.get_append(img,img,'c').
- Convert CMYK input via CMYKtoCMY() first, then CMYtoRGB(), before RGBtoCMY() if needed.
- Catch CImgInstanceException to handle non-RGB inputs gracefully.
Example fix
// before
CImg<unsigned char> img("scan.png"); // grayscale
img.RGBtoCMY();
// after
CImg<unsigned char> img("scan.png");
if (img.spectrum()==1) img.append(img,img,img,'c');
img.RGBtoCMY(); Defensive patterns
Strategy: validation
Validate before calling
if (img.spectrum()==1) img.append(img,img,img,'c');
if (img.spectrum()!=3) throw std::runtime_error("RGBtoCMY requires 3-channel RGB image"); Type guard
bool isRGB(const cimg_library::CImg<T>& img) { return img.spectrum()==3; } Try / catch
try {
img.RGBtoCMY();
} catch (const cimg_library::CImgInstanceException& e) {
std::cerr << "Non-RGB input: spectrum=" << img.spectrum() << std::endl;
} Prevention
- Convert to RGB explicitly (via append/channels) right after loading
- Handle CMYK sources with CMYKtoCMY().CMYtoRGB() before re-converting
- Check spectrum() on all user-supplied files
When it happens
Trigger: Calling img.RGBtoCMY() on a 1-channel grayscale image, a 4-channel RGBA/CMYK image, or an empty CImg.
Common situations: Print pipelines where scanned images may be grayscale or CMYK; loading JPEGs with alpha or PNGs with alpha; forgetting to normalize input to RGB before conversion.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- RGBtoYCbCr(): Instance is not a RGB image.
- YCbCrtoRGB(): Instance is not a YCbCr image.
- RGBtoYUV(): Instance is not a RGB image.
- YUVtoRGB(): Instance is not a YUV image.
- CMYtoRGB(): Instance is not a CMY image.
AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08).
Data as JSON: /api/errors/e4be9e9bf96ae177.
Report an issue: GitHub.