Yalantis/uCrop · error · CImgArgumentException
draw_polygon(): Specified color is (null).
Error message
draw_polygon(): Specified color is (null).
What it means
CImg's filled draw_polygon(const CImg<tp>& points, const tc* color, opacity) received a null color pointer. CImg throws CImgArgumentException because polygon filling needs per-channel color values that a null pointer cannot supply.
Source
Thrown at ucrop/src/main/jni/CImg.h:52298
draw_line(nx1,ny1,nx0,ny1,color,opacity,pattern,false);
return draw_line(nx0,ny0,nx1,ny0,color,opacity,pattern,true).
draw_line(nx1,ny0 + 1,nx1,ny1 - 1,color,opacity,pattern,false).
draw_line(nx1,ny1,nx0,ny1,color,opacity,pattern,false).
draw_line(nx0,ny1 - 1,nx0,ny0 + 1,color,opacity,pattern,false);
}
//! Draw a filled 2D polygon.
/**
\param points Set of polygon vertices.
\param color Pointer to \c spectrum() consecutive values of type \c T, defining the drawing color.
\param opacity Drawing opacity.
**/
template<typename tp, typename tc>
CImg<T>& draw_polygon(const CImg<tp>& points,
const tc *const color, const float opacity=1) {
if (is_empty() || !points) return *this;
if (!color)
throw CImgArgumentException(_cimg_instance
"draw_polygon(): Specified color is (null).",
cimg_instance);
if (points.height()!=2)
throw CImgArgumentException(_cimg_instance
"draw_polygon(): Invalid specified point set (%u,%u,%u,%u).",
cimg_instance,
points._width,points._height,points._depth,points._spectrum);
CImg<intT> ipoints;
if (cimg::type<tp>::is_float()) ipoints = points.get_round();
else ipoints.assign(points,cimg::type<tp>::string()==cimg::type<int>::string());
if (ipoints._width==1) return draw_point(ipoints(0,0),ipoints(0,1),color,opacity);
if (ipoints._width==2) return draw_line(ipoints(0,0),ipoints(0,1),ipoints(1,0),ipoints(1,1),color,opacity);
if (ipoints._width==3) return draw_triangle(ipoints(0,0),ipoints(0,1),ipoints(1,0),ipoints(1,1),
ipoints(2,0),ipoints(2,1),color,opacity);
cimg_init_scanline(opacity);
int
xmin = 0, ymin = 0,View on GitHub (pinned to f788b534b4)
Solutions
- Allocate and populate the color buffer with img.spectrum() values before the call.
- Pass a stack array like const unsigned char color[3]={255,255,255}.
- Guard: if (color) draw_polygon(...); else use a default color.
- Verify the vector holding the color is non-empty before taking .data().
Example fix
// before
std::vector<unsigned char> col; // empty
img.draw_polygon(points, col.data(), 1.0f); // throws: null color
// after
std::vector<unsigned char> col = {255, 0, 0};
img.draw_polygon(points, col.data(), 1.0f); Defensive patterns
Strategy: type-guard
Validate before calling
if (!color) {
static const unsigned char white[3] = {255, 255, 255};
color = white;
}
img.draw_polygon(points, color, opacity); Type guard
template <typename tc>
bool color_is_valid(const tc* color) { return color != nullptr; } Try / catch
try {
img.draw_polygon(points, color, opacity);
} catch (CImgArgumentException& e) {
std::cerr << "Null polygon color: " << e.what() << std::endl;
} Prevention
- Keep color buffers alive for the duration of the draw call
- Guard pointer-based color APIs with null checks
- Prefer literal arrays for fixed colors
When it happens
Trigger: Calling img.draw_polygon(points, color, opacity) with color==nullptr (uninitialized buffer, empty vector's data(), or failed allocation). Note the call is silently skipped if points is empty, but a null color on non-empty points throws.
Common situations: Color array freed or never allocated; passing .data() of an empty std::vector; API migration from a value-based color API to pointer-based one.
Related errors
- draw_rectangle(): Specified color is (null).
- draw_polygon(): Invalid specified point set (%u,%u,%u,%u).
- draw_ellipse(): Specified color is (null).
- draw_circle(): Specified color is (null).
- draw_graph(): Specified color is (null).
AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08).
Data as JSON: /api/errors/6ecbf5cd4ba8b108.
Report an issue: GitHub.