1

Rephrased question:

When I draw on bitmaps from a unit test from within Visual Studio, the zoom factor I have on my desktop is taken into account, but when I run from the console it is not.

What can I do to make texts rendered using Graphics.DrawString behave consistently regardless of my desktop settings?


I have some NUnit tests that create bitmaps using GDI+ and compares them to pre-saved images to make sure that the correct image is generated.

My problem is that texts (rendered with Graphics.DrawString) are different when I run the tests from within Visual Studio, compared to what is generated when I run then tests in my command line build script (using the NUnit 3.2 test runner).

Note: it is not some minor one-pixel-off or text wrapping issue. The font size of the texts rendered while running from the console is waaay smaller.

Does anybody know why the font size would be different one the same machine depending on the execution environment? And equally important: what can I do about it?

Dan Byström
  • 9,067
  • 5
  • 38
  • 68

1 Answers1

3

A console mode app is almost never declared dpiAware. That matters when you create bitmaps, their default Horizontal/VerticalResolution property will be 96 pixels per inch regardless of what the video adapter is running at. The DPI virtualization feature takes care of that. Which in turn affects the number of pixels used for a font since by default their size is specified in points. One point is 1/72 inches, how many pixels you need to draw, say, an 9 point font depends on the pixels-per-inch ratio. It will be 9 / 72 * 96 = 12 pixels.

In a program that is dpiAware that runs on, say, a 144 dpi video adapter, that same text will be 9 / 72 * 144 = 18 pixels high. Leading you to conclude that the console mode app is making the text too small. Or the dpiAware app is making them too big, depending on your point of view.

DPI awareness or virtualization is general important, it prevents a program from creating unreadable text on a high resolution monitor. On a 4K monitor that 12 pixel high text looks but like a fleck of dust. That does not exactly apply in a console mode app that creates bitmaps. Although you might well consider to create much larger bitmaps and therefore also use larger text. Since if you don't those small bitmaps don't look very good when they have to be rescaled to match the 4K monitor. Especially noticeable for text, anti-aliasing pixels turn into boulders that don't anti-alias anymore.

If not, and you only care about sizes in pixels, you should consider avoiding this problem is by using one of the Font constructors that takes a GraphicsUnit. You would favor GraphicsUnit.Pixel instead of the default. You'll get a predictable text height in pixels regardless of the video adapter setting, a fixed proportion of the overall bitmap height.

Community
  • 1
  • 1
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • 2
    I told my colluges after posting my question; Hans Passant will explain this to us in a few minutes - and you did! :-) #hero – Dan Byström Apr 02 '16 at 15:37