44 internal Handle _handle;
52 var handle =
new Handle();
62 Backend.Types.peak_icv_point[] cPoints = points
63 .Select(coordinate =>
new Backend.Types.peak_icv_point { x = coordinate.X, y = coordinate.Y })
65 var handle =
new Handle(cPoints);
75 var cRectangle =
new Backend.Types.peak_common_rectangle
76 { x = rectangle.
X, y = rectangle.
Y, width = rectangle.
Width, height = rectangle.Height };
77 var handle =
new Handle(cRectangle);
81 internal Region(Handle handle)
103 nuint numConnectedComponents = 0;
104 DllHelper.ExecuteAndMapReturnCodes(() =>
105 CInterface.peak_icv_Region_GetConnectedComponents_GetCount(_handle, out numConnectedComponents));
107 if (numConnectedComponents == 0)
112 var cConnectedComponentsHandles =
new IntPtr[numConnectedComponents];
115 DllHelper.ExecuteAndMapReturnCodes(() =>
116 CInterface.peak_icv_Region_Array_Create(cConnectedComponentsHandles, numConnectedComponents));
118 DllHelper.ExecuteAndMapReturnCodes(() =>
119 CInterface.peak_icv_Region_GetConnectedComponents(_handle, cConnectedComponentsHandles,
120 numConnectedComponents));
124 cConnectedComponentsHandles.Select(handle =>
new Region(
new Handle(handle))).ToList());
128 CInterface.peak_icv_Region_Array_Destroy(cConnectedComponentsHandles, numConnectedComponents);
143 DllHelper.ExecuteAndMapReturnCodes(() =>
144 CInterface.peak_icv_Region_GetPoints_GetCount(_handle, out numPoints));
148 return new List<Point>();
151 var cPoints =
new Backend.Types.peak_icv_point[numPoints];
153 DllHelper.ExecuteAndMapReturnCodes(() =>
154 CInterface.peak_icv_Region_GetPoints(_handle, cPoints, numPoints));
155 return cPoints.Select(cCoordinate =>
new Point(cCoordinate.x, cCoordinate.y)).ToList();
171 DllHelper.ExecuteAndMapReturnCodes(() => CInterface.peak_icv_Region_GetArea(_handle, out area));
190 var cCenterOfGravity =
new Backend.Types.peak_icv_point_f();
191 DllHelper.ExecuteAndMapReturnCodes(() =>
192 CInterface.peak_icv_Region_GetCenterOfGravity(_handle, out cCenterOfGravity));
193 return new PointF(cCenterOfGravity.x, cCenterOfGravity.y);
201 public static IEqualityComparer<Region>
Comparer {
get; } =
new RegionEqualityComparer();
210 GC.SuppressFinalize(
this);
215 var cOptions =
new Backend.Types.peak_icv_drawing_options
218 opacity = drawingOptions.Opacity.Value
220 DllHelper.ExecuteAndMapReturnCodes(() =>
221 CInterface.peak_icv_Region_Draw(image._handle, _handle, cOptions));
224 SafeHandle IHasSafeHandle.Handle => _handle;
235 var outputRegion =
new Region();
236 DllHelper.ExecuteAndMapReturnCodes(() =>
237 CInterface.peak_icv_Region_Difference(_handle, other._handle, ref outputRegion._handle));
252 var outputRegion =
new Region();
253 DllHelper.ExecuteAndMapReturnCodes(() =>
254 CInterface.peak_icv_Region_Union(_handle, other._handle, ref outputRegion._handle));
268 var outputRegion =
new Region();
269 DllHelper.ExecuteAndMapReturnCodes(() =>
270 CInterface.peak_icv_Region_Intersection(_handle, other._handle, ref outputRegion._handle));
287 var outputRegion =
new Region();
288 DllHelper.ExecuteAndMapReturnCodes(() =>
289 CInterface.peak_icv_Region_Dilation(_handle, structuringElement._handle, ref outputRegion._handle));
306 var outputRegion =
new Region();
307 DllHelper.ExecuteAndMapReturnCodes(() =>
308 CInterface.peak_icv_Region_Erosion(_handle, structuringElement._handle, ref outputRegion._handle));
322 List<Point> points =
Points;
323 return "{" +
string.Join(
", ", points.Select(p => $
"{{X: {p.X}, Y: {p.Y}}}")) +
"}";
341 return regionMinuend.
Difference(regionSubtrahend);
353 return region1.
Union(region2);
356 private sealed class RegionEqualityComparer : IEqualityComparer<Region>
360 if (ReferenceEquals(x, y))
365 if (ReferenceEquals(x,
null))
370 if (ReferenceEquals(y,
null))
376 DllHelper.ExecuteAndMapReturnCodes(() =>
377 CInterface.peak_icv_Region_Compare(x._handle, y._handle, out isEqual));
382 public int GetHashCode(Region obj)
386 return obj.Points?.Aggregate(17, (current, p) => current * 31 + p.GetHashCode()) ?? 0;
391 internal sealed class Handle : SafeHandleZeroOrMinusOneIsInvalid
393 internal Handle() : base(true)
395 DllHelper.ExecuteAndMapReturnCodes(() => CInterface.peak_icv_Region_Create(out handle));
398 internal Handle(Backend.Types.peak_icv_point[] cPoints) : base(true)
400 DllHelper.ExecuteAndMapReturnCodes(() =>
401 CInterface.peak_icv_Region_CreateFromPoints(out handle, cPoints, (uint) cPoints.Length));
404 internal Handle(Backend.Types.peak_common_rectangle cRectangle) : base(true)
406 DllHelper.ExecuteAndMapReturnCodes(() =>
407 CInterface.peak_icv_Region_CreateFromRectangle(out handle, cRectangle));
410 internal Handle(IntPtr handle) : base(true)
415 protected override bool ReleaseHandle()
417 return CInterface.peak_icv_Region_Destroy(handle) ==
418 Backend.Types.peak_icv_status.PEAK_ICV_STATUS_SUCCESS;
422 private static class CInterface
424 [DllImport(Global.LibraryName, CallingConvention = Global.CallingConvention)]
425 public static extern Backend.Types.peak_icv_status peak_icv_Region_Create(out IntPtr region_handle);
427 [DllImport(Global.LibraryName, CallingConvention = Global.CallingConvention)]
428 public static extern Backend.Types.peak_icv_status peak_icv_Region_CreateFromPoints(
429 out IntPtr region_handle,
430 Backend.Types.peak_icv_point[] points, nuint num_points);
432 [DllImport(Global.LibraryName, CallingConvention = Global.CallingConvention)]
433 public static extern Backend.Types.peak_icv_status peak_icv_Region_CreateFromRectangle(
434 out IntPtr region_handle,
435 Backend.Types.peak_common_rectangle rectangle);
437 [DllImport(Global.LibraryName, CallingConvention = Global.CallingConvention)]
438 public static extern Backend.Types.peak_icv_status peak_icv_Region_Destroy(IntPtr region_handle);
440 [DllImport(Global.LibraryName, CallingConvention = Global.CallingConvention)]
441 public static extern Backend.Types.peak_icv_status peak_icv_Region_GetArea(Handle input_region,
444 [DllImport(Global.LibraryName, CallingConvention = Global.CallingConvention)]
445 public static extern Backend.Types.peak_icv_status peak_icv_Region_GetPoints_GetCount(
447 out nuint points_count);
449 [DllImport(Global.LibraryName, CallingConvention = Global.CallingConvention)]
450 public static extern Backend.Types.peak_icv_status peak_icv_Region_GetPoints(Handle input_region,
451 [Out] Backend.Types.peak_icv_point[] points, nuint num_points);
453 [DllImport(Global.LibraryName, CallingConvention = Global.CallingConvention)]
454 public static extern Backend.Types.peak_icv_status peak_icv_Region_GetConnectedComponents_GetCount(
455 Handle input_region, out nuint num_connected_components);
457 [DllImport(Global.LibraryName, CallingConvention = Global.CallingConvention)]
458 public static extern Backend.Types.peak_icv_status peak_icv_Region_GetConnectedComponents(
460 IntPtr[] output_regions, nuint num_connected_components);
462 [DllImport(Global.LibraryName, CallingConvention = Global.CallingConvention)]
463 public static extern Backend.Types.peak_icv_status peak_icv_Region_Array_Create(IntPtr[] region_handles,
464 nuint num_region_handles);
466 [DllImport(Global.LibraryName, CallingConvention = Global.CallingConvention)]
467 public static extern Backend.Types.peak_icv_status peak_icv_Region_Array_Destroy(IntPtr[] region_handles,
468 nuint num_region_handles);
470 [DllImport(Global.LibraryName, CallingConvention = Global.CallingConvention)]
471 public static extern Backend.Types.peak_icv_status peak_icv_Region_Compare(Handle region_lhs,
473 [MarshalAs(UnmanagedType.I1)] out
bool is_equal);
475 [DllImport(Global.LibraryName, CallingConvention = Global.CallingConvention)]
476 public static extern Backend.Types.peak_icv_status peak_icv_Region_GetCenterOfGravity(Handle input_region,
477 out Backend.Types.peak_icv_point_f center_of_gravity);
479 [DllImport(Global.LibraryName, CallingConvention = Global.CallingConvention)]
480 public static extern Backend.Types.peak_icv_status peak_icv_Region_Difference(Handle input_region_minuend,
481 Handle input_region_subtrahend, ref Handle output_region_difference);
483 [DllImport(Global.LibraryName, CallingConvention = Global.CallingConvention)]
484 public static extern Backend.Types.peak_icv_status peak_icv_Region_Union(Handle input_region_1,
485 Handle input_region_2, ref Handle output_region_united);
487 [DllImport(Global.LibraryName, CallingConvention = Global.CallingConvention)]
488 public static extern Backend.Types.peak_icv_status peak_icv_Region_Intersection(Handle input_region_1,
489 Handle input_region_2, ref Handle output_region_intersection);
491 [DllImport(Global.LibraryName, CallingConvention = Global.CallingConvention)]
492 public static extern Backend.Types.peak_icv_status peak_icv_Region_Dilation(Handle input_region,
493 Handle input_structuring_element, ref Handle output_region_dilation);
495 [DllImport(Global.LibraryName, CallingConvention = Global.CallingConvention)]
496 public static extern Backend.Types.peak_icv_status peak_icv_Region_Erosion(Handle input_region,
497 Handle input_structuring_element, ref Handle output_region_erosion);
499 [DllImport(Global.LibraryName, CallingConvention = Global.CallingConvention)]
500 public static extern Backend.Types.peak_icv_status peak_icv_Region_Draw(Image.Handle input_image,
501 Handle input_region, Backend.Types.peak_icv_drawing_options drawing_options);