MAUI迁移:Android端SVG资源如何转为流用于SkiaSharp绘制?
解决MAUI迁移中Android端内置SVG资源转SkiaSharp可用格式的问题
问题根源
iOS打包时会将SVG资源转为PNG并存放在包根目录,因此可以通过FileSystem.OpenAppPackageFileAsync直接获取流;而Android会按屏幕分辨率将图片拆分到/res/drawable-*目录,无法通过文件系统路径访问,只能通过资源ID加载原生Drawable,但Drawable无法直接用于SkiaSharp绘制。
解决方案:将Android Drawable转为SKBitmap
核心思路是把Android原生Drawable(包括BitmapDrawable和VectorDrawable)转换为SkiaSharp的SKBitmap,这样就能直接在SKCanvas上绘制。
1. 跨平台工具类封装
using SkiaSharp; #if ANDROID using Android.Graphics; using Android.Content.Res; #endif public static class ResourceBitmapHelper { public static async Task<SKBitmap> GetBuiltInSKBitmapAsync(string resourceName) { #if IOS // iOS端通过文件系统加载PNG并解码为SKBitmap using var stream = await FileSystem.OpenAppPackageFileAsync($"{resourceName}.png"); return stream != null ? SKBitmap.Decode(stream) : null; #elif ANDROID // 从资源名获取对应的Android资源ID var resourceId = MainApplication.Current.Resources.GetIdentifier( resourceName, "drawable", MainApplication.Current.PackageName ); if (resourceId == 0) return null; var drawable = MainApplication.Current.GetDrawable(resourceId); if (drawable == null) return null; Bitmap androidBitmap; // 处理矢量Drawable和普通BitmapDrawable if (drawable is VectorDrawable vectorDrawable) { // 创建空白Bitmap并将VectorDrawable绘制到上面 androidBitmap = Bitmap.CreateBitmap( vectorDrawable.IntrinsicWidth, vectorDrawable.IntrinsicHeight, Bitmap.Config.Argb8888 ); using var canvas = new Canvas(androidBitmap); vectorDrawable.SetBounds(0, 0, canvas.Width, canvas.Height); vectorDrawable.Draw(canvas); } else { androidBitmap = ((BitmapDrawable)drawable).Bitmap; } // 将Android Bitmap转为SKBitmap var skBitmap = androidBitmap.ToSKBitmap(); androidBitmap.Recycle(); // 释放原生Bitmap资源,避免内存泄漏 return skBitmap; #else return null; #endif } }
2. 使用示例
在SkiaSharp绘制逻辑中调用工具类,直接获取可用的SKBitmap:
// 替换为你的内置资源名称(不带后缀) var skBitmap = await ResourceBitmapHelper.GetBuiltInSKBitmapAsync("icon_svg"); if (skBitmap != null) { // 在SKCanvas上绘制图片 canvas.DrawBitmap(skBitmap, new SKPoint(100, 100), new SKPaint()); }
注意事项
- Android端需要确保资源名称与
Resources/drawable目录下的文件名称一致(不含后缀) - 处理VectorDrawable时要注意创建对应尺寸的Bitmap,避免拉伸变形
- 转换后记得调用
androidBitmap.Recycle()释放原生资源,防止内存占用过高
内容的提问来源于stack exchange,提问作者Red Nightingale
相关产品推荐
相关产品推荐

