How to get real PPI (pixels per inch) device resolution with javascript?
some examples of device and value expected:
- iMac 27-inch: 109ppi
- iPad: 132ppi
- 19inch 1440x900 screen: 89ppi
- ...
How to get real PPI (pixels per inch) device resolution with javascript?
some examples of device and value expected:
Running a native application directly on top of the operating system is the only surefire way to acquire the physical characteristics of the client monitor stored in the EDID. No mainstream browser engine currently offers this information through any web API and will likely not in the foreseeable future. However there are several ways to approximate the density to varying levels of accuracy.
All modern browsers give hints to the pixel density via attributes like devicePixelRatio, deviceXDPI which basically tell you how much zoom the client has going on (versus 1.0x Operating System default zoom). If you're targeting only a few devices like the Apple line then you might be able to tell which one is which, although Apple doesn't leave a scrap of a clue to discern a iPad mini from a regular iPad.
Another alternative is using device databases or proprietary software that analyze the client's "user agent string" to achieve a hit-or-miss guess of the device and then looking up the DPI associated with that device if it exists in their big database. Expensive proprietary systems might have higher accuracy by leveraging complex data mining algorithms but regardless any system like this would need constant manual updating and will still remain open to client manipulation since they can just change their user agent string ("view this website in desktop mode")
It's really an unfortunate situation not having this information available. I've spent countless hours researching ANY POSSIBLE WAY to make a PPI aware Web Application.
Maybe one day someone will be able to convince the folks at WebKit or Mozilla or Microsoft to allow people to create PPI aware Web apps for augmented reality and such... Sigh
In pure JS:
function calcScreenDPI() {
const el = document.createElement('div');
el.style = 'width: 1in;'
document.body.appendChild(el);
const dpi = el.offsetWidth;
document.body.removeChild(el);
return dpi;
}
console.log(calcScreenDPI());
Related, but not an exact answer to the poster's question:
You can get the DPI of your display (and a lot of other information), if you're developing a Chrome Extension with the proper permissions using chrome.system.display.getInfo:
const info = await chrome.system.display.getInfo()
console.log(info.dpiX, info.dpiY)
It returns a DisplayUnitInfo object that tells you everything you might need to know.
Also, it's worth noting that you can get an approximate pixel density combining pieces of information provided above. However, it's unlikely this will be useful for anything but logging purposes, IMO. I say this because any pixel values you use in your DOM/JS code aren't going to be "device pixel values". They'll likely have a multiplier applied.
The trick is to alter @nikksan's answer above and multiply by window.devicePixelRatio
Note that it is going to be the same answer every single time on each device, so it's probably only worth doing once.
function calcScreenDPI() {
// Create a "1 inch" element to measure
const el = document.createElement('div');
el.style.width = '1in';
// It has to be appended to measure it
document.body.appendChild(el);
// Get it's (DOM-relative) pixel width, multiplied by
// the device pixel ratio
const dpi = el.offsetWidth * devicePixelRatio;
// remove the measurement element
el.remove();
return dpi;
}
You can create an element of 1in
of fixed height, then look at its height in pixels
createDpiTestElements()
var dpi = getDpi()
Because
[dpi] = [px/in]
So let
p
be an object's length in pixels [px]i
be that object's length in inches [in]d
be the searched DPI/PPI for that object, in pixels per inches [dpi]We get
d = p/i
So if we choose
i = 1
we get
d = p
/**
* @function
* @inner
*/
function createDpiTestElements () {
var getDpiHtmlStyle = 'data-dpi-test { height: 1in; left: -100%; position: absolute; top: -100%; width: 1in; }'
var head = document.getElementsByTagName('head')[0]
var getDPIElement = document.createElement('style')
getDPIElement.setAttribute('type', 'text/css')
getDPIElement.setAttribute('rel', 'stylesheet')
getDPIElement.innerHTML = getDpiHtmlStyle
head.appendChild(getDPIElement)
var body = document.getElementsByTagName('body')[0]
var dpiTestElement = document.createElement('data-dpi-test')
dpiTestElement.setAttribute('id', 'dpi-test')
body.appendChild(dpiTestElement)
}
/**
* Evaluate the DPI of the device's screen (pixels per inche).
* It creates and inpect a dedicated and hidden `data-dpi-test` DOM element to
* deduct the screen DPI.
* @method
* @static
* @returns {number} - The current screen DPI, so in pixels per inch.
*/
function getDpi () {
return document.getElementById('dpi-test').offsetHeight
}
Here is what works for me (but didn't test it on mobile phones):
Then I put in the .js: screenPPI = document.getElementById('ppitest').offsetWidth;
This got me 96, which corresponds to my system's ppi.
© 2022 - 2024 — McMap. All rights reserved.