Search code examples
racketdpi

High DPI support in Racket


I'm creating a simple program in Racket that imports two bitmaps and exports them in a single image. I'm having an issue with the pixel density on my MacBook because the images are non-retina. For my image processing, I'm using the 2htdp/image library.

Is there a way to set the pixel density of my racket program?


The line that exports the image is:

(save-image final-image "final.png" WIDTH HEIGHT)

I'm trying not to include too much information, but if there's anything I can add (more code, for example) to make my question more clear, please let me know.


P.S: Processing approaches this problem in the following way:

https://processing.org/reference/displayDensity_.html


Solution

  • This is not a complete answer, but perhaps it will help you to get started.

    First, you say "the images are non-retina". This might be a misconception. The word "retina" is used to describe the resolution of the screen, you happen to be using (roughly the screen is "retina" if the screen pixels are so small your eye can't see individual dots).

    However, my guess is that when you draw the loaded image on screen, it is shown at half the size, you are expecting?

    The reason for that is found in section "1.8 Screen Resolution and Text Scaling" in the docs for gui has the following to say:

    On Mac OS, screen sizes are described to users in terms of drawing units. A Retina display provides two pixels per drawing unit, while drawing units are used consistently for window sizes, child window positions, and canvas drawing. A “point” for font sizing is equivalent to a drawing unit.

    One solution is to scale the loaded image to double the size:

    (scale 2 the-loaded-image)
    

    before drawing it.

    Finally, how can a program know whether the current display is a retina display? The function get-display-backing-scale is what you need:

    (require racket/gui/base)
    (get-display-backing-scale)
    

    It will return 2.0 if the screen is retina, otherwise 1.0. If you have more than one monitor, lookup the function in the docs to see details on handling that.