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

如何将Xamarin ImageSource转换为可像素操作的格式(如SkiaSharp/GDI)

Xamarin.Forms图片像素级操作解决方案

一、SkiaSharp:正确将ImageSource转为可读写SKBitmap

你之前的代码问题在于ImageSource没有直接的ToStream()方法,需要根据不同的ImageSource类型异步获取流,再解码为可修改的SKBitmap。以下是通用实现:

using SkiaSharp;
using Xamarin.Forms;
using System.IO;
using System.Threading.Tasks;

public static async Task<SKBitmap> ImageSourceToSKBitmapAsync(ImageSource imageSource)
{
    SKBitmap skBitmap = null;
    Stream stream = null;

    try
    {
        // 根据ImageSource类型获取对应流
        if (imageSource is FileImageSource fileSource)
        {
            stream = File.OpenRead(fileSource.File);
        }
        else if (imageSource is UriImageSource uriSource)
        {
            using var httpClient = new System.Net.Http.HttpClient();
            stream = await httpClient.GetStreamAsync(uriSource.Uri);
        }
        else if (imageSource is StreamImageSource streamSource)
        {
            stream = await streamSource.Stream(CancellationToken.None);
        }

        if (stream != null)
        {
            skBitmap = SKBitmap.Decode(stream);
            // 确保Bitmap可读写(原解码的Bitmap可能为只读)
            if (!skBitmap.IsMutable)
            {
                skBitmap = skBitmap.Copy();
            }
        }
    }
    finally
    {
        stream?.Dispose();
    }

    return skBitmap;
}

像素读写示例

ImageSource myImageSource = // 你的ImageSource实例
SKBitmap bitmap = await ImageSourceToSKBitmapAsync(myImageSource);

if (bitmap != null && bitmap.Width > 0 && bitmap.Height > 0)
{
    // 获取(10,10)位置的像素颜色
    SKColor pixelColor = bitmap.GetPixel(10, 10);
    // 设置(10,10)位置为红色
    bitmap.SetPixel(10, 10, SKColors.Red);
}

二、GDI+方案(仅Windows平台适用)

GDI+仅支持Windows平台(如Xamarin.Windows),移动端(Android、iOS)无法使用。若你的项目仅针对Windows,可使用System.Drawing.Common库(.NET 6+需在项目文件中启用Windows兼容):

using System.Drawing;
using Xamarin.Forms;
using System.IO;
using System.Threading.Tasks;

public static async Task<Bitmap> ImageSourceToBitmapAsync(ImageSource imageSource)
{
    Bitmap bitmap = null;
    Stream stream = null;

    try
    {
        // 同样先获取流,逻辑与SkiaSharp一致
        if (imageSource is FileImageSource fileSource)
        {
            stream = File.OpenRead(fileSource.File);
        }
        else if (imageSource is UriImageSource uriSource)
        {
            using var httpClient = new System.Net.Http.HttpClient();
            stream = await httpClient.GetStreamAsync(uriSource.Uri);
        }
        else if (imageSource is StreamImageSource streamSource)
        {
            stream = await streamSource.Stream(CancellationToken.None);
        }

        if (stream != null)
        {
            bitmap = new Bitmap(stream);
            // 创建可读写副本(原Bitmap可能只读)
            bitmap = new Bitmap(bitmap);
        }
    }
    finally
    {
        stream?.Dispose();
    }

    return bitmap;
}

像素读写示例

Bitmap gdiBitmap = await ImageSourceToBitmapAsync(myImageSource);
if (gdiBitmap != null)
{
    // 获取(10,10)位置像素
    Color pixel = gdiBitmap.GetPixel(10, 10);
    // 设置(10,10)位置为蓝色
    gdiBitmap.SetPixel(10, 10, Color.Blue);
}

三、其他替代方案

  • ImageSharp:跨平台图片处理库,支持.NET Standard,转换逻辑类似,先获取流再解码为Image对象,同样支持像素级读写。
  • 注意事项:所有Bitmap对象使用完毕后需调用Dispose()释放资源,避免内存泄漏;UI线程操作控件时需切换回主线程。

内容的提问来源于stack exchange,提问作者user23066555

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 05:45:32