Yalantis/uCrop · error · CImgArgumentException
save_jxl(): JPEG XL only supports at most 4 channels.
Error message
save_jxl(): JPEG XL only supports at most 4 channels.
What it means
JPEG XL encoding in CImg supports at most 4 channels (gray, RGB, RGB+alpha, RGBA). save_jxl() throws CImgArgumentException when the image's _spectrum exceeds 4, before any encoder setup, because libjxl's basic info cannot represent that channel count.
Solutions
- Reduce channels before saving: img.channels(0,3) to keep the first 4, or split into multiple images.
- Pack channels differently (e.g. save each band as a separate grayscale JXL file).
- Choose a format that supports more channels (e.g. TIFF) instead of JXL.
Example fix
// before
img.save_jxl("spectral.jxl"); // img.spectrum() == 8
// after
CImg<T> vis = img.get_channels(0, 0, 0, 0, 0, 3); // keep RGB-like subset
vis.save_jxl("spectral.jxl"); Defensive patterns
Strategy: validation
Validate before calling
if (img.spectrum() > 4) {
img.channels(0, 3); // keep first 4 channels before jxl save
}
img.save_jxl("out.jxl"); Prevention
- Reject or reduce >4-channel images at ingestion.
- Document that JXL output supports at most 4 channels.
- Route multispectral data to formats like TIFF.
When it happens
Trigger: Calling save_jxl() on an image whose _spectrum > 4, e.g. multispectral/hyperspectral data, CMYK+extra channels, or images produced by concatenating many channel planes.
Common situations: Scientific imaging and remote-sensing pipelines where images carry 5+ spectral bands, then get saved to JXL for compression without channel reduction.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- save_jxl(): bytes_per_pixel must be in [0, 2] and less than…
- [" cimg_appname "_math_parser] CImg<
- [cimg_appname_math_parser] CImg<
- cimg::dialog(): No buttons have been defined.
- _cimg2cvmat() : Invalid number of channels (should be '1'…
AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08).
Data as JSON: /api/errors/00c6f90fda63131d.
Report an issue: GitHub.
Appendix: source
Thrown at ucrop/src/main/jni/CImg.h:61770
/**
\param filename Filename, as a C-string.
\param distance Sets the level for lossy compression: lower = higher quality.
Range: 0 .. 25. 0.0 = mathematically lossless
\param bytes_per_pixel Force the number of bytes per pixels for the saving, when possible.
**/
const CImg<T>& save_jxl(const char *const filename, const float distance=1.0f,
const unsigned int bytes_per_pixel=0) const {
return _save_jxl(filename,distance,bytes_per_pixel);
}
const CImg<T>& _save_jxl(const char *const filename, const float distance=1.0f,
const unsigned int bytes_per_pixel=0) const {
if (!filename)
throw CImgArgumentException(_cimg_instance
"save_jxl(): Specified filename is (null).",
cimg_instance);
if (_spectrum > 4)
throw CImgArgumentException(_cimg_instance
"save_jxl(): JPEG XL only supports at most 4 channels.",
cimg_instance);
double stmin, stmax = (double)max_min(stmin);
if (stmin<0 || (bytes_per_pixel==1 && stmax>=256) || stmax>=65536)
cimg::warn(_cimg_instance
"save_jxl(): Instance has pixel values in [%g,%g], probable type overflow in file '%s'.",
cimg_instance,
stmin,stmax,filename);
if (bytes_per_pixel>2 || sizeof(T)<bytes_per_pixel)
throw CImgArgumentException(_cimg_instance
"save_jxl(): bytes_per_pixel must be in [0, 2] and less than or equal to sizeof(T)",
cimg_instance);
if (_depth>1)
cimg::warn(_cimg_instance
"save_jxl(): Instance is volumetric, only the first slice will be saved in file '%s'.",
cimg_instance,
filename);
#ifndef cimg_use_jxlView on GitHub (pinned to f788b534b4)