ADC Home > Reference Library > Technical Q&As > Graphics & Imaging > Quartz >
Technical Q&A QA1217
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]
|