How to edit a WritableBitmap.BackBuffer in non UI thread?

前端 未结 5 778
旧时难觅i
旧时难觅i 2020-12-03 15:37

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

5条回答
  •  北海茫月
    2020-12-03 16:24

    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.

提交回复
热议问题