ADC Home > Reference Library > Technical Q&As > Graphics & Imaging > Quartz >

How can I programmatically determine the DPI of the current video mode?


Q: How can I programmatically determine the DPI (dots per inch) of the current video mode?

A: There isn't a single API to return this but you can get the required pieces of information from IOKit and Core Graphics. IOKit can tell you the physical dimensions of the monitor in millimeters while CG knows the current display resolution. Listing 1 shows a function that will return the DPI of a given display mode on a given monitor. Listing 2 shows how to use the function to determine the horizontal and vertical DPI for the main monitor in its current display mode.



//    Handy utility function for retrieving an int from a CFDictionaryRef
static int GetIntFromDictionaryForKey( CFDictionaryRef desc, CFStringRef key )
{
    CFNumberRef value;
    int num = 0;
    if ( (value = CFDictionaryGetValue(desc, key)) == NULL
            || CFGetTypeID(value) != CFNumberGetTypeID())
        return 0;
    CFNumberGetValue(value, kCFNumberIntType, &num);
    return num;
}

CGDisplayErr GetDisplayDPI(
    CFDictionaryRef displayModeDict,
    CGDirectDisplayID displayID,
    double *horizontalDPI, double *verticalDPI )
{
    CGDisplayErr err = kCGErrorFailure;
    io_connect_t displayPort;
    CFDictionaryRef displayDict;

    //    Grab a connection to IOKit for the requested display
    displayPort = CGDisplayIOServicePort( displayID );
    if ( displayPort != MACH_PORT_NULL )
    {
        //    Find out what IOKit knows about this display
        displayDict = IOCreateDisplayInfoDictionary(displayPort, 0);
        if ( displayDict != NULL )
        {
            const double mmPerInch = 25.4;
            double horizontalSizeInInches =
                (double)GetIntFromDictionaryForKey(displayDict,
                        CFSTR(kDisplayHorizontalImageSize)) / mmPerInch;
            double verticalSizeInInches =
                (double)GetIntFromDictionaryForKey(displayDict,
                        CFSTR(kDisplayVerticalImageSize)) / mmPerInch;

            //    Make sure to release the dictionary we got from IOKit
            CFRelease(displayDict);

            // Now we can calculate the actual DPI
            // with information from the displayModeDict
            *horizontalDPI =
                (double)GetIntFromDictionaryForKey( displayModeDict, kCGDisplayWidth )
                    / horizontalSizeInInches;
            *verticalDPI = (double)GetIntFromDictionaryForKey( displayModeDict,
                    kCGDisplayHeight ) / verticalSizeInInches;
            err = CGDisplayNoErr;
        }
    }
    return err;
}

Listing 1. Computing the screen DPI





double horizontalDPI, verticalDPI;
CGDisplayErr err = GetDisplayDPI( CGDisplayCurrentMode(kCGDirectMainDisplay),
                kCGDirectMainDisplay,
                &horizontalDPI, &verticalDPI );
if ( err == CGDisplayNoErr )
{
    //    do something with horizontalDPI and verticalDPI
}

Listing 2. Typical usage




[Dec 02 2002]


Did this document help you?
Yes: Tell us what works for you.
It’s good, but: Report typos, inaccuracies, and so forth.
It wasn’t helpful: Tell us what would have helped.