8

Can anyone think of a way I can discover a users pixels per inch? I want to ensure that a image displays in a web browser exactly the size I need it to, so using a combination of resolution (which I can get from the user agent) and pixels per inch I could do this.

However, I'm not sure if there is any way to discover a users pixels per inch, ideally using JavaScript or some other non-invasive method.

Any suggestions?

Thanks,

CJ

Caroline
  • 1,582
  • 3
  • 16
  • 30
  • 5
    Might be hard. I've never in my life used a computer in which the DPI was set to the correct, real life DPI of the screen. Of course if your specific audience generally does have it correct, then that's ok. – Bart van Heukelom Feb 17 '10 at 16:17
  • @Bart: I have, but I set them up myself (and use Linux, which is more able to cope with the truth than Windows) – Andrew Aylett Feb 17 '10 at 16:23
  • I think the ruler idea is most promising although a bit of a pain for your users, if they are viewing lots of images you could just show the ruler the first time and maintain their setting. Also perhaps you could add to your question why you need this. – PeteT Feb 23 '10 at 16:30
  • Possible duplicate of [Detecting the system DPI/PPI from JS/CSS?](http://stackoverflow.com/questions/279749/detecting-the-system-dpi-ppi-from-js-css) – Endless Mar 11 '16 at 15:03

5 Answers5

7

You could use the following javascript function to get the DPI.

<script type="text/javascript">
   var dpi = {
      v: 0,
      get: function (noCache) {
         if (noCache || dpi.v == 0) {
            e = document.body.appendChild(document.createElement('DIV'));
            e.style.width = '1in';
            e.style.padding = '0';
            dpi.v = e.offsetWidth;
            e.parentNode.removeChild(e);
         }
         return dpi.v;
      }
   }

    alert(dpi.get(true));  // recalculate
    alert(dpi.get(false)); // use cached value
</script>

However, I think it will always return 96 on windows machines.

As far as I know, there is no way for the operating system to determine the actual physical dimensions of the viewport. So, it might very well be that it is actually impossible for software to know the real-life DPI.

However, professionals is certain branches make sure that the on screen DPI matches the real-life DPI. In those case the above javascript would probably be sufficient.

Note:
Tested the above code in Opera 9, IE6 & 7 and Firefox 3.6 on WinXP and Win2k.

Update:
Added the noCache param. But I doubt it will have any effect. I tested it with zoom in FireFox and Opera on the above mentioned windows versions and they keep quoting the DPI as '96', regardless of the amount of zoom. Would be interesting to see what mobile devices make of this.

Jacco
  • 23,534
  • 17
  • 88
  • 105
  • 1
    Per the original poster's comment below about mobile browsers: Bear in mind that mobile phone browsers allow users to zoom in and out, so the DPI will be an extremely dynamic value. It may not make sense to cache the value calculated for the DPI. – Dancrumb Feb 22 '10 at 21:09
  • @Dancrumb: This also applies to desktop browsers. Many of the new browser versions have zoom functionality. Opera was very early with this, and now others have followed. – awe Feb 23 '10 at 11:17
  • Thanks Dan I will be doing some testing with this, I was hoping that something of this sort would be possible :) – Caroline Feb 23 '10 at 17:18
  • -1 Returned 96 for me. Using http://www.swell3d.com/2008/07/how-many-pixels-per-inch-lets.html, I have 128 pixels per inch. Unless I am confused, this answer is not accurate. – antony.trupe Oct 14 '12 at 03:25
  • @antony.trupe, read the note, on windows it will always return 96. – Jacco Oct 15 '12 at 05:47
5

You could do as the drawing packages of old did, and display a stretchable ruler. Have your users drag the virtual ruler until it matches a physical ruler they've put against the screen.

Not a serious suggestion for production use, but probably the only way to actually get the right answer :(.

Andrew Aylett
  • 39,182
  • 5
  • 68
  • 95
  • 1
    I think this is the only method that will actually work. But it is not very practical. – Jacco Feb 22 '10 at 17:09
1

The safest and easiest would be to tell the browser what size you want the image. CSS supports inch and metrics, so you could specify the image like any of these examples:

<img src="image.png" style="width:15cm;height:10cm;" alt="Centimeters" />
<img src="image.png" style="width:5.9in;height:3.9in;" alt="Inches" />
<img src="image.png" style="width:150mm;height:100mm;" alt="Millimeters" />
awe
  • 21,938
  • 6
  • 78
  • 91
  • I just tried this in firefox on windows, although the units are valid they don't seem to work correctly. On my monitor it was roughly 1.5cm specified = 1cm actual. I don't know what it will be like in other browsers. – PeteT Feb 23 '10 at 16:24
  • This is not working at all. The browser will use the default dpi for the operating system for this. – Jacco Feb 23 '10 at 16:42
  • Thanks for the interest and testing that idea - v. helpful to me and a real shame something that simple and intuitive doesn't work :( Thanks for the idea though! – Caroline Feb 23 '10 at 17:17
  • The solution you have accepted relies on setting style using inch just like my solution. The only difference is that I use the style setting to set the size directly on the image, and jacco use the same style to calculate the dpi. I tested my solution in IE 8, Chrome 4, Firefox 3.5.8 and all displayed the same size. When I measured, it was about 1-2mm wrong. My operating system is Windows Vista. I also tried Jacco's method to get the dpi, and then used the result to calculate the image sizes and set them on an image using javascript. The measured size was exactly the same as with my solution! – awe Feb 24 '10 at 11:19
  • Conclusion: If all you need to do is set the image size, use my method (it's simpler). If you need the DPI value for other things as well, use Jacco's method. If this is not good enough, I think you have to go with the ruler suggested by Andrew Aylett. – awe Feb 24 '10 at 11:41
0

Displays today support 96px/inch or 72pixels/inch .

You can get the HTTP request User-Agent header

User-Agent: Mozilla/5.0 (Linux; X11)

this one will tell you the operating system and from here you can make a decision.

Elzo Valugi
  • 27,240
  • 15
  • 95
  • 114
  • I'm also thinking about mobile phone browsers though, and these have far higher levels of and more varied ranges of px/inch hence I was wondering if there's any programmatic way of doing this. – Caroline Feb 17 '10 at 16:00
  • They've standardised on pretending that, but the actual displays may vary quite a bit -- for example, my netbook has a real DPI of ~170, and my desktop here at work of ~90. Think about it: when you get both 17" and 19" monitors with the same resolution, the actual DPI can't be the same :). – Andrew Aylett Feb 17 '10 at 16:22
0

This may be very tough - even if you somehow manage to scale the rendered image based on dpi, how do you prevent the user from scaling the image in his browser directly?

Have you considered some rich interface technologies like flash or Silverlight? They may give you additional options.

Marek
  • 10,307
  • 8
  • 70
  • 106