My application runs CPU-heavy algorythms to edit an Image placed at a WPF window. I need the edition to be done in a background thread. However trying to edit the BackBuffer
I implemented the following, based on this answer:
In the view model, there is a property like this, that is bound to the Image source in XAML:
private WriteableBitmap cameraImage;
private IntPtr cameraBitmapPtr;
public WriteableBitmap CameraImage
{
get { return cameraImage; }
set
{
cameraImage = value;
cameraBitmapPtr = cameraImage.BackBuffer;
NotifyPropertyChanged();
}
}
Using a property means that if the WritableBitmap changes, e.g. because of resolution, it would be updated in the View and also a new IntPtr will be constructed.
The image is constructed when appropriate:
CameraImage = new WriteableBitmap(2448, 2048, 0, 0, PixelFormats.Bgr24, null);
In the update thread, a new image is copied in, e.g. using:
[DllImport("kernel32.dll", EntryPoint = "RtlMoveMemory")]
public static extern void CopyMemory(IntPtr Destination, IntPtr Source, uint Length);
you would do
CopyMemory(cameraImagePtr, newImagePtr, 2448 * 2048 * 3);
There might be a better function for this...
In the same thread, after the copy:
parent.Dispatcher.Invoke(new Action(() =>
{
cameraImage.Lock();
cameraImage.AddDirtyRect(new Int32Rect(0, 0, cameraImage.PixelWidth, cameraImage.PixelHeight));
cameraImage.Unlock();
}), DispatcherPriority.Render);
where parent
is the Control / Window with the Image.