WPF迁移avalonia之图像处理(一)

发布于:2025-09-03 ⋅ 阅读:(17) ⋅ 点赞:(0)

从WPF迁移到avalonia中,对于图像处理部分,在WPF常用System.Windows.Drawing中图像处理元素,但是在开发avalonia应用时考虑跨平台特性,则必须有对应的跨平台替换方案。主要考虑Avalonia.Media.Imaging.Bitmap和SkiaSharp.SKBitmap

方案比对

特性维度 Avalonia.Media.Imaging.Bitmap SkiaSharp.SKBitmap
集成度与兼容性 原生支持,与Avalonia控件和绑定机制无缝集成 ⚠️ 需额外安装 NuGet包,但API稳定且跨平台一致
功能丰富度 提供日常UI操作(加载、显示、简单变换) 支持高级滤镜、路径绘制、文本渲染、多种颜色空间等复杂图像处理
性能 对常规UI操作进行了优化 高性能,底层为C++实现的Skia库,复杂图形操作和渲染效率高
API 风格与学习曲线 与WPF的System.Windows.Media.Imaging.BitmapImage类似,迁移成本低 自成体系的API,需一定学习成本,但功能强大灵活
跨平台一致性 依赖Avalonia的实现 行为高度一致,各平台渲染结果相同
内存与资源管理 与Avalonia UI元素生命周期绑定 需留意手动管理SKBitmap等对象的释放(使用usingDispose
优选情况

1.图像的加载、显示、简单的缩放或裁剪

2.图像直接与Avalonia的Image控件绑定

3.希望尽量减少外部依赖,WPF改动较少

1.复杂的图像处理,如应用滤镜、模糊、锐化、颜色校正等

2.动态生成内容丰富的图片

3.极高的跨平台一致性

根据项目特性,考虑使用SkiaSharp.SKBitmap;最后选择Avalonia.Media.Imaging.Bitmap与SkiaSharp.SKBitmap结合的方案

1.考虑图片会绑定到ImageViewer控件,该控件数据源是IImage?类型Avalonia.Media.Imaging.Bitmap可以直接绑定,但是SkiaSharp.SKBitmap不可直接绑定,且avalonia中使用Avalonia.Media.Imaging.Bitmap改动较少;

2.考虑需要对图像进行图像处理,如灰度化,锐化等,所以使用SkiaSharp.SKBitmap

实现方案

1.将Avalonia的Bitmap转换为SkiaSharp的SKBitmap。

2.使用SkiaSharp进行图像处理。

......

3.将SkiaSharp的SKBitmap转换回Avalonia的Bitmap。

WPF迁移avalonia的图像部分常遇问题

1.OpenCvSharp.Extensions.BitmapConverter拓展包仅适用于Windows

OpenCvSharp.Extensions.BitmapConverter仅限用于Windows平台,因为WPF和avalonia的使用图像不同(System.Drawing.Bitmap vs Avalonia.Media.Imaging.Bitmap),所以需要实现一组

Mat ↔ Avalonia Bitmap相互转换的方法。

2.WPF 中的灰度处理使用矩阵ColorMatrix 转换为 SkiaSharp 颜色矩阵

要将 WPF 的 5×5 矩阵转换为 Skia 的 4×5 矩阵,如果使用HLSL着色器,则可能需要将矩阵转置(因为HLSL是列主序),并且需要将矩阵扩展矩阵(对于RGB和A的变换)

WPF的矩阵含义

new float[][] {
  new float[] {.711f, .7111f, .711f, 0, 0},  // 红色输出 = 0.711*R + 0.711*G + 0.711*B + 0*A + 0
  new float[] {.222f, .222f, .222f, 0, 0},  // 绿色输出 = 0.222*R + 0.222*G + 0.222*B + 0*A + 0
  new float[] {.111f, .111f, .111f, 0, 0},  // 蓝色输出 = 0.111*R + 0.111*G + 0.111*B + 0*A + 0
  new float[] {0, 0, 0, 1, 0},        // Alpha输出 = 0*R + 0*G + 0*B + 1*A + 0
  new float[] {0, 0, 0, 0, 1}         // 偏移量(通常为0,0,0,0,1)
}
  1. 转置这些行(行变列,列变行)
  2. 保持每行的第 5 个值(偏移量)不变

avalonia下变换后的矩阵转换

new float[] {
  0.711f, 0.222f, 0.111f, 0, 0,  // 第一列:红色系数
  0.711f, 0.222f, 0.111f, 0, 0,  // 第二列:绿色系数
  0.711f, 0.222f, 0.111f, 0, 0,  // 第三列:蓝色系数
  0,    0,    0,    1, 0   // 第四列:Alpha系数
}

显示效果

使用灰度化矩阵后


网站公告

今日签到

点亮在社区的每一天
去签到