Why is Picture DPI and sizing different in Canvas on Windows

Forgive me, obviously I’m still relatively new to Canvas painting, but I was building a simple little utility on macOS to help me deal with Icon picture files, and when I ran the app on Windows, the drawing of the picture file in the Canvas came out smaller.

Oddly, on Windows, the code reports the Width & Height correctly (same as macOS), but the DPI on Windows says 96 whereas on macOS it it says 72 (as confirmed when I open the same file in photo editing software on both macOS & Windows).

My example is a PNG file, as are most of my Icon files.

The following is the relevant code in the Canvas Paint event:

Dim x As Int32 Dim y As Int32 Dim w As Int32 = Self.ImageReference.Width Dim h As Int32 = Self.ImageReference.Height x = (Me.Width \\ 2) - (w \\ 2) y = (Me.Height \\ 2) - (h \\ 2) // position image in center of canvas g.DrawPicture(Self.ImageReference, x, y)

I originally wrote the app in 2019r2.1, but I went back and made a sample app in 2019r1.1 to see if it was a bug of some kind, but I see the same (expected and unexpected) results in either version (regardless of macOS or Windows).

My sample app can be downloaded here https://basic.fyi/screenshots/ImageDPI.xojo_binary_project as well as the image you’ll see in the following screenshots.

Note: You can use the “Open…” button to load an image or just drag-and-drop the image to the Canvas.

Tested using Windows 10 Home and macOS High Sierra & Mojave.

Any advice or insight would be appreciated. Thanks.

Edited to add, ScaleFactor on all test machines is 1.0, native screen resolution.

Direct2D works at 96dpi, if the image doesn’t have an embedded DPI it will default to 96. Try this after your two Picture.Open’s

#If TargetWindows Self.ImageReference.VerticalResolution = 72 Self.ImageReference.HorizontalResolution = 72 #EndIf

I’ve not done a lot of hidpi work, there may be another route to this and I’ve not personally checked this for pixel perfection so someone else might be able to chip in with a more accurate answer.

Apple’s Macintosh was created at 72 dpi.
Then, later, Windows was released using 96 dpi and I never knew why.

[quote=466234:@JulianS]Direct2D works at 96dpi, if the image doesn’t have an embedded DPI it will default to 96. Try this after your two Picture.Open’s

#If TargetWindows Self.ImageReference.VerticalResolution = 72 Self.ImageReference.HorizontalResolution = 72 #EndIf

I’ve not done a lot of hidpi work, there may be another route to this and I’ve not personally checked this for pixel perfection so someone else might be able to chip in with a more accurate answer.[/quote]
Thank you Julian, worked like a charm :slight_smile:

hello scott,
With drawpicture you can adapt all pictures to your canvas
DPI does not matter then
Canvas Paint:
g.drawpicture Self.ImageReference,0,0,g.Width,g.Height,0,0,ImageReference.Width,ImageReference.height

Thank you Rudolf, that also works to get the Picture properly sized on the Canvas in Windows. I changed my call to DrawPicture to the following:

Var x As Int32 Var y As Int32 Var w As Int32 = Self.ImageReference.Width Var h As Int32 = Self.ImageReference.Height x = (Me.Width \\ 2) - (w \\ 2) y = (Me.Height \\ 2) - (h \\ 2) // position image in center of canvas g.DrawPicture(Self.ImageReference, x, y, w, h, 0, 0, w, h)

Although, without Julian’s suggestion, the image still says it’s 96 DPI, when I know the original image is 72 DPI.

It seems safe to add both changes.

Working with the Canvas is pretty interesting stuff, but up until now when I wanted to embed an image for an icon, like for a custom button, I was just assigning the image to the Canvas.Backdrop property (which appears to automatically take care of the DPI and scaling handling when using an Image Set). But now I’m trying to get more creative :slight_smile:

Thanks again to both you and Julian.