using Avalonia; using Avalonia.Media; using Avalonia.Input; using Avalonia.Controls; using Avalonia.Media.Imaging; using Mat = OpenCvSharp.Mat; using Cv2 = OpenCvSharp.Cv2; using GSS2.Core.Extentions; namespace GSS2.UI.Core; public class OpenCvImage : ZoomPanImage { private class OpenCvBitmap : Bitmap { public OpenCvBitmap(Mat mat) : base( format: Avalonia.Platform.PixelFormat.Rgba8888, alphaFormat: Avalonia.Platform.AlphaFormat.Unpremul, data: mat.Data, size: new PixelSize(mat.Width, mat.Height), dpi: new Vector(96, 96), stride: (mat.DataEnd - mat.DataStart).ToInt32() / mat.Rows ) { } } public static readonly StyledProperty ImageProperty = AvaloniaProperty.Register(nameof(Image), defaultValue: null); public Mat? Image { get => GetValue(ImageProperty); set => SetValue(ImageProperty, value); } public OpenCvImage() : base() { } protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) { if (change.Property == ImageProperty) { if (Image is null) return; if (Image.Type() != OpenCvSharp.MatType.CV_8UC3 && Image.Type() != OpenCvSharp.MatType.CV_8UC4 && Image.Type() != OpenCvSharp.MatType.CV_16UC3 && Image.Type() != OpenCvSharp.MatType.CV_16UC4) return; var image = new Mat(); Image.CopyTo(image); if (image.Type() == OpenCvSharp.MatType.CV_16UC3) image.ConvertTo(image, OpenCvSharp.MatType.CV_8UC3, 1 / 256.0); if (image.Type() == OpenCvSharp.MatType.CV_16UC4) image.ConvertTo(image, OpenCvSharp.MatType.CV_8UC4, 1 / 256.0); var channels = image.Split(); var alphaChannel = image.Channels() == 4 ? channels[4] : new Mat(Image.Size(), OpenCvSharp.MatType.CV_8UC1, new OpenCvSharp.Scalar(255)); Cv2.Merge([channels[2], channels[1], channels[0], alphaChannel], image); ImageSource = new OpenCvBitmap(image); InvalidateVisual(); } base.OnPropertyChanged(change); } }