Yalantis/uCrop · error · CImgArgumentException
draw_quiver(): Invalid sampling value %g (should be >0)
Error message
draw_quiver(): Invalid sampling value %g (should be >0)
What it means
draw_quiver() validates that its sampling parameter (the grid spacing in pixels between drawn arrows) is strictly positive, throwing CImgArgumentException with the offending value otherwise. Sampling controls downsampling of the flow field; zero or negative spacing is mathematically meaningless for the stride loop.
Solutions
- Clamp before calling: if (sampling<1) sampling=1.
- Ensure derived sampling uses at least std::max(1u, width/step).
- Validate the user/config-facing density parameter and reject or clamp non-positive values at the input boundary.
- If a very dense quiver plot is intended, use sampling=1, not 0.
Example fix
// before unsigned sampling = img.width()/density; // density>width => 0 img.draw_quiver(flow,color,1.f,sampling); // after unsigned sampling = std::max(1u, img.width()/density); img.draw_quiver(flow,color,1.f,sampling);
Defensive patterns
Strategy: validation
Validate before calling
unsigned sampling = std::max(1u, computedSampling); img.draw_quiver(flow,color,1.f,sampling);
Try / catch
try { img.draw_quiver(flow,color,1.f,sampling); }
catch (CImgArgumentException& e) { log_error("draw_quiver sampling=%u rejected", sampling); } Prevention
- Clamp computed sampling with std::max(1u, value) at derivation time.
- For tiny images, guard width/step computations against truncation to 0.
- Validate user-facing density settings to reject <=0 up front.
- Remember sampling is a pixel stride (>=1), not a density.
When it happens
Trigger: Calling img.draw_quiver(flow,color,opacity,0) or with a negative sampling value; computing sampling dynamically (e.g. width/step) where step>width yields 0; passing float 0 through a default-argument chain.
Common situations: Auto-deriving sampling from image size for tiny images (e.g. sampling = w/64 == 0 for small thumbnails); user-configurable density setting allowed to be 0 or negative; unit mix-ups where sampling was given as a density instead of spacing.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- "[" cimg_appname "_math_parser] CImg<
- "[" cimg_appname "_math_parser] CImg<
- "[" cimg_appname "_math_parser] CImg<
- CImg< >::streamline(): Invalid specified integration length…
- deriche(): Invalid specified axis '%c'.
AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08).
Data as JSON: /api/errors/154b43fc0193aa69.
Report an issue: GitHub.
Appendix: source
Thrown at ucrop/src/main/jni/CImg.h:53108
\param sampling Length (in pixels) between each arrow.
\param factor Length factor of each arrow (if <0, computed as a percentage of the maximum length).
\param is_arrow Tells if arrows must be drawn, instead of oriented segments.
\param pattern Used pattern to draw lines.
\note Clipping is supported.
**/
template<typename t1, typename t2>
CImg<T>& draw_quiver(const CImg<t1>& flow,
const CImg<t2>& color, const float opacity=1,
const unsigned int sampling=25, const float factor=-20,
const bool is_arrow=true, const unsigned int pattern=~0U) {
if (is_empty()) return *this;
if (!flow || flow._spectrum!=2)
throw CImgArgumentException(_cimg_instance
"draw_quiver(): Invalid dimensions of specified flow (%u,%u,%u,%u,%p).",
cimg_instance,
flow._width,flow._height,flow._depth,flow._spectrum,flow._data);
if (sampling<=0)
throw CImgArgumentException(_cimg_instance
"draw_quiver(): Invalid sampling value %g "
"(should be >0)",
cimg_instance,
sampling);
const bool colorfield = (color._width==flow._width && color._height==flow._height &&
color._depth==1 && color._spectrum==_spectrum);
if (is_overlapped(flow)) return draw_quiver(+flow,color,opacity,sampling,factor,is_arrow,pattern);
float vmax,fact;
if (factor<=0) {
float m, M = (float)flow.get_norm(2).max_min(m);
vmax = (float)std::max(cimg::abs(m),cimg::abs(M));
if (!vmax) vmax = 1;
fact = -factor;
} else { fact = factor; vmax = 1; }
for (unsigned int y = sampling/2; y<_height; y+=sampling)
for (unsigned int x = sampling/2; x<_width; x+=sampling) {
const unsigned int X = x*flow._width/_width, Y = y*flow._height/_height;View on GitHub (pinned to f788b534b4)