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

如何在WPF中实现实时视图?WinForm代码迁移遇类型转换错误

问题描述

原本在Windows Form中实现实时视图的代码可正常运行,但迁移到WPF时,因WPF使用Image控件而非WinForms的PictureBox,赋值时出现错误:

Can not implicitly convert type 'System.Drawing.Bitmap' to 'System.MediaControls.Image'

相关错误代码片段:

if (btn_GetviewWasClicked)
{
    Bitmap image = new Bitmap(width, height);
    Rectangle rect = new Rectangle(0, 0, width, height);
    BitmapData bmpData = image.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

    IntPtr ptr = bmpData.Scan0;
    Marshal.Copy(buf, 0, ptr, 1200000);
    image.UnlockBits(bmpData);
    img_original.Source = image;// 错误位置


    Bitmap image2 = new Bitmap(width, height);
    Rectangle rect2 = new Rectangle(0, 0, width, height);
    BitmapData bmpData2 = image2.LockBits(rect2, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

    IntPtr ptr2 = bmpData2.Scan0;
    Marshal.Copy(bf, 0, ptr2, 1200000);
    image2.UnlockBits(bmpData2);

    img_original = image2;// 错误位置
}
解决方案

WPF的Image控件Source属性需要的是System.Windows.Media.Imaging.ImageSource派生类型(比如BitmapImage),而非WinForms的System.Drawing.Bitmap,两者属于不同UI框架,无法直接赋值。以下是两种解决方式:

方式一:Bitmap转BitmapImage(通用场景)

添加转换方法,将WinForms的Bitmap转为WPF兼容的BitmapImage,同时注意资源释放:

using System.Windows.Media.Imaging;
using System.IO;

if (btn_GetviewWasClicked)
{
    // 处理第一张图
    using (Bitmap image = new Bitmap(width, height))
    {
        Rectangle rect = new Rectangle(0, 0, width, height);
        BitmapData bmpData = image.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

        IntPtr ptr = bmpData.Scan0;
        Marshal.Copy(buf, 0, ptr, 1200000);
        image.UnlockBits(bmpData);

        img_original.Source = ConvertBitmapToBitmapImage(image);
    }

    // 处理第二张图(注意:不能直接给img_original赋值Bitmap,需设置Source)
    using (Bitmap image2 = new Bitmap(width, height))
    {
        Rectangle rect2 = new Rectangle(0, 0, width, height);
        BitmapData bmpData2 = image2.LockBits(rect2, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

        IntPtr ptr2 = bmpData2.Scan0;
        Marshal.Copy(bf, 0, ptr2, 1200000);
        image2.UnlockBits(bmpData2);

        img_original.Source = ConvertBitmapToBitmapImage(image2);
    }
}

// Bitmap转BitmapImage的工具方法
private BitmapImage ConvertBitmapToBitmapImage(Bitmap bitmap)
{
    using (MemoryStream ms = new MemoryStream())
    {
        bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
        ms.Position = 0;
        BitmapImage bitmapImage = new BitmapImage();
        bitmapImage.BeginInit();
        bitmapImage.CacheOption = BitmapCacheOption.OnLoad; // 确保流关闭后图像仍可显示
        bitmapImage.StreamSource = ms;
        bitmapImage.EndInit();
        bitmapImage.Freeze(); // 冻结后可在非UI线程访问(按需使用)
        return bitmapImage;
    }
}

方式二:使用WriteableBitmap(实时视图高性能场景)

如果是频繁更新的实时视图,直接使用WPF的WriteableBitmap更高效,无需转换Bitmap:

using System.Windows.Media.Imaging;

// 全局声明WriteableBitmap,在窗口初始化时创建
private WriteableBitmap _writeableBitmap;

// 在窗口构造函数或Loaded事件中初始化
public YourWindow()
{
    InitializeComponent();
    // 参数:宽、高、DPI X、DPI Y、像素格式、调色板(null用默认)
    _writeableBitmap = new WriteableBitmap(width, height, 96, 96, PixelFormats.Bgr24, null);
    img_original.Source = _writeableBitmap;
}

// 实时更新图像的代码
if (btn_GetviewWasClicked)
{
    // 更新buf数据到视图
    _writeableBitmap.Lock();
    IntPtr ptr = _writeableBitmap.BackBuffer;
    Marshal.Copy(buf, 0, ptr, 1200000);
    _writeableBitmap.AddDirtyRect(new Int32Rect(0, 0, width, height));
    _writeableBitmap.Unlock();

    // 更新bf数据到视图
    _writeableBitmap.Lock();
    IntPtr ptr2 = _writeableBitmap.BackBuffer;
    Marshal.Copy(bf, 0, ptr2, 1200000);
    _writeableBitmap.AddDirtyRect(new Int32Rect(0, 0, width, height));
    _writeableBitmap.Unlock();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 07:01:27