Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
638 views
in Technique[技术] by (71.8m points)

python - Calculate screen DPI

I am using Python to build an image-rendering app that renders numpy arrays as images. I need a way to automate the calculation screen DPI, as I am generating images of the same size on different monitors (e.g., 2x2 inches). I am in Windows 10, Python 3.7.

I am not asking how to get the monitor's screen size -- like finding out if your monitor is 3000x2000 pixels (as was solved at: How do I get monitor resolution in Python?).

Rather, I want something that calculates DPI speficially, and takes into account any scale settings the user has applied that might change the DPI of their system. E.g., I have the scale set to 250%.

Following this answer at experts-exchange (https://www.experts-exchange.com/questions/21794611/Detecting-system-DPI-settings-in-Python.html), I have tried using this:

from ctypes import windll

def get_ppi():
    LOGPIXELSX = 88
    LOGPIXELSY = 90
    user32 = windll.user32
    user32.SetProcessDPIAware()
    dc = user32.GetDC(0)   
    pix_per_inch = windll.gdi32.GetDeviceCaps(dc, LOGPIXELSX)
    print("Horizontal DPI is", windll.gdi32.GetDeviceCaps(dc, LOGPIXELSX))
    print("Vertical DPI is", windll.gdi32.GetDeviceCaps(dc, LOGPIXELSY))
    user32.ReleaseDC(0, dc)
    return pix_per_inch

It seems to be the right ballpark, but returns a number that is too low. It returns 240, while my actual DPI is closer to 285.

I would prefer to avoid using a GUI framework like Qt for this, as I want to minimize overhead, but if that's the only way, then I will! If I do have to use a framework, I'd prefer PyQt5.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

While I said I wanted to avoid it, there is one very simple way to pull this off using PyQt5. The more I think about it, the more I think this could be the best solution, as it is largely platform independent:

import sys
from PyQt5.QtWidgets import QApplication
app = QApplication(sys.argv)
screen = app.screens()[0]
dpi = screen.physicalDotsPerInch()
app.quit()

Note that app.screens() returns a list of screens. In my case I only have one attached but you may have multiple, so be sure to be aware of which screen you need to get dpi from. And if you keep all this contained in a function, it won't clutter your namespace with PyQt junk.

Also, for more on QScreen (sc is a QScreen object) see this doc page:
https://doc.qt.io/qt-5/qscreen.html

There's all sorts of cool stuff you can pull from it.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...