Я пишу приложение WPF, которое использует компонент, и этот компонент возвращает указатель (IntPtr) пикселям битового массива (шаг * высота). Я знаю заранее, что битовый массив составляет 24 бита rgb, его ширина и высота.
Обновление управления Изображением с этими битовыми массивами составляет видео пользователю, но я не уверен, что является самым эффективным способом сделать это, большую часть времени использование ЦП переходит к 75% + и память, изменяющаяся от 40 МБ до 500 МБ, и nI думают, что GC начинает работать, и затем это отбрасывает снова к 40 мм. Приложение начинает не быть быстро реагирующим.
Какой shoud я делаю?
спасибо!
Скорее всего, вы размещаете новые растровые изображения, которые не являются одноразовыми. Вы должны выделить один WriteableBitmap
и вместо этого обновить его. В связанной документации описывается процесс блокировки, обновления и разблокировки WriteableBitmap
В программном обеспечении, над которым я работаю с использованием живых ультразвуковых изображений в WPF, я получаю растровое изображение Windows Forms, которое копирую в WriteableBitmap напрямую с помощью собственный метод CopyMemory. Даже при этой более сложной работе процессор не нагружается слишком сильно, и использование памяти никогда не меняется, пока я правильно распоряжаюсь тем, что могу. Надеюсь, этот пример поможет вам:
// 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);