.NET Image DPI Scaling Problems
Today I noticed that the buttons in my Windows forms app were being scaled. As you can see from the image below there is a ghosting around the edges of the lines which isn’t in the original image.
I eventually tracked this down to DPI scaling issues. I’m drawing the image using DrawImage:
System.Windows.Forms.Graphics.DrawImage
The graphics object has a correct DPI of 96, but the image DPI is 95.91039. This incorrect DPI value is what is causing the scaling.
e.Graphics.DpiY = 96 image.VerticalResolution = 95.91039
The image was created in Paint.NET so that was the first thing to check. The DPI settings can be found in the resize dialog, and it was indeed wrong.
The DPI in Paint.NET settings is correctly set to 96 so it is unclear why the DPI has been set incorrectly. So, simple fix, just change it to 96 and re-save right? Wrong. Reloading the image in Paint.NET now shows 95.99 DPI. Close but still not right. Interestingly GIMP appears to have similar accuracy problem with displaying and loading/saving the DPI. Even after this change, loading the image in .NET still shows a DPI of 95.91039.
A quick python script shows that the DPI is actually correct:
from PIL import Image image = Image.open("ScopeColourModeButton.png") print(str(image.info['dpi']))
Just to be sure let’s try re-saving the file:
image.save("ScopeColourModeButton.png", dpi=(96,96))
Unfortunately this doesn’t help either. It appears that the png is at the correct DPI (or close enough with whatever rounding is going on). The problem lies with the .NET Image class. I assume that this is a bug in the image loading code when the image is embedded into the resources file.
The only work-around I could find was to forcibly change the DPI before displaying the image
public static Image To96Dpi(Image image) { Bitmap bitmap = (Bitmap)image; bitmap.SetResolution(96.0f, 96.0f); image = bitmap; return image; } ... Image image = Utils.To96Dpi(Properties.Resources.ScopeColourModeButton);
This fixes the problem and now my button images are pixel perfect!