如何以编程方式获取屏幕 DPI(Linux、Mac)?

10

我需要知道Linux和Mac OS上的屏幕DPI(每英寸像素数)。在Linux上,我认为xlib可能会有帮助,但我找不到获取当前DPI的方法。我想要这个信息来获取真实的屏幕尺寸(以英寸为单位)。

提前感谢!


4
请注意,这个东西要小心。DPI信息通常是不可靠的,驱动程序可能会出错,显示器的EDID信息有时也可以错误地提供信息。确保有覆盖方式。 - bobince
5个回答

9
在Mac上,使用CGDisplayScreenSize函数获取屏幕尺寸(单位为毫米)。

6
在Linux中,使用XOpenDisplay()调用以获取Display,然后结合DisplayWidthMM()DisplayHeightMM()DisplayWidth()DisplayHeight()来计算DPI。
在Mac上,肯定有比X更本地化的API可用。Mac OS X默认不运行X Window,它具有本地窗口环境。

在现代X服务器上,RandR扩展将提供更好的信息。 - elmindreda
FYI Windows的答案 - Brian Cannard
FYI:使用X11时,硬件DPI经常会被错误计算(特别是当有多个屏幕与X11连接时...)-编写应用程序时,您应该尽量遵守用户请求的设置-请参阅Xft.dpi。 - totaam

4

我从xdpyinfo中拼凑出了这个程序... 编译命令:gcc -Wall -o getdpi getdpi.c -lX11

/* Get dots per inch 
 */
static void get_dpi(int *x, int *y)
{
    double xres, yres;
    Display *dpy;
    char *displayname = NULL;
    int scr = 0; /* Screen number */

    if( (NULL == x) || (NULL == y)){ return ; }

    dpy = XOpenDisplay (displayname);

    /*
     * there are 2.54 centimeters to an inch; so there are 25.4 millimeters.
     *
     *     dpi = N pixels / (M millimeters / (25.4 millimeters / 1 inch))
     *         = N pixels / (M inch / 25.4)
     *         = N * 25.4 pixels / M inch
     */
    xres = ((((double) DisplayWidth(dpy,scr)) * 25.4) / 
        ((double) DisplayWidthMM(dpy,scr)));
    yres = ((((double) DisplayHeight(dpy,scr)) * 25.4) / 
        ((double) DisplayHeightMM(dpy,scr)));

    *x = (int) (xres + 0.5);
    *y = (int) (yres + 0.5);

    XCloseDisplay (dpy);
}

我将这段代码复制到文件中并尝试在OS X上编译,但是出现了一些错误:http://hastebin.com/ocikivubed.pas。有什么建议吗? - trusktr

2
你可以使用NSScreen来获取连接显示器的像素尺寸,但这并不能提供显示器的物理尺寸/像素密度,并且实际上我认为没有任何可靠的API能够做到这一点。
你可以像下面这样询问窗口的分辨率:
NSDictionary* deviceDescription = [window deviceDescription];
NSSize resolution = [[deviceDescription objectForKey:NSDeviceResolution] sizeValue];

目前这将为您提供所有屏幕的NSSize,其大小为{72, 72},无论它们的实际PPI是多少。唯一可以改变此值的事情是在Quartz Debug实用程序中更改缩放因子,或者如果苹果公司开启了分辨率独立的UI。您可以通过调用以下代码来获得当前比例因子:

[[NSScreen mainScreen] userSpaceScaleFactor];

如果你真的需要知道确切的分辨率(我很想知道你为什么认为你需要它),你可以创建一个屏幕校准程序,让用户使用实际的物理尺子测量屏幕上的一条线。虽然粗略,但它会起作用。


这是因为回答这个问题是不可能的,这也是我的回答所说的。你无法仅通过软件获得物理上准确的显示测量值。我认为我的回答不应该被评为-1。 - Rob Keniger

1
这是一种跨平台获取屏幕DPI的方法:
// Written in Java
import java.awt.Toolkit;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.border.EmptyBorder;

public final class DpiTest {

    public static void main(String[] args) {
        JFrame frame = new JFrame("DPI");
        JLabel label = new JLabel("Current Screen DPI: " + Toolkit.getDefaultToolkit().getScreenResolution());
        label.setBorder(new EmptyBorder(20, 20, 20, 20));
        frame.add(label);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }

}

你可以从这里下载已编译的jar文件。下载后,java -jar dpi.jar将显示DPI。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接