Files
GSS2Rework/GSS2.UI.Core/OpenCvImage.cs
T

67 lines
2.1 KiB
C#

using Avalonia;
using Avalonia.Media.Imaging;
using Mat = OpenCvSharp.Mat;
using Cv2 = OpenCvSharp.Cv2;
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<Mat?> ImageProperty = AvaloniaProperty.Register<OpenCvImage, Mat?>(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);
}
}