Yalantis/uCrop · error · CImgArgumentException
draw_rectangle(): Specified color is (null).
Error message
draw_rectangle(): Specified color is (null).
What it means
CImg's draw_rectangle() with a templated color pointer received a null color pointer. CImg throws CImgArgumentException because there are no pixel values to fill the rectangle with; drawing cannot proceed.
Source
Thrown at ucrop/src/main/jni/CImg.h:52244
//! Draw a filled 3D rectangle.
/**
\param x0 X-coordinate of the upper-left rectangle corner.
\param y0 Y-coordinate of the upper-left rectangle corner.
\param z0 Z-coordinate of the upper-left rectangle corner.
\param x1 X-coordinate of the lower-right rectangle corner.
\param y1 Y-coordinate of the lower-right rectangle corner.
\param z1 Z-coordinate of the lower-right rectangle corner.
\param color Pointer to \c spectrum() consecutive values of type \c T, defining the drawing color.
\param opacity Drawing opacity.
**/
template<typename tc>
CImg<T>& draw_rectangle(const int x0, const int y0, const int z0,
const int x1, const int y1, const int z1,
const tc *const color, const float opacity=1) {
if (is_empty()) return *this;
if (!color)
throw CImgArgumentException(_cimg_instance
"draw_rectangle(): Specified color is (null).",
cimg_instance);
cimg_forC(*this,c) draw_rectangle(x0,y0,z0,c,x1,y1,z1,c,(T)color[c],opacity);
return *this;
}
//! Draw a filled 2D rectangle.
/**
\param x0 X-coordinate of the upper-left rectangle corner.
\param y0 Y-coordinate of the upper-left rectangle corner.
\param x1 X-coordinate of the lower-right rectangle corner.
\param y1 Y-coordinate of the lower-right rectangle corner.
\param color Pointer to \c spectrum() consecutive values of type \c T, defining the drawing color.
\param opacity Drawing opacity.
**/
template<typename tc>
CImg<T>& draw_rectangle(const int x0, const int y0,
const int x1, const int y1,View on GitHub (pinned to f788b534b4)
Solutions
- Ensure the color buffer exists and points to at least spectrum() values before the call.
- Use the array overload with a literal, e.g. unsigned char color[] = {255,0,0};
- If color may be missing, early-return or draw with a default color instead of null.
- Check the pointer for null before calling and handle the fallback path.
Example fix
// before
const unsigned char* color = vec.empty() ? nullptr : vec.data();
img.draw_rectangle(0,0,0,99,99,0, color, 1.0f); // throws when vec empty
// after
if (!vec.empty()) {
img.draw_rectangle(0,0,0,99,99,0, vec.data(), 1.0f);
} else {
const unsigned char black[3] = {0,0,0};
img.draw_rectangle(0,0,0,99,99,0, black, 1.0f);
} Defensive patterns
Strategy: type-guard
Validate before calling
if (!color || is_empty_color(color)) {
static const unsigned char fallback[3] = {0, 0, 0};
color = fallback;
}
img.draw_rectangle(x0,y0,z0,x1,y1,z1, color, opacity); Type guard
template <typename tc>
bool color_is_valid(const tc* color, unsigned int spectrum) { return color != nullptr; } Try / catch
try {
img.draw_rectangle(x0,y0,z0,x1,y1,z1, color, opacity);
} catch (CImgArgumentException& e) {
std::cerr << "Null color: " << e.what() << std::endl;
} Prevention
- Never pass .data() of an empty vector as a color
- Use stack arrays for literal colors
- Check pointers for null before any draw_* call
When it happens
Trigger: Calling img.draw_rectangle(x0,y0,z0,x1,y1,z1,color,opacity) where color==nullptr — typically an uninitialized pointer, a failed allocation, or an empty std::vector's data().
Common situations: Color array declared but never filled/allocated; .data() of an empty vector; refactoring changed a value overload to a pointer overload; conditionally-initialized color buffers.
Related errors
- cimg::fopen(): Specified file path is (null).
- cimg::fopen(): File '%s', specified mode is (null).
- cimg::fread(): Invalid reading request of %u %s%s from file
- cimg::fwrite(): Invalid writing request of %u %s%s from buff
- cimg::fempty(): Specified filename is (null).
AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08).
Data as JSON: /api/errors/9f3f822cacf93837.
Report an issue: GitHub.