Yalantis/uCrop · warning
save_bmp(): Instance is volumetric, only the first slice…
Error message
save_bmp(): Instance is volumetric, only the first slice will be saved in file '%s'.
What it means
save_bmp() can only write a single 2D bitmap; BMP has no volume representation. When _depth>1 the library warns that only the first slice (z=0) will be written and proceeds, silently discarding the rest of the volume.
Solutions
- Save a specific slice: volume.get_slice(z).save_bmp("slice.bmp").
- Use a multi-slice capable format: save_tiff (pages), save_cimg, or save_analyze for volumes.
- Write one BMP per z via a loop if BMP is required for downstream tooling.
- Check depth before saving and fail fast if volume data would be dropped.
Example fix
// before
volume.save_bmp("out.bmp"); // only slice 0 written
// after
for (int z = 0; z < volume.depth(); ++z)
volume.get_slice(z).save_bmp(cimg::format("out_z%04d.bmp", z)); Defensive patterns
Strategy: validation
Validate before calling
if (img.depth() > 1) throw std::logic_error("BMP stores one slice; save slices individually or use TIFF");
img.save_bmp(path); Type guard
bool is2D(const CImg<T>& im) { return im.depth() == 1; } Prevention
- Only export viewable 2D images to BMP.
- Use save_tiff/save_cimg for volumes.
- Explicitly select the slice you intend to export.
When it happens
Trigger: CImg::save_bmp() or save("file.bmp") on a volumetric image (_depth>1), e.g. output of volume processing or a 3D crop.
Common situations: Saving 3D results with a .bmp extension; generic save() dispatch on filename; exporting the wrong variable (volume instead of one slice) from 3D code.
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_bmp(): Instance is multispectral, only the three first…
- save_dlm(): Instance is volumetric, values along Z will be…
- save_jpeg(): Instance is volumetric, only the first slice…
- save_dlm(): Instance is multispectral, values along C will…
- CImgList< >::FFT(): Specified real and imaginary parts…
AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08).
Data as JSON: /api/errors/f3a389dd5c691e4d.
Report an issue: GitHub.
Appendix: source
Thrown at ucrop/src/main/jni/CImg.h:61496
\param filename Filename, as a C-string.
**/
const CImg<T>& save_bmp(const char *const filename) const {
return _save_bmp(0,filename);
}
//! Save image as a BMP file \overloading.
const CImg<T>& save_bmp(std::FILE *const file) const {
return _save_bmp(file,0);
}
const CImg<T>& _save_bmp(std::FILE *const file, const char *const filename) const {
if (!file && !filename)
throw CImgArgumentException(_cimg_instance
"save_bmp(): Specified filename is (null).",
cimg_instance);
if (is_empty()) { cimg::fempty(file,filename); return *this; }
if (_depth>1)
cimg::warn(_cimg_instance
"save_bmp(): Instance is volumetric, only the first slice will be saved in file '%s'.",
cimg_instance,
filename?filename:"(FILE*)");
if (_spectrum>3)
cimg::warn(_cimg_instance
"save_bmp(): Instance is multispectral, only the three first channels will be saved in file '%s'.",
cimg_instance,
filename?filename:"(FILE*)");
std::FILE *const nfile = file?file:cimg::fopen(filename,"wb");
CImg<ucharT> header(54,1,1,1,0);
unsigned char align_buf[4] = {};
const unsigned int
align = (4 - (3*_width)%4)%4,
buf_size = (3*_width + align)*height(),
file_size = 54 + buf_size;
header[0] = 'B'; header[1] = 'M';
header[0x02] = file_size&0xFF;View on GitHub (pinned to f788b534b4)