Yalantis/uCrop · error · CImgArgumentException
draw_line(): Invalid specified texture (%u,%u,%u,%u,%p).
Error message
draw_line(): Invalid specified texture (%u,%u,%u,%u,%p).
What it means
The 2D draw_line() overload with texturing requires the texture image to be 2D (_depth==1) and to have at least as many channels as the target image (_spectrum>=img._spectrum). Passing a volumetric texture (depth>1) or one with too few color channels cannot be sampled correctly, so CImg throws CImgArgumentException.
Source
Thrown at ucrop/src/main/jni/CImg.h:50067
\par Example:
\code
CImg<unsigned char> img(100,100,1,3,0), texture("texture256x256.ppm");
const unsigned char color[] = { 255,128,64 };
img.draw_line(40,40,80,70,texture,0,0,255,255);
\endcode
**/
template<typename tc>
CImg<T>& draw_line(int x0, int y0,
int x1, int y1,
const CImg<tc>& texture,
int tx0, int ty0,
int tx1, int ty1,
const float opacity=1,
const unsigned int pattern=~0U, const bool init_hatch=true) {
if (is_empty() || !opacity || !pattern) return *this;
if (texture._depth>1 || texture._spectrum<_spectrum)
throw CImgArgumentException(_cimg_instance
"draw_line(): Invalid specified texture (%u,%u,%u,%u,%p).",
cimg_instance,
texture._width,texture._height,texture._depth,texture._spectrum,texture._data);
if (is_overlapped(texture)) return draw_line(x0,y0,x1,y1,+texture,tx0,ty0,tx1,ty1,opacity,pattern,init_hatch);
if (std::min(y0,y1)>=height() || std::max(y0,y1)<0 || std::min(x0,x1)>=width() || std::max(x0,x1)<0)
return *this;
int
w1 = width() - 1, h1 = height() - 1,
dx01 = x1 - x0, dy01 = y1 - y0,
dtx01 = tx1 - tx0, dty01 = ty1 - ty0;
const bool is_horizontal = cimg::abs(dx01)>cimg::abs(dy01);
if (is_horizontal) cimg::swap(x0,y0,x1,y1,w1,h1,dx01,dy01);
if (pattern==~0U && y0>y1) {
cimg::swap(x0,x1,y0,y1,tx0,tx1,ty0,ty1);
dx01*=-1; dy01*=-1; dtx01*=-1; dty01*=-1;
}
const floatView on GitHub (pinned to f788b534b4)
Solutions
- Make the texture a 2D image with matching channels: CImg<> texture(tw,th,1,img.spectrum()).
- If the texture is grayscale, convert or expand it: texture.resize(tw,th,1,img.spectrum()) or draw on a grayscale image instead.
- If the texture is a 3D volume, select a slice first: draw_line(...,texture.get_slice(z),...).
- Note: overlapping texture and image is handled internally (copy via +texture), so overlap itself is not the problem — only depth/spectrum is.
Example fix
// before CImg<> tex(64,64,8,1); // depth>1 -> throws on RGB img img.draw_line(0,0,50,50,tex,0,0,63,63); // after CImg<> tex(64,64,1,3); img.draw_line(0,0,50,50,tex,0,0,63,63);
Defensive patterns
Strategy: validation
Validate before calling
if (texture && texture._depth == 1 && texture._spectrum >= img.spectrum()) {
img.draw_line(x0,y0,x1,y1,texture,tx0,ty0,tx1,ty1,opacity);
} Type guard
template<typename t, typename T>
bool is_valid_texture(const CImg<t>& img, const CImg<T>& tex) {
return !tex.is_empty() && tex._depth == 1 && tex._spectrum >= img.spectrum();
} Try / catch
try {
img.draw_line(x0,y0,x1,y1,texture,tx0,ty0,tx1,ty1);
} catch (CImgArgumentException& e) {
std::fprintf(stderr, "bad texture: %s\n", e.what());
} Prevention
- Keep textures 2D: build atlases as wide 2D images, not stacked volumes.
- Match texture spectrum to the target image spectrum before drawing.
- Convert grayscale textures with resize(tw,th,1,img.spectrum()) when drawing on color images.
- Use get_slice(z) when the source data is volumetric.
When it happens
Trigger: Calling img.draw_line(x0,y0,x1,y1,texture,tx0,ty0,tx1,ty1) where texture._depth>1 (e.g. a CImg of size w,h,d,c with d>1) or texture._spectrum<img._spectrum — e.g. a single-channel grayscale texture used to draw on an RGB image, or a 3D volume passed as the texture.
Common situations: Using a scalar (1-channel) texture against an RGBA/RGB image; accidentally passing a 3D image/volume or a list of slices as the texture; a texture built by concatenation that gained a depth dimension; spectrum mismatch after converting the main image to color but keeping the old texture.
Related errors
- draw_line(): Instance and specified Z-buffer (%u,%u,%u,%u,%p
- draw_triangle(): Invalid specified texture (%u,%u,%u,%u,%p).
- operator*(): Invalid multiplication of instance by specified
- [" cimg_appname "_math_parser] CImg<%s>::%s: %s: Type of sec
- [" cimg_appname "_math_parser] CImg<%s>::%s: %s: Type of fir
AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08).
Data as JSON: /api/errors/048454c7bb3bef1e.
Report an issue: GitHub.