如何在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
相关产品推荐
相关产品推荐

