3

I have a GPU rendering engine that produces textures. These textures are copied into a WriteableBitmap. This Bitmap is used as an ImageSource in a normal Windows Presentation Foundation view.

Now, I set my dpi to 120, that is, I enabled the 125% font size setting in Windows Control Panel.

Since that change, the WritableBitmap looks really ugly. It is no longer pixel-perfect and looks like badly antialiased (probably because Wpf is stretching it somehow).

I played around with the following settings:

  • This answer describes how to get Dpi from Wpf, and I adjusted the WritableBitmap dpi and Width/Height values accordingly.
  • Disable UseLayoutRounding and enable SnapToDevicePixels in the XAML that contains the image.

But I cannot get it to look good. I am not sure I understand what exactly I have to set to which values in order to get pixel-perfect display. It seems to be there are multiple settings that depend on each other.

A good answer would explain how which settings have to be set in combinations so that it works as expected.

Community
  • 1
  • 1
Wilbert
  • 7,251
  • 6
  • 51
  • 91
  • Better one time [to see](http://stackoverflow.com/help/mcve), than 10 times to hear. – Sinatr Feb 17 '15 at 13:52
  • Does the last paragraph of this article help at all? https://msdn.microsoft.com/en-us/library/windows/desktop/ee308410%28v=vs.85%29.aspx – Bradley Uffner Feb 17 '15 at 14:01
  • and have you checked out this article - http://blogs.msdn.com/b/patricka/archive/2010/04/15/why-does-a-high-dpi-setting-make-my-application-look-fuzzy-and-have-clipped-text.aspx – AwkwardCoder Feb 17 '15 at 14:04

1 Answers1

3

In the xaml, set SnapsToDevicePixels to true.

In the class that sets up the WritableBitmap, query ActualWidth and ActualHeight. Then multiply those with the scale factors from Dpi (1.25 for dpi 120, etc).

var width = ActualWidth * _dpi_x_scale;
var height = ActualHeight * _dpi_y_scale;

I use those width and height value to set the size for the render texture on Gpu.

When creating the WritableBitmap, also use those scaled width/height but make sure to set the correct dpi:

_bitmap = new WriteableBitmap(
            width,
            height,
            _dpi_x, 
            _dpi_y,
            PixelFormats.Pbgra32,
            null
            );

This solves the problem.

Wilbert
  • 7,251
  • 6
  • 51
  • 91
  • 2
    But how to get dpi? – Exerion Dec 27 '16 at 10:56
  • Someone please tell us how to actual get the dpi? I've tried this: double scale = VisualTreeHelper.GetDpi(this).DpiScaleX; int dpi = 96 * scale; It appears to give the correct scale factor at program start. But if the scale changes while the program is running, the changes are not detected. Further calls to VisualTreeHelper.GetDpi() always seems to return the same result. That is in spite me changing the scale in windows settings while my program was running. Also, it should change when I drag the window to a monitor with a different scale factor. – Wayne VanWeerthuizen Oct 17 '22 at 23:12