Yalantis/uCrop · warning
save_pnk(): Instance is multispectral, only the first…
Error message
save_pnk(): Instance is multispectral, only the first channel will be saved in file '%s'.
What it means
save_pnk() writes a single-channel PNM (portable any-map) file; CImg warns when the instance has more than one spectral channel because only channel 0 is written and channels 1..n are silently discarded. It is emitted via cimg::warn() and does not stop the save.
Solutions
- Convert to a single channel first, e.g. img.get_channels(0,0) or RGB->luminance via img.get_norm().normalize(0,255)
- Call a multi-channel saver: save_ppm() or save_png() for RGB data
- If only channel 0 is wanted explicitly, pass get_channel(0) so intent is clear
Example fix
// before
rgbImage.save_pnk("out.pgm"); // only R channel written
// after
rgbImage.get_norm().normalize(0,255).save_pnk("out.pgm"); Defensive patterns
Strategy: validation
Validate before calling
if (img.spectrum() > 1) img = img.get_norm().normalize(0,255); // or img.get_channels(0,0)
img.save_pnk("out.pgm"); Type guard
bool is_single_channel(const cimg_library::CImg<T>& img) { return img.spectrum() == 1; } Try / catch
try { img.save_pnk("out.pgm"); } catch (CImgException& e) { /* handle */ } Prevention
- Check spectrum() before single-channel savers
- Convert RGB to luminance explicitly when grayscale output is intended
- Use save_ppm/save_png for color images
When it happens
Trigger: Calling save_pnk() (or save_pnm on a pnk-formatted path) on an image with _spectrum>1, e.g. an RGB or RGBA image loaded from PNG/JPEG, or a 3D volumetric image with multiple channels.
Common situations: Converting color images to grayscale-map files without converting channels first; pipelines that assume grayscale input but receive RGB frames (webcam or video frames); accidentally calling save_pnk instead of a color-capable saver like save_ppm or save_png.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- save_pfm(): image instance is multispectral, only the three…
- load_dcraw_external(): Failed to load file
- load_pdf_external(): Failed to load file
- load_pnm(): COLORMAX field is undefined in file
- load_pnm(): PNM header not found in file
AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08).
Data as JSON: /api/errors/574774b4072bb443.
Report an issue: GitHub.
Appendix: source
Thrown at ucrop/src/main/jni/CImg.h:62415
\param filename Filename, as a C-string.
**/
const CImg<T>& save_pnk(const char *const filename) const {
return _save_pnk(0,filename);
}
//! Save image as a PNK file \overloading.
const CImg<T>& save_pnk(std::FILE *const file) const {
return _save_pnk(file,0);
}
const CImg<T>& _save_pnk(std::FILE *const file, const char *const filename) const {
if (!file && !filename)
throw CImgArgumentException(_cimg_instance
"save_pnk(): Specified filename is (null).",
cimg_instance);
if (is_empty()) { cimg::fempty(file,filename); return *this; }
if (_spectrum>1)
cimg::warn(_cimg_instance
"save_pnk(): Instance is multispectral, only the first channel will be saved in file '%s'.",
cimg_instance,
filename?filename:"(FILE*)");
const ulongT buf_size = std::min((ulongT)1024*1024,(ulongT)_width*_height*_depth);
std::FILE *const nfile = file?file:cimg::fopen(filename,"wb");
const T *ptr = data(0,0,0,0);
if (!cimg::type<T>::is_float() && sizeof(T)==1 && _depth<2) // Can be saved as regular PNM file
_save_pnm(file,filename,0);
else if (!cimg::type<T>::is_float() && sizeof(T)==1) { // Save as extended P5 file: Binary byte-valued 3D
std::fprintf(nfile,"P5\n%u %u %u\n255\n",_width,_height,_depth);
CImg<ucharT> buf((unsigned int)buf_size);
for (longT to_write = (longT)width()*height()*depth(); to_write>0; ) {
const ulongT N = std::min((ulongT)to_write,buf_size);
unsigned char *ptrd = buf._data;
for (ulongT i = N; i>0; --i) *(ptrd++) = (unsigned char)*(ptr++);
cimg::fwrite(buf._data,N,nfile);View on GitHub (pinned to f788b534b4)