Repository navigation
Releases
Releases · sn4k3/EmguExtensions
v0.3.0
- Upgrade Emgu.CV and native test runtimes to
5.0.0.6584/ OpenCV 5. - Migrate affine and rotated-text transforms from the removed
Matrix<T>type toMatstorage with span access - Update legacy text APIs/tests to
HersheyFonts. - Extend
DepthType.ByteCountfor half, bfloat16, bool, uint32, uint64, and int64 storage. - Add caller-owned
FontFacetext overloads for Unicode and custom fonts:PutTextExtended,
GetTextSizeExtended, andPutTextRotated, with pixel font sizes, optional weights, wrapping,
and whole-block alignment. AddPutTextInRectangleto fit and clip text within an image region. - Add perspective helpers:
CreatePerspectiveCropvalidates ordered convex corners, infers dimensions when requested, and preserves
image depth/channels with configurable sampling and borders.OrderPerspectiveCornersgives unordered corners a deterministic clockwise order.PerspectiveCropsupports reusable destinations and safely handles overlapping source/destination buffers.GetPerspectiveCropSize,CreatePerspectiveTransform, andMapPerspectivePointssupport forward/inverse
coordinate mapping, rejecting non-finite coordinates and points at infinity.- Add a
RotatedRectcrop overload, usable withEmguContour.BoundsBestFit. FindQuadrilateralsreturns ordered convex contour approximations, filtered by area and sorted largest first.
- Add boolean-mask creation and conversion helpers, plus logical
MaskAnd,MaskOr,MaskXor, andMaskNot.
SupportCvBoolandCv8Uinput masks, including ROI views; boolean output uses canonical0/1values,
andToByteMaskuses0/255. - Optimize mask conversion and logical negation with native thresholding, use native bitwise operations for
combinations, and fill constant boolean masks natively while preserving canonical values and ROI strides. - Keep the Windows native test packages' NU1701 metadata warnings visible without failing the test build.
- Document resource ownership, geometry conventions, text behavior, mask formats, and OpenCV 5 migration
considerations; add native regression tests for text, perspective geometry, buffer reuse, and masks.
v0.2.1
MatCompressor& Subclasses:Decompress/DecompressAsyncnow throwArgumentExceptionfor an empty destinationMaton compressors that do
not allocate it (everything except PNG), instead of silently returning an empty resultPNG: throwInvalidDataExceptionon corrupt data (OpenCV did not report it) and decode into pre-allocated
destinations (including ROIs) with size/type validationNone: copy with a length check instead of Emgu's uncheckedSetTo(byte[]), and support non-continuous destinationsBrotli: never return an empty result for a non-empty source- Cache
Id, drop redundantasync/awaitwrappers and document the integer compression levels, the
non-interruptible async work and the non-thread-safeAvailableCompressors
CMat:- Thread safety: every property read and the
Compressor/CompressionLevel/ThresholdToCompresssetters now go
through the lock, andEquals,GetHashCode,ToStringand the ratio properties work on a consistent snapshot;
the hash is computed outside the lock - Fix silent data loss when a compressor returns an empty result, store raw for the
Nonecompressor without a
wasted compress pass, and only fall back to raw on codec errors (ArgumentExceptions now propagate) - Fix
SetCompressedByteskeeping a staleRoiand document that it takes ownership of the array - Validate the decompressed size/type against the cached description (
InvalidDataExceptionon mismatch) - Breaking (binary): the
compressionLevelconstructor parameter is nowCompressionLevel?and defaults to
MatCompressor.DefaultCompressionLevel
- Thread safety: every property read and the
EmguCvExtensions:PutTextRotated: render on a small layer instead of rotating copies of the whole image (about 30x faster on a 12MP
image) and rotate exactly around the text origin- Vertical
ScanLineswalks the image row by row (cache friendly), same results and ordering GetSvgPathformats coordinates without allocations and with the invariant cultureResizeandShrinkToFitPreserveAspectnever produce a zero-sized image and validate their argumentsCreateLetterBoxuses area interpolation when shrinking,RotateAdjustBoundsrounds the bounds upCreateMasknow always returns an 8-bit single-channel mask, as documentedSanitizeRoiWithBehaviortreats any ROI without area as empty,GetMemory2D(roi)validates likeGetSpan2D(roi)CopyAreasSmallerThan/CopyAreasLargerThanadd islands nested inside holes to the area of their group- Document
Kernel3X3Rectangleas a shared read-only instance
DrawingExtensions.FactorColorrounds instead of truncating; addPointExtensions.FindLength(PointF, PointF)BitmapInfo/Mat.GetBitmapInfo():RowBytesis now the real stride (Mat.Step), it was the row data size, which was
wrong for ROI MatsEmguExtensions.Avalonia:ToBitmap: convert straight into the locked bitmap memory through aMatview, without an intermediate Mat, and
validate the Mat (channels, depth, color type) before allocating the bitmapToBitmap(Type srcType): validate thatsrcTypeis an Emgu color matching the channel count, and honor it for
4-channel Mats (e.g.Rgba), which were always copied as BGRA- Add
ToBitmap(scale, shift)/ToBitmapAsyncto convert 16-bit, floating point and other depths to 8-bit - Add
ILockedFramebuffer.ToMat()(zero-copy view honoring the stride) andWriteableBitmap.ToMat()(copy) - Breaking:
WriteableBitmap.GetBitmapInfo()no longer returns the memory address (it was only valid while the
bitmap was locked): use the newWithBitmapInfoto access it inside a lock - Breaking:
ILockedFramebuffer.GetRowSpanOfBytesexcludes the row padding by default (likeGetRowSpanand the
coreMataccessors), a negativelengthnow throws instead of meaning "all", andGetPixelBytePos/GetPixelPos
validate the coordinates - Add
PixelPoint/PixelRectoverloads next to theSystem.Drawingones,ByteCountInt64, checked size
calculations, and document that the spans are only valid while the framebuffer is locked - Reference
CommunityToolkit.HighPerformanceexplicitly and add a test suite running on the Avalonia headless
platform
v0.2.0
EmguCvExtensions:- Fix element offset calculation in
FillSpan<T>for multi-byte types (sizeof(T) > 1) - Enable continuous memory fast-path in
ToArrayusing direct span copy - Fix empty and non-positive dimension checks in
GetMemory2D,GetReadOnlyMemory2D,InitMat, and
RoiFromBoundingRectangle - Ensure unmanaged matrix disposal on exceptions in
CreateLetterBoxandSkeletonize - Fix native memory leak in
CopyAreasSmallerThanandCopyAreasLargerThanby disposing contour group vectors in
finallyblocks - Optimize
GetSvgPathby caching contour point arrays to avoid per-vertex P/Invoke calls - Eliminate closure allocations in
GetTextSizeExtendedandPutTextExtended, and allocatelinesSizeonly for
non-left text alignments - Align generic type constraints on
FindFirst*Pixel*methods toIBinaryInteger<T>, IMinMaxValue<T> - Add missing
ArgumentNullException.ThrowIfNullguards across public APIs
- Fix element offset calculation in
CMat:- Fix ROI zero-dimension checks in
UncompressedLength,Compress(MatRoi), andDecompress - Ensure unmanaged matrix disposal on decompression failure in
RawDecompressInternal - Add rollback safety in
ChangeCompressorto preserve original dimensions and ROI if re-encoding fails - Improve
GetHashCodeto incorporate matrix dimensions, channels, and ROI - Add argument null checks on constructors and public methods
- Fix ROI zero-dimension checks in
MatCompressor& Subclasses:- Add non-continuous destination
Mat(e.g. ROI submatrix) decompression support acrossBrotli,Deflate,GZip,
ZLib, andZstdcompressors via row-by-row streaming intodst.GetRowSpanOfBytes(row) - Add null validation guard to
MatCompressor.DefaultCompressorproperty setter - Add empty byte array guard and cancellation token checking in
DecompressAsyncandCompressAsync - Clean up unused constants and use
ArgumentOutOfRangeExceptioninMatCompressorBrotli
- Add non-continuous destination
EmguContours,EmguContour,EmguContourFamily:- Fix bug in
EmguContours.GetLargestContourArea(VectorOfVectorOfPoint, int[,])where contour index 0 was
unconditionally assigned - Fix
InvalidOperationExceptioninMinSolidAreaandMaxSolidAreawhenFamiliesis empty - Optimize
ContoursIntersectingPixelsto rasterize only the intersection bounding boxRectangle.Intersectinstead
of the full contour bounding box - Optimize
CalculateCentroidDistancesby caching contour centroid outside the inner comparison loop - Pre-populate
_contoursarray upfront in constructors to prevent null or unassigned elements - Implement
IEquatable<EmguContour>and checkIsEmptyinEmguContour.Centroidto avoid P/Invoke on empty
contours - Ensure unmanaged matrix disposal on exception in
ContourApproximationandToVectorOfVectorOfPoint - Fix
EmguContourFamily.Roottraversal to handle non-zero external depth roots safely - Add argument null validation guards across all public contour APIs
- Fix bug in
- Add regression tests covering all audited compressors and contour methods
- Modernize DevSkim GitHub Actions workflow (
microsoft/DevSkim-Action@v1) - Modernize and optimize NuGet release workflow (
.github/workflows/release.yml) with concurrency guards, .NET package
caching, package artifact archiving, step summaries, and release package asset attachments - Bump dependencies
v0.1.9
- Add
EmguCvExtensions.CreateVectorto wrap a byte buffer in a Mat - Refactor span/memory accessors to use shared
ResolveElementRangehelper - Add validation methods:
ValidateByteRange,ValidatePixelCoordinates,ValidateRoi - Fix integer overflow in
FindLength,Rotate, and polygon calculations - Fix
CalculatePolygonRadiusFromSideLengthformula; raise minimum sides guard to 3 - Add a stack-allocation fast path in Brotli compressor for small inputs
- Replace
Marshal.Copywith span-based copy inSetByte - Fix
InitMatarray factory to dispose already-created Mats on failure - Change
MatCompressorequality to use Provider+Name instead of Id - Update Avalonia to 12.1.0, DotNext to 6.4.1, and other dependencies
v0.1.8
- Change
Skeletonizeto use own implementation instead ofXImgProcdue to mini openCV build lacks of it
v0.1.7
- Add
CompressCoreAsyncandDecompressCoreAsyncoverrides toMatCompressor - Add
CopyToAsync(Stream, CancellationToken)toEmguCvExtensionsfor async raw Mat stream copies. Continuous
matrices are written as one block; non-continuous matrices are written row by row without row padding. - Add
Memory/Memory2Daccessors toEmguCvExtensionsmirroring the span accessors:GetMemory,
GetReadOnlyMemory,GetRowMemory,GetReadOnlyRowMemory,GetMemory2D(+ ROI overload),GetReadOnlyMemory2D
(+ ROI overload), and their*OfBytescounterparts.
v0.1.6
- Add
EmptyRoiBehaviorenum and refactor ROI-related APIs to use ref Rectangle and explicit empty-ROI semantics. - Add
ConstrainRoiandSanitizeRoiWithBehaviorhelpers - Add new SafeRoi overloads (ref-based, padding and behavior options), additional Roi/RoiFromBoundingRectangle overloads with padding, and RoiFromCenter adjustments.
- Rename
PutTextLineAlignment.NonetoDefaultand add descriptions. - Update
MatRoito use the new SafeRoi semantics. - Update span/stream usages to ReadOnlySpan helpers
- Remove old async CopyToAsync/CropByBounds implementations.
- Tests updated to cover ConstrainRoi and to use ref SafeRoi.
v0.1.5
- Improve the
MatCompressorschemantic by favor int compressionLevel instead of enum
v0.1.4
- Add StageKit.Primitives dependency and related using imports
- Add a new EmguExtensions.Avalonia project (bitmap helpers and Mat→WriteableBitmap converters) and a BitmapInfo record for describing locked framebuffer state.
- Introduce many EmguCvExtensions improvements:
- PixelCount
- Renamed LengthInt32/LengthInt64 → ByteCountInt32/ByteCountInt64
- Async helpers (GetPngBytesAsync, CopyToAsync, ToBitmapAsync)
- Additional span/stream helpers
- Small API/exception message refinements.
v0.1.3
- Add/adjust EmguCvExtensions API
- Make common color/anchor constants readonly
- Add
Kernel3x3Rectangle - Rename
InitMat(Count)toInitMats(Count) - Add
Mat.New(Size)andNewZeros(Size),NewFromRoiToCenter, and default parameters forGetSpanOfBytesandFillSpanoverloads. - Implement
CopyAreasSmallerThanandCopyAreasLargerThanto copy contour-based regions by area.
- Add
MatRoi.Cloneconvenience method.