Yalantis/uCrop · error · CImgArgumentException
get_gradient(): Invalid specified axes
Error message
get_gradient(): Invalid specified axes '%s'.
What it means
CImg's get_gradient() computes image gradients along the axes given as a string. Each character of the axes string must be 'x', 'y' or 'z'; the library validates the string character-by-character and throws this CImgArgumentException if any character is not one of the three allowed axis letters.
Solutions
- Inspect the axes string at the throw site and remove/replace any character that is not 'x','y' or 'z' (case-insensitive)
- Use only concatenated axis letters with no separators, e.g. 'xy' or 'xyz'
- Lowercase/normalize user-supplied axis names before passing them, or build the string programmatically from a whitelist
- If you need derivatives along other dimensions (spectrum/time), compute them with get_derivative() along that dimension instead
Example fix
// before
img.get_gradient("x,t");
// after
img.get_gradient("x"); // or "xy" / "xyz" - only x,y,z are valid Defensive patterns
Strategy: validation
Validate before calling
static bool isValidAxes(const std::string& axes) {
for (char c : axes) {
char l = (char)std::tolower((unsigned char)c);
if (l != 'x' && l != 'y' && l != 'z') return false;
}
return !axes.empty();
}
// call only if isValidAxes(axes)
CImg<float> grad = img.get_gradient(axes.c_str()); Type guard
bool isCimgAxis(char c) {
char l = (char)std::tolower((unsigned char)c);
return l == 'x' || l == 'y' || l == 'z';
} Try / catch
try {
CImg<float> grad = img.get_gradient(axes);
} catch (CImgArgumentException& e) {
std::fprintf(stderr, "bad axes string '%s': %s\n", axes.c_str(), e.what());
// fall back to default full gradient
CImg<float> grad = img.get_gradient("xy");
} Prevention
- Build axes strings from a whitelist enum instead of free text
- Strip whitespace/separators ('x,y' is invalid) before passing
- Normalize case with cimg::lowercase or std::tolower
- Never pass 't' or 'c' - get_gradient only supports x,y,z
When it happens
Trigger: Calling get_gradient(axes) (or gradient() which delegates to it) with an axes string containing any character other than 'x','y','z' (or 'X','Y','Z', which are lowercased) - e.g. 'w', 't', 'xy z', or a string with trailing whitespace/punctuation.
Common situations: Typo in the axes string ('X,Y' with commas), porting code that used axis indices or different axis names, accidentally passing a user/config string with spaces, or handling 4D images where a developer passes 't' for the time axis which get_gradient does not support.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- get_hessian(): Invalid specified axes
- "[" cimg_appname "_math_parser] CImg<
- "[" cimg_appname "_math_parser] CImg<
- "[" cimg_appname "_math_parser] CImg<
- "[" cimg_appname "_math_parser] CImg<
AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08).
Data as JSON: /api/errors/7f6a96489fa513bf.
Report an issue: GitHub.
Appendix: source
Thrown at ucrop/src/main/jni/CImg.h:45536
- 4 = Using Deriche recursive filter.
- 5 = Using Van Vliet recursive filter.
**/
CImgList<Tfloat> get_gradient(const char *const axes=0, const int scheme=0) const {
CImgList<Tfloat> res;
char __axes[4] = {};
const char *_axes = axes?axes:__axes;
if (!axes) {
unsigned int k = 0;
if (_width>1) __axes[k++] = 'x';
if (_height>1) __axes[k++] = 'y';
if (_depth>1) __axes[k++] = 'z';
}
CImg<Tfloat> grad;
while (*_axes) {
const char axis = cimg::lowercase(*(_axes++));
if (axis!='x' && axis!='y' && axis!='z')
throw CImgArgumentException(_cimg_instance
"get_gradient(): Invalid specified axes '%s'.",
cimg_instance,
axes);
const longT off = axis=='x'?1:axis=='y'?_width:_width*_height;
if ((axis=='x' && _width==1) || (axis=='y' && _height==1) || (axis=='z' && _depth==1)) {
grad.assign(_width,_height,_depth,_spectrum,0).move_to(res);
continue;
}
const int _scheme = axis=='z' && (scheme==2 || scheme==3)?0:scheme;
switch (_scheme) {
case -1 : { // Backward finite differences
grad.assign(_width,_height,_depth,_spectrum);
cimg_pragma_openmp(parallel for cimg_openmp_collapse(3) cimg_openmp_if_size(size(),16384))
cimg_forXYZC(*this,x,y,z,c) {
const ulongT pos = offset(x,y,z,c);
if ((axis=='x' && !x) || (axis=='y' && !y) || (axis=='z' && !z))
grad[pos] = 0;View on GitHub (pinned to f788b534b4)