WPF:如何每秒30次有效地更新图像

时间:2010-03-16 14:12:43

标签: c# wpf bitmap

我正在编写一个使用组件的WPF应用程序,该组件将指针(IntPtr)返回到位图的像素(stride * height)。我事先知道位图是24位rgb,它的宽度和高度。

使用这些位图更新Image控件构成了一个视频给用户,但我不确定最有效的方法是什么,大多数情况下CPU使用率达到75%+且内存从40mb变化到500mb并且nI认为GC开始工作然后再次下降到40mm。该应用程序开始没有响应。

我该怎么办?

谢谢!

2 个答案:

答案 0 :(得分:16)

您最有可能分配新的位图,这些位图不是一次性的。您应该分配一个WriteableBitmap并更新它。链接的文档描述了锁定,更新和解锁WriteableBitmap

背后的过程

在软件上,我在WPF中使用实时超声图像,我收到一个Windows窗体位图,我使用本机CopyMemory方法直接将其复制到WriteableBitmap中。即使使用这种更复杂的工作,CPU也不会过于紧张,只要我能够正确处理我的内存,内存使用就不会发生变化。希望这个例子可以帮助你:

// DLL returns images as a WinForms Bitmap
Bitmap bmp = myClass.getWinFormsBitmap();

// In my situation, the images are always 640 x 480.
BitmapData data = bmp.LockBits(new Rectangle(0, 0, 640, 480), ImageLockMode.ReadOnly,  System.Drawing.Imaging.PixelFormat.Format32bppArgb);
this.writeableBitmap.Lock();

// Copy the bitmap's data directly to the on-screen buffers
NativeMethods.CopyMemory(this.writeableBitmap.BackBuffer, data.Scan0, ImageBufferSize);

// Moves the back buffer to the front.
this.writeableBitmap.AddDirtyRect(new Int32Rect(0, 0, 640, 480));
this.writeableBitmap.Unlock();

bmp.UnlockBits(data);

// Free up the memory of the WinForms bitmap
bmp.Dispose();

CopyMemory定义为:

[DllImport("Kernel32.dll", EntryPoint = "RtlMoveMemory")]
public static extern void CopyMemory(IntPtr Destination, IntPtr Source, int Length);

答案 1 :(得分:4)

WritePixels上使用名为WriteableBitmap的便捷方法,我们可以将其写得更短一些:

// DLL returns images as a WinForms Bitmap
// It's disposed even if an exception is thrown
using (Bitmap bmp = myClass.getWinFormsBitmap())
{
    // In my situation, the images are always 640 x 480.
    BitmapData data = bmp.LockBits(new Rectangle(0, 0, 640, 480), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
    writeableBitmap.WritePixels(new Int32Rect(0, 0, 640, 480), data.Scan0, ImageBufferSize, data.Stride);
    bmp.UnlockBits(data);
}