Yalantis/uCrop · error · CImgInstanceException
get_isoline3d(): Instance is not a scalar image.
Error message
get_isoline3d(): Instance is not a scalar image.
What it means
CImg::get_isoline3d() extracts 3D isolines (contours at a given isovalue) from a scalar 2D image. The instance must have a single channel; CImg throws CImgInstanceException when _spectrum>1, i.e. the image is vector-valued (e.g. RGB or RGBA).
Solutions
- Convert to scalar first: img.get_channel(0) or img.get_norm() / RGBtoYCbCr channel depending on intent.
- Verify img._spectrum==1 before calling get_isoline3d.
- If all channels are equal, take channel 0; if not, decide a reduction (luminance, mean, norm) and apply it.
- Cache the scalar conversion once instead of converting per isoline call.
- Wrap in try/catch on CImgInstanceException.
Example fix
// before
CImg<unsigned char> img = load("map.png"); // RGBA, _spectrum==4
img.get_isoline3d(prims, 128.0f); // throws
// after
CImg<float> gray = img.get_channel(0).get_resize(...,-100,-100,1,1); // scalar
gray.get_isoline3d(prims, 128.0f); // OK Defensive patterns
Strategy: validation
Validate before calling
if (img._spectrum>1) img = img.get_channel(0); // or luminance/norm reduction img.get_isoline3d(prims, isovalue);
Type guard
template<typename T>
const CImg<T>& require_scalar(const CImg<T>& img) {
if (img._spectrum>1) throw std::invalid_argument("expected scalar image");
return img;
} Try / catch
try {
img.get_isoline3d(prims, isovalue);
} catch (CImgInstanceException& e) {
std::fprintf(stderr, "isoline3d needs a scalar 2D image: %s\n", e.what());
} Prevention
- Convert RGB(A) inputs to grayscale/one channel at load time
- Decide an explicit channel reduction (channel 0, luminance, norm)
- Assert _spectrum==1 before contouring
- Keep contouring input images separate from display textures
When it happens
Trigger: Calling get_isoline3d directly on a color image loaded from file (spectrum 3 or 4), or on any multi-channel image, instead of a scalar (spectrum==1) image.
Common situations: Forgetting to convert an RGB height/intensity image to grayscale before contouring; applying isoline extraction to a feature stack image with several bands.
Understand the failure class
Background: Tensor shape mismatch errors ("must have shape", "expected shape ... got ..."): when tensor dimensions disagree with what an op or layer was told to expect — this error's family across 6 libraries.
Related errors
- assign(): Invalid assignment request of shared instance from
- assign(): Shared image instance has overlapping memory.
- at(): Empty instance.
- atN(): Empty instance.
- atNX(): Empty instance.
AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08).
Data as JSON: /api/errors/f6b7edfb5b0d5774.
Report an issue: GitHub.
Appendix: source
Thrown at ucrop/src/main/jni/CImg.h:48346
(template type \e tf should be at least \e unsigned \e int).
\param isovalue The returned list of the 3D object colors.
\param size_x The number of subdivisions along the X-axis.
\param size_y The number of subdisivions along the Y-axis.
\return The N vertices (xi,yi,zi) of the 3D object as a Nx3 CImg<float> image (0<=i<=N - 1).
\par Example
\code
const CImg<float> img("reference.jpg");
CImgList<unsigned int> faces3d;
const CImg<float> points3d = img.get_isoline3d(faces3d,100);
CImg<unsigned char>().display_object3d("Isoline3d",points3d,faces3d,colors3d);
\endcode
\image html ref_isoline3d.jpg
**/
template<typename tf>
CImg<floatT> get_isoline3d(CImgList<tf>& primitives, const float isovalue,
const int size_x=-100, const int size_y=-100) const {
if (_spectrum>1)
throw CImgInstanceException(_cimg_instance
"get_isoline3d(): Instance is not a scalar image.",
cimg_instance);
if (_depth>1)
throw CImgInstanceException(_cimg_instance
"get_isoline3d(): Instance is not a 2D image.",
cimg_instance);
primitives.assign();
if (is_empty()) return *this;
CImg<floatT> vertices;
if ((size_x==-100 && size_y==-100) || (size_x==width() && size_y==height())) {
const _functor2d_int func(*this);
vertices = isoline3d(primitives,func,isovalue,0,0,width() - 1.f,height() - 1.f,width(),height());
} else {
const _functor2d_float func(*this);
vertices = isoline3d(primitives,func,isovalue,0,0,width() - 1.f,height() - 1.f,size_x,size_y);
}
return vertices;
}View on GitHub (pinned to f788b534b4)