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

如何将System.Drawing.Icon转换为Microsoft.UI.Xaml.ImageSource?

WinUI中System.Drawing.Icon转Microsoft.UI.Xaml.ImageSource的解决方案

方法一:通过MemoryStream转换(简单易实现)

将Icon转换为GDI+ Bitmap后保存到内存流,再用WinUI的BitmapImage加载,适合大多数场景:

using System.Drawing;
using System.IO;
using Microsoft.UI.Xaml.Media.Imaging;
using Windows.Storage.Streams;

public static ImageSource IconToImageSource(Icon icon)
{
    if (icon == null)
        return null;

    using var stream = new MemoryStream();
    icon.ToBitmap().Save(stream, System.Drawing.Imaging.ImageFormat.Png);
    stream.Position = 0;

    var bitmapImage = new BitmapImage();
    bitmapImage.SetSource(stream.AsRandomAccessStream());
    return bitmapImage;
}

注意事项

  • 需确保在UI线程调用此方法,因为BitmapImage的SetSource操作依赖UI线程上下文;若在非UI线程,可通过DispatcherQueue切换:
    await DispatcherQueue.TryEnqueue(async () =>
    {
        MyImage.Source = IconToImageSource(myIcon);
    });
    
  • 使用PNG格式保存可保留图标透明度,避免背景变黑。

方法二:通过Win32 API+WinRT SoftwareBitmap转换(高效低开销)

直接基于Icon的HBITMAP创建WinRT SoftwareBitmap,跳过GDI+的Bitmap转换,性能更优:

using System.Drawing;
using System.Runtime.InteropServices;
using Microsoft.UI.Xaml.Media.Imaging;
using Windows.Graphics.Imaging;
using Windows.Storage.Streams;

[DllImport("gdi32.dll", SetLastError = true)]
private static extern bool DeleteObject(IntPtr hObject);

public static async Task<ImageSource> IconToImageSourceAsync(Icon icon)
{
    if (icon == null)
        return null;

    IntPtr hBitmap = icon.ToBitmap().Handle;
    try
    {
        using var decoder = await GdiBitmapDecoder.CreateAsync(hBitmap);
        var softwareBitmap = await decoder.GetSoftwareBitmapAsync();
        
        var bitmapSource = new BitmapSource();
        await bitmapSource.SetSourceAsync(softwareBitmap.AsRandomAccessStream());
        return bitmapSource;
    }
    finally
    {
        // 必须释放GDI资源,防止内存泄漏
        DeleteObject(hBitmap);
    }
}

注意事项

  • 必须调用DeleteObject释放HBITMAP,否则会导致GDI资源泄漏;
  • 异步方法需注意线程调度,同样需在UI线程更新Image控件的Source属性。

为什么BitmapSource.FromAbi会报错?

BitmapSource.FromAbi的参数要求是WinRT BitmapSource对象的ABI指针,而System.Drawing.Icon.Handle是HICON(图标句柄),两者类型完全不匹配,直接传入会触发内存访问违例,因此不能用该方法转换。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 19:22:32