Yalantis/uCrop · error · CImgArgumentException
draw_triangle(): One of the specified color is (null).
Error message
draw_triangle(): One of the specified color is (null).
What it means
This draw_triangle() overload takes three separate per-vertex colors (color0, color1, color2) for gradient shading. All three must be non-null; any null among them makes interpolation impossible, so the library throws CImgArgumentException naming the problem. The check happens before vertex sorting/swapping so no partial work is done.
Solutions
- Ensure all three per-vertex color arrays are allocated and non-null before the call
- Validate each pointer: if (c0 && c1 && c2) img.draw_triangle(...); else supply defaults
- Replace the null color with a copy of a neighboring vertex color as a fallback
- Fix the upstream initialization loop that leaves one color unset
Example fix
// before
const float *cols[3] = {c0, c1, NULL};
img.draw_triangle(x0,y0,x1,y1,x2,y2,cols[0],cols[1],cols[2],opacity);
// after
const float c2[3] = {0,0,255};
const float *cols[3] = {c0, c1, c2}; // all non-null
img.draw_triangle(x0,y0,x1,y1,x2,y2,cols[0],cols[1],cols[2],opacity); Defensive patterns
Strategy: validation
Validate before calling
if (color0 && color1 && color2 && !img.is_empty()) { img.draw_triangle(x0,y0,x1,y1,x2,y2,color0,color1,color2,opacity); } Type guard
bool allColorsValid(const tc* c0, const tc* c1, const tc* c2) { return c0 && c1 && c2; } Try / catch
try { img.draw_triangle(x0,y0,x1,y1,x2,y2,c0,c1,c2,opacity); } catch (const CImgArgumentException& e) { /* substitute default vertex colors and retry */ } Prevention
- Initialize every per-vertex color in loops; avoid partially filled arrays
- Use std::array<const tc*,3> and validate all entries before drawing
- Default missing vertex colors to a neighbor's color instead of null
- In JNI, check each element of a color-pointer array for null
When it happens
Trigger: Calling draw_triangle(x0,y0,x1,y1,x2,y2,color0,color1,color2,opacity) with any of the three color pointers NULL; passing data() of an empty CImg for one vertex color.
Common situations: Arrays of color pointers where one entry was never set; partially initialized color list from config; JNI code filling only some vertex colors.
Related errors
- cimg::fempty(): Specified filename is (null).
- cimg::fopen(): File ' ', specified mode is (null).
- cimg::fopen(): Specified file path is (null).
- cimg::fread(): Invalid reading request of %u
- cimg::fwrite(): Invalid writing request of %u
AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08).
Data as JSON: /api/errors/22a6268f0e73e71d.
Report an issue: GitHub.
Appendix: source
Thrown at ucrop/src/main/jni/CImg.h:50998
\param x2 X-coordinate of the third vertex in the image instance.
\param y2 Y-coordinate of the third vertex in the image instance.
\param color1 Pointer to \c spectrum() consecutive values of type \c T, defining the color of the first vertex.
\param color2 Pointer to \c spectrum() consecutive values of type \c T, defining the color of the second vertex.
\param color3 Pointer to \c spectrum() consecutive values of type \c T, defining the color of the third vertex.
\param opacity Drawing opacity.
**/
template<typename tc>
CImg<T>& draw_triangle(int x0, int y0,
int x1, int y1,
int x2, int y2,
const tc *color0,
const tc *color1,
const tc *color2,
const float opacity=1) {
typedef typename cimg::superset<tc,int>::type stc;
if (is_empty()) return *this;
if (!color0 || !color1 || !color2)
throw CImgArgumentException(_cimg_instance
"draw_triangle(): One of the specified color is (null).",
cimg_instance);
if (y0>y1) cimg::swap(x0,x1,y0,y1,color0,color1);
if (y0>y2) cimg::swap(x0,x2,y0,y2,color0,color2);
if (y1>y2) cimg::swap(x1,x2,y1,y2,color1,color2);
if (y2<0 || y0>=height() || cimg::min(x0,x1,x2)>=width() || cimg::max(x0,x1,x2)<0 || !opacity) return *this;
const int w1 = width() - 1, h1 = height() - 1, cy0 = cimg::cut(y0,0,h1), cy2 = cimg::cut(y2,0,h1);
const longT
dx01 = (longT)x1 - x0, dx02 = (longT)x2 - x0, dx12 = (longT)x2 - x1,
dy01 = std::max((longT)1,(longT)y1 - y0),
dy02 = std::max((longT)1,(longT)y2 - y0),
dy12 = std::max((longT)1,(longT)y2 - y1),
hdy01 = dy01/2, hdy02 = dy02/2, hdy12 = dy12/2;
cimg_init_scanline(opacity);
View on GitHub (pinned to f788b534b4)