I'm writing a WPF application that uses a component, and this component returns a pointer (IntPtr) to pixels of a bitmap (stride * height). I know in advance that the bitmap is a 24bits rgb, its width and height.
Updating the Image control with these bitmaps makes up a video to the user, but I'm not sure what's the most efficient way to do that, most of the time the CPU usage goes to 75%+ and memory changing from 40mb to 500mb and the nI think GC starts to work and then it drops again to 40mm. The app starts to not be responsive.
What shoud I do?
thanks!
You're most likely allocating new Bitmaps, which aren't disposable. You should allocate a single WriteableBitmap
and update that instead. The linked documentation describes the process behind locking, updating, and unlocking a WriteableBitmap
On software I work on using live ultrasound images in WPF, I am receiving a Windows Forms Bitmap, which I copy into the WriteableBitmap directly using the native CopyMemory method. Even with this more complicated work, the CPU isn't strained too hard, and the memory usage never moves as long as I properly dispose what I can. Hopefully this example can help you:
// 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();
Where CopyMemory is defined as:
[DllImport("Kernel32.dll", EntryPoint = "RtlMoveMemory")]
public static extern void CopyMemory(IntPtr Destination, IntPtr Source, int Length);
Using the convenience method called WritePixels
on WriteableBitmap
we can write it a bit shorter like so:
// 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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With