I'm using WritableBitmap to draw fast 2d graphics in WPF.
The problem is, my WritableBitmap does not match the pixel size of the Image control 1:1. When I try to make a new WritableBitmap based on size-change events of the Image control, the performance is terrible.
How can I render a WPF control's pixels 1:1 with a WritableBitmap?
You can see both WPF and Windows.Forms versions of my code on github.
The application is a tiny mini-app called SoundLevelMonitor, which monitors audio levels of applications and paints a continuously moving graph with a legend. Below is a screenshot of the Windows.Forms version. The WPF version is basically the same, except the Image is a fixed size and stretched to fit the window.
Before I started using WritableBitmap, I tried using UIElement, but the drawing performance was horrible. One problem is that triggering repaint requires InvalidateVisual()
which causes a slow re-layout. The other problem is that drawing text with DrawingContext is extremely slow.
So I found this suggestion to write to WriteableBitmap using GDI, and it actually works really well, and is SUPER fast. (the WPF version feels more responsive than the windows forms version!)
However, the WriteableBitmap is a fixed-sized backingstore which WPF is scaling up to fit in the Image control. I want the WriteableBitmap to be a 1:1 pixel backing store for the control, even when the control is resized.
I tried to use both OnRender
and LayoutUpdated
to trigger creating a new size-matched WriteableBitmap, but both of them were incredibly slow. Probably because setting Image.Source is triggering a relayout.
Any ideas?