You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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,提问作者林碧山

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 18:58:16