WPF CreateBitmapSourceFromHBitmap()内存泄漏我需要逐个像素地绘制图像并将其显示在WPF中。我试图通过使用System.Drawing.Bitmap然后使用CreateBitmapSourceFromHBitmap()创建BitmapSource一个WPF图像控件来做到这一点。我在某处有内存泄漏,因为当CreateBitmapSourceFromBitmap()重复调用时,内存使用率会上升,并且在应用程序结束之前不会下降。如果我不打电话CreateBitmapSourceFromBitmap(),内存使用量没有明显变化。for (int i = 0; i < 100; i++){
var bmp = new System.Drawing.Bitmap(1000, 1000);
var source = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
bmp.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty,
System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
source = null;
bmp.Dispose();
bmp = null;}我该怎么做才能释放BitmapSource记忆?
3 回答
翻阅古今
TA贡献1780条经验 获得超5个赞
每当处理非托管句柄时,使用“安全句柄”包装器是个好主意:
public class SafeHBitmapHandle : SafeHandleZeroOrMinusOneIsInvalid{ [SecurityCritical] public SafeHBitmapHandle(IntPtr preexistingHandle, bool ownsHandle) : base(ownsHandle) { SetHandle(preexistingHandle); } protected override bool ReleaseHandle() { return GdiNative.DeleteObject(handle) > 0; }}
只要你展示一个句柄就构造一个(理想情况下你的API永远不会暴露IntPtr,它们总是返回安全句柄):
IntPtr hbitmap = bitmap.GetHbitmap();var handle = new SafeHBitmapHandle(hbitmap , true);
并像这样使用它:
using (handle){ ... Imaging.CreateBitmapSourceFromHBitmap(handle.DangerousGetHandle(), ...)}
SafeHandle基础为您提供自动一次性/终结器模式,您需要做的就是覆盖ReleaseHandle方法。
慕标琳琳
TA贡献1830条经验 获得超9个赞
我有相同的要求和问题(内存泄漏)。我实施了标记为答案的相同解决方案。但是虽然解决方案有效,但它对性能造成了不可接受的打击。在i7上运行,我的测试应用程序看到了稳定的30-40%CPU,200-400MB RAM增加,垃圾收集器几乎每毫秒运行一次。
由于我正在进行视频处理,因此我需要更好的性能。我想出了以下内容,以为我会分享。
可重用的全局对象
//set up your Bitmap and WritableBitmap as you see fitBitmap colorBitmap = new Bitmap(..);WriteableBitmap colorWB = new WriteableBitmap(..);//choose appropriate bytes as per your pixel format, I'll cheat here an just pick 4int bytesPerPixel = 4;//rectangles will be used to identify what bits changeRectangle colorBitmapRectangle = new Rectangle(0, 0, colorBitmap.Width, colorBitmap.Height);Int32Rect colorBitmapInt32Rect = new Int32Rect(0, 0, colorWB.PixelWidth, colorWB.PixelHeight);
转换代码
private void ConvertBitmapToWritableBitmap(){ BitmapData data = colorBitmap.LockBits(colorBitmapRectangle, ImageLockMode.WriteOnly, colorBitmap.PixelFormat); colorWB.WritePixels(colorBitmapInt32Rect, data.Scan0, data.Width * data.Height * bytesPerPixel, data.Stride); colorBitmap.UnlockBits(data); }
实施例
//do stuff to your bitmapConvertBitmapToWritableBitmap();Image.Source = colorWB;
结果是稳定的10-13%CPU,70-150MB RAM,垃圾收集器在6分钟运行中仅运行两次。
- 3 回答
- 0 关注
- 1270 浏览
添加回答
举报
0/150
提交
取消