Yalantis/uCrop · error · CImgInstanceException

streamline(): Instance is not a 2D or 3D vector field.

Error message

streamline(): Instance is not a 2D or 3D vector field.

What it means

CImg<T>::get_streamline() requires the image instance to be a vector field whose spectrum (channel count) is 2 or 3. The constructor-level overload validates this immediately and throws CImgInstanceException when _spectrum is anything else (e.g. grayscale or 4-channel data).

Solutions

  1. Check the image spectrum before calling: if img.spectrum() is not 2 or 3, reshape the data into a vector field first.
  2. Extract 2 or 3 channels with img.get_channel(0).append(img.get_channel(1),'c') (etc.) to build a proper vector field.
  3. If the source image has an unwanted alpha channel, use img.channels(0,2) to keep only the vector components.
  4. If the field is grayscale, it is not a vector field; construct one explicitly from your components (e.g. CImg<float>(w,h,1,2)).

Example fix

// before
CImg<float> field = gray_image;             // spectrum()==1
CImg<float> line = field.get_streamline(10,10,0);
// after
if (field.spectrum() < 2) {
  CImg<float> vf(field.width(), field.height(), field.depth(), 2);
  vf.get_shared_channel(0) = field;
  vf.get_shared_channel(1) = field;  // fill with real vx/vy data
}
CImg<float> line = vf.get_streamline(10,10,0);
Defensive patterns

Strategy: validation

Validate before calling

if (img.spectrum() != 2 && img.spectrum() != 3)
  throw std::invalid_argument("streamline needs a 2D/3D vector field; spectrum=" + std::to_string(img.spectrum()));

Type guard

bool is_vector_field(const CImg<float>& img) { return img.spectrum() == 2 || img.spectrum() == 3; }

Try / catch

try { line = field.get_streamline(x, y, z); }
catch (CImgInstanceException& e) { /* rebuild vector field from components or skip */ }

Prevention

When it happens

Trigger: Calling get_streamline(x,y,z,...) on an image whose _spectrum != 2 and != 3, e.g. a grayscale image (1 channel) or an RGBA image (4 channels).

Common situations: Loading a scalar image (PNG/JPEG grayscale) and passing it directly to streamline() expecting it to be a velocity/flow field; an image with alpha channel making spectrum=4; forgetting to call channels() to extract the 2-3 flow components.

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


AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08). Data as JSON: /api/errors/c05af9fd1a8400f3. Report an issue: GitHub.

Appendix: source

Thrown at ucrop/src/main/jni/CImg.h:41277

       \param c0 Starting image channel.
       \param c1 Ending image channel.
    **/
    CImg<T> get_channels(const int c0, const int c1) const {
      return get_crop(0,0,0,c0,width() - 1,height() - 1,depth() - 1,c1);
    }

    //! Return specified range of image channels \inplace.
    CImg<T>& channels(const int c0, const int c1) {
      return get_channels(c0,c1).move_to(*this);
    }

    //! Return stream line of a 2D or 3D vector field.
    CImg<floatT> get_streamline(const float x, const float y, const float z,
                                const float L=256, const float dl=0.1f,
                                const unsigned int interpolation_type=2, const bool is_backward_tracking=false,
                                const bool is_oriented_only=false) const {
      if (_spectrum!=2 && _spectrum!=3)
        throw CImgInstanceException(_cimg_instance
                                    "streamline(): Instance is not a 2D or 3D vector field.",
                                    cimg_instance);
      if (_spectrum==2) {
        if (is_oriented_only) {
          typename CImg<T>::_functor4d_streamline2d_oriented func(*this);
          return streamline(func,x,y,z,L,dl,interpolation_type,is_backward_tracking,true,
                            0,0,0,_width - 1.f,_height - 1.f,0.f);
        } else {
          typename CImg<T>::_functor4d_streamline2d_directed func(*this);
          return streamline(func,x,y,z,L,dl,interpolation_type,is_backward_tracking,false,
                            0,0,0,_width - 1.f,_height - 1.f,0.f);
        }
      }
      if (is_oriented_only) {
        typename CImg<T>::_functor4d_streamline3d_oriented func(*this);
        return streamline(func,x,y,z,L,dl,interpolation_type,is_backward_tracking,true,
                          0,0,0,_width - 1.f,_height - 1.f,_depth - 1.f);
      }

View on GitHub (pinned to f788b534b4)