Search code examples
c#wpfimageperformance

WPF Image Control Slow to Update with Large Images


I'm trying to update an Image control in WPF whenever new image data is fetched. I'm working with 1500x1500 16-bit RAW images (~5MB each), and I'm seeing an update time of around 22ms on average, which seems slow for my use case.

Currently, I'm loading images sequentially on a background task and updating the UI like this:

while (!cancelToken.IsCancellationRequested)
{
    cancelToken.ThrowIfCancellationRequested();

    if (imageCounter > 359)
        imageCounter = 0;

    //_memoryMappedViewAccessor.ReadArray(0, imageData, 0, imageData.Length);
    string path = $"{basePath}img{imageCounter++:D4}.raw";
    frame = ImageHelper.LoadImageRaw(path, Size, Size);

    await Application.Current.Dispatcher.InvokeAsync(() =>
    {
        _writeableBitmap.Lock();
        _writeableBitmap.WritePixels(_rect, frame.Data, locStride, 0);
        _writeableBitmap.Unlock();
        ImageDisplay = _writeableBitmap;

        _frameCounter.Count();
    }, DispatcherPriority.Background, cancelToken);

}

Reading the data and writing to the WriteableBitmap takes about 2-3ms, which is expected. However, the entire update takes ~22ms, which suggests the internal redraw of the Image control is taking around 19ms for this kind of images.

I also used larger images of size 3000x3000. This resulted in a 4x slower speed (~80ms total, 8ms for loading the data), which at least seems plausible based on the relative size. In addition I noticed the image display runs much faster when starting the app with a debugger attached.

Is this performance typical for the WPF Image control with large images? Or am I doing something wrong in my approach (especially because attaching a debugger seems to speed up the image drawing which is strange) that could be optimized for faster updates?


Solution

  • I did not find a solution to update the 'Image' control faster. Instead im now using a OpenGL window thats embedded into a control, load the image as a texture and render it on a screen-filling quad. This works much better even with bigger image sizes.