Yalantis/uCrop · error · CImgArgumentException

draw_point(): Specified color is (null).

Error message

draw_point(): Specified color is (null).

What it means

CImg's draw_point() requires a pointer to a color array whose length matches the image spectrum. The library throws CImgArgumentException when the color pointer is null, because there is nothing to draw with.

Solutions

  1. Always pass a valid array of at least spectrum() elements, e.g. const unsigned char col[3] = {255,0,0}; for an RGB image.
  2. If the color is optional in your code, assign a default color before the draw call instead of passing null.
  3. Check the pointer for null before calling and return/log an error early.

Example fix

// before
const float *color = palette.empty() ? nullptr : palette[0].data();
img.draw_point(x, y, z, color); // throws when palette empty
// after
const float default_color[3] = {255.0f, 255.0f, 255.0f};
const float *color = palette.empty() ? default_color : palette[0].data();
img.draw_point(x, y, z, color);
Defensive patterns

Strategy: validation

Validate before calling

if (!color) {
  throw std::invalid_argument("draw_point requires a non-null color array");
}
if (img.spectrum() > 0 && sizeof(*color) >= 0) { /* ensure array has spectrum() elements */ }

Try / catch

try {
  img.draw_point(x, y, z, color);
} catch (const cimg_library::CImgArgumentException& e) {
  std::cerr << "draw_point: " << e.what() << std::endl;
}

Prevention

When it happens

Trigger: Calling img.draw_point(x,y,z, NULL) or passing a pointer variable that was never assigned / was set to null after a failed allocation or empty vector.

Common situations: Conditionally-built color arrays left null; passing nullptr as a placeholder assuming opacity-only drawing is allowed; a vector resized to zero and its data() pointer passed through.

Related errors


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

Appendix: source

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

       \param y0 Y-coordinate of the point.
       \param z0 Z-coordinate of the point.
       \param color Pointer to \c spectrum() consecutive values, defining the drawing color.
       \param opacity Drawing opacity.
       \note
       - To set pixel values without clipping needs, you should use the faster CImg::operator()() function.
       \par Example:
       \code
       CImg<unsigned char> img(100,100,1,3,0);
       const unsigned char color[] = { 255,128,64 };
       img.draw_point(50,50,color);
       \endcode
    **/
    template<typename tc>
    CImg<T>& draw_point(const int x0, const int y0, const int z0,
                        const tc *const color, const float opacity=1) {
      if (is_empty()) return *this;
      if (!color)
        throw CImgArgumentException(_cimg_instance
                                    "draw_point(): Specified color is (null).",
                                    cimg_instance);
      if (x0>=0 && y0>=0 && z0>=0 && x0<width() && y0<height() && z0<depth()) {
        const ulongT whd = (ulongT)_width*_height*_depth;
        const float nopacity = cimg::abs(opacity), copacity = 1 - std::max(opacity,0.f);
        T *ptrd = data(x0,y0,z0,0);
        const tc *col = color;
        if (opacity>=1) cimg_forC(*this,c) { *ptrd = (T)*(col++); ptrd+=whd; }
        else cimg_forC(*this,c) { *ptrd = (T)(*(col++)*nopacity + *ptrd*copacity); ptrd+=whd; }
      }
      return *this;
    }

    //! Draw a 2D point \simplification.
    template<typename tc>
    CImg<T>& draw_point(const int x0, const int y0,
                        const tc *const color, const float opacity=1) {
      return draw_point(x0,y0,0,color,opacity);

View on GitHub (pinned to f788b534b4)