从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 等对象的释放(使用using 或Dispose ) |
优选情况 | 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 + 0new float[] {.222f, .222f, .222f, 0, 0}, // 绿色输出 = 0.222*R + 0.222*G + 0.222*B + 0*A + 0new float[] {.111f, .111f, .111f, 0, 0}, // 蓝色输出 = 0.111*R + 0.111*G + 0.111*B + 0*A + 0new float[] {0, 0, 0, 1, 0}, // Alpha输出 = 0*R + 0*G + 0*B + 1*A + 0new float[] {0, 0, 0, 0, 1} // 偏移量(通常为0,0,0,0,1)
}
- 转置这些行(行变列,列变行)
- 保持每行的第 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系数
}
显示效果
使用灰度化矩阵后