MAUI移动端:CameraView快照转Bitmap及跨平台兼容问题解决
解决MAUI跨平台图像处理替代System.Drawing.Common的方案
问题根源
System.Drawing.Common仅支持Windows平台,MAUI作为跨平台框架,在Android/iOS等非Windows设备上会抛出PlatformNotSupportedException,需改用跨平台图像库SkiaSharp(Google维护的跨平台2D图形库,完美适配MAUI)。
步骤1:安装SkiaSharp NuGet包
在项目中安装以下NuGet包:
SkiaSharp:核心图像处理库SkiaSharp.Views.Maui.Controls:MAUI集成组件- 按需安装对应平台原生资产包(如
SkiaSharp.NativeAssets.Android、SkiaSharp.NativeAssets.iOS)
步骤2:改写代码
替换命名空间
移除using System.Drawing;,添加:
using SkiaSharp; using System.IO;
主代码改写
// 改用Path.Combine适配跨平台路径格式 string camPath = Path.Combine(FileSystem.AppDataDirectory, "cam.jpg"); string grayPath = Path.Combine(FileSystem.AppDataDirectory, "gray.jpg"); await Cameraview.SaveSnapShot(Camera.MAUI.ImageFormat.JPEG, camPath); // 替换System.Drawing.Bitmap为SKBitmap,用SkiaSharp解码图像 SKBitmap bmp = SKBitmap.Decode(camPath); SKBitmap newbmp = MakeGrayscale(bmp); // 编码并保存灰度图像 using (var stream = File.OpenWrite(grayPath)) { newbmp.Encode(stream, SKEncodedImageFormat.Jpeg, 100); } // 更新Image控件源 sampleImage.Source = null; sampleImage.Source = ImageSource.FromFile(grayPath);
灰度处理方法改写
public static SKBitmap MakeGrayscale(SKBitmap original) { // 创建与原图尺寸、格式一致的新位图 SKBitmap newBitmap = new SKBitmap(original.Width, original.Height, original.ColorType, original.AlphaType); // 逐像素转换为灰度 for (int i = 0; i < original.Width; i++) { for (int j = 0; j < original.Height; j++) { SKColor originalColor = original.GetPixel(i, j); // 标准灰度计算公式 int grayScale = (int)((originalColor.Red * 0.3) + (originalColor.Green * 0.59) + (originalColor.Blue * 0.11)); SKColor newColor = new SKColor((byte)grayScale, (byte)grayScale, (byte)grayScale, originalColor.Alpha); newBitmap.SetPixel(i, j, newColor); } } return newBitmap; }
可选:高性能像素缓冲区处理
逐像素GetPixel/SetPixel性能较低,大图像建议直接操作内存缓冲区:
public static SKBitmap MakeGrayscaleFast(SKBitmap original) { SKBitmap newBitmap = new SKBitmap(original.Width, original.Height, original.ColorType, original.AlphaType); // 锁定像素缓冲区,直接读写内存 using (var originalPixels = original.LockPixels()) using (var newPixels = newBitmap.LockPixels()) { int bytesPerPixel = original.ColorType == SKColorType.Rgba8888 ? 4 : 3; int stride = original.RowBytes; for (int y = 0; y < original.Height; y++) { for (int x = 0; x < original.Width; x++) { int offset = y * stride + x * bytesPerPixel; byte r = originalPixels[offset]; byte g = originalPixels[offset + 1]; byte b = originalPixels[offset + 2]; byte a = bytesPerPixel == 4 ? originalPixels[offset + 3] : (byte)255; int grayScale = (int)(r * 0.3 + g * 0.59 + b * 0.11); byte gray = (byte)grayScale; newPixels[offset] = gray; newPixels[offset + 1] = gray; newPixels[offset + 2] = gray; if (bytesPerPixel == 4) newPixels[offset + 3] = a; } } } return newBitmap; }
说明
- SkiaSharp完全兼容MAUI所有目标平台(Android、iOS、Windows、MacCatalyst等)
- 缩放、裁剪等其他图像操作,均可通过SkiaSharp API实现,完全替代System.Drawing的功能
内容的提问来源于stack exchange,提问作者林碧山
相关产品推荐
相关产品推荐

