Yalantis/uCrop · error · CImgArgumentException

distance_dijkstra(): image instance and metric map (%u,%u,%u

Error message

distance_dijkstra(): image instance and metric map (%u,%u,%u,%u) have incompatible dimensions.

What it means

CImg::get_distance_dijkstra() computes a Dijkstra distance map from pixels equal to `value`, using `metric` as the per-pixel traversal cost map. The library requires the metric map to match the source image along X, Y and Z (spectrum/channel count may differ). If is_sameXYZ(metric) fails, it throws CImgArgumentException so the algorithm never runs on mismatched geometry.

Source

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

       \param value Reference value.
       \param metric Field of distance potentials.
       \param is_high_connectivity Tells if the algorithm uses low or high connectivity.
       \param[out] return_path An image containing the nodes of the minimal path.
     **/
    template<typename t, typename to>
    CImg<T>& distance_dijkstra(const T& value, const CImg<t>& metric, const bool is_high_connectivity,
                               CImg<to>& return_path) {
      return get_distance_dijkstra(value,metric,is_high_connectivity,return_path).move_to(*this);
    }

    //! Compute distance map to a specified value, according to a custom metric (use dijkstra algorithm) \newinstance.
    template<typename t, typename to>
    CImg<typename cimg::superset<t,long>::type>
    get_distance_dijkstra(const T& value, const CImg<t>& metric, const bool is_high_connectivity,
                          CImg<to>& return_path) const {
      if (is_empty()) return return_path.assign();
      if (!is_sameXYZ(metric))
        throw CImgArgumentException(_cimg_instance
                                    "distance_dijkstra(): image instance and metric map (%u,%u,%u,%u) "
                                    "have incompatible dimensions.",
                                    cimg_instance,
                                    metric._width,metric._height,metric._depth,metric._spectrum);
      typedef typename cimg::superset<t,long>::type td; // Type used for computing cumulative distances
      CImg<td> result(_width,_height,_depth,_spectrum), Q;
      CImg<boolT> is_queued(_width,_height,_depth,1);
      if (return_path) return_path.assign(_width,_height,_depth,_spectrum);

      cimg_forC(*this,c) {
        const CImg<T> img = get_shared_channel(c);
        const CImg<t> met = metric.get_shared_channel(c%metric._spectrum);
        CImg<td> res = result.get_shared_channel(c);
        CImg<to> path = return_path?return_path.get_shared_channel(c):CImg<to>();
        unsigned int sizeQ = 0;

        // Detect initial seeds.
        is_queued.fill(0);

View on GitHub (pinned to f788b534b4)

Solutions

  1. Before calling, verify metric.width()==img.width() && metric.height()==img.height() && metric.depth()==img.depth() (CImg: img.is_sameXYZ(metric)).
  2. Recompute the metric map from the exact image instance you pass, after all crops/resizes are applied.
  3. If dimensions must differ, crop or resize the metric to match (metric.crop(0,0,0,0,w-1,h-1,d-1)) or pad the image.
  4. Ensure both images share the same 2D/3D interpretation (a 2D image has depth 1).

Example fix

// before
CImg<> metric = img.get_resize(64,64); // metric smaller than img
CImg<> dist = img.get_distance_dijkstra(0, metric);
// after
CImg<> metric(img.width(), img.height(), img.depth(), 1, 1); // same XYZ dims
CImg<> dist = img.get_distance_dijkstra(0, metric);
Defensive patterns

Strategy: validation

Validate before calling

if (!img.is_sameXYZ(metric)) { /* resize metric or abort */ }

Type guard

bool metricMatches(const CImg<T>& img, const CImg<t>& metric) {
  return img.is_sameXYZ(metric);
}

Try / catch

try {
  dist = img.get_distance_dijkstra(value, metric, connectivity, path);
} catch (const CImgArgumentException& e) {
  // log dims, recompute metric at img's geometry
}

Prevention

When it happens

Trigger: Calling get_distance_dijkstra(value, metric, ...) where metric._width/_height/_depth differ from the image's width/height/depth — e.g. passing a metric computed from a cropped, scaled, or padded image, or a metric with different depth (2D vs 3D).

Common situations: Resizing the image after computing the metric map; using a metric derived from a different frame in a video pipeline; mixing 2D and 3D volumes; passing a channel-expanded (spectrum>1) metric while spatial dims were accidentally altered by a crop (e.g. in an image-cropping native module like ucrop).

Related errors


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