Titanium Community Questions & Answer Archive

We felt that 6+ years of knowledge should not die so this is the Titanium Community Questions & Answer Archive

Calculate apps density pixel width & height using Titanium.Platform.DisplayCaps.dpi?

When getting the height and width of the application using: Titanium.Platform.DisplayCaps.platformWidth/platformHeight it returns the values in pixels. My app is using density pixel width's and height's so it looks consistent across various devices. Using pixel values results in unexpected layout.

Is it possible to caclulate the density pixel width & height using the Titanium.Platform.DisplayCaps.dpi value?

Thanks

— asked September 8th 2011 by Jimmy Forrester-Fellowes
  • density
  • density pixels
  • displaycaps
  • dpi
  • resolutions
0 Comments

4 Answers

  • Accepted Answer

    Jimmy, here are the functions for converting pixels to DPs and vice versa:

    function PixelsToDPUnits(ThePixels)
    {
      return (ThePixels / (Titanium.Platform.displayCaps.dpi / 160));
    }
    
    
    function DPUnitsToPixels(TheDPUnits)
    {
      return (TheDPUnits * (Titanium.Platform.displayCaps.dpi / 160));
    }
    
    — answered September 8th 2011 by Shawn Lipscomb
    permalink
    9 Comments
    • Thanks Shawn - that works a treat

      — commented September 8th 2011 by Jimmy Forrester-Fellowes
    • thanks~~ solve a hard problem for me..

      — commented February 13th 2012 by louis sherren
    • Are the 160 used within the calculation the same for HiRes and LoRes screens?

      — commented February 14th 2012 by Matthias Fliegner
    • Matthias, yes, the 160 is a constant (it's the dpi of "standard" devices, which is where DP units are equal to actual units). The Titanium.Platform.displayCaps.dpi is what changes between devices.

      — commented February 14th 2012 by Shawn Lipscomb
    • Thanks for both functions :) Just what I needed for a project where I need to width, height, top and bottom values of view elements to calculate animations and positions (doen't work with 'dp' values)

      — commented April 14th 2012 by Marco Schierhorn
    • thanks, thats works :)

      — commented August 14th 2014 by Jibran Khan
    • Titanium returns wrong dpi value for Samsung galaxy s4 and HTC one max. How to handle it?

      — commented December 29th 2014 by Namrata Bibekar
    • This is Great Answer. Thanks

      — commented March 21st 2015 by Nabeel Munawar
    • Works fine!!! Thanks a lot!!!

      — commented August 22nd 2015 by Pedro Brasileiro
  • Please be careful people,

    Shawn's answer is wrong. It will seem to work perfectly for iPhone and Android, but then it will fail for the older iPads.

    The reason is that the reference point he has taken for converting between density independent pixels and real pixels (160) is not in fact universal. If you read the docs here, you will find that there is no universal reference point for density independent pixels. On android the reference point is indeed 160, but for iPhone it varies with device.

    Quoting from the docs:
    "On iOS, a DIP corresponds to one pixel on a non-Retina display, which is 163DPI for iPhone/iPod touch and 132DPI for the iPad. A DIP corresponds to 2 pixels of width or height on a Retina display."

    So the functions need to include some kind of check based on the device and the value of Titanium.Platform.displayCaps.dpi

    A quick work around would be:

    function PixelsToDPUnits(ThePixels)
    {
        if ( Titanium.Platform.displayCaps.dpi > 160 )
              return (ThePixels / (Titanium.Platform.displayCaps.dpi / 160));
        else 
            return ThePixels;
    }
    
    
    function DPUnitsToPixels(TheDPUnits)
    {
        if ( Titanium.Platform.displayCaps.dpi > 160 )
                return (TheDPUnits * (Titanium.Platform.displayCaps.dpi / 160));
        else 
            return TheDPUnits;
    }
    

    But there could be more exceptions.

    — answered August 6th 2012 by John Hawkins
    permalink
    2 Comments
    • John, my answer was not "wrong"…it sounds like maybe it wasn't comprehensive enough to cover older iPads, but iPad wasn't even on my radar 11 months ago when I gave that answer. And to be clear, the only time that 132dpi is relevant is when you are truly writing an iPad app…not when you are running an iPhone app on an iPad.

      — commented August 6th 2012 by Shawn Lipscomb
    • Ok Shawn,

      Perhaps saying it was 'Wrong' was a little harsh. I will concede that it was merely an incomplete answer. However, nothing in the original question or your answer indicates that this is a phone only piece of code, hence it caused me a great deal of frustration until I read the documentation on DPI units in detail.

      I hope that my answer prevents other people going through the frustration I went through.

      — commented August 6th 2012 by John Hawkins
  • Check out this link.
    It will tell you how density is calculated.

    — answered September 8th 2011 by Marco Ferreira
    permalink
    1 Comment
    • Thanks for in the info Marco

      — commented September 8th 2011 by Jimmy Forrester-Fellowes
  • According to this Android Density Independece the following is a better version of all the above code -for any future use… :)

    function dipUnitsToPixels(dipUnits)
    {
      var DENSITY_SMALL_LDPI = 120;
    var DENSITY_BASELINE_MDPI = 160;
    var DENSITY_HIGH_HDPI = 240;
    var DENSITY_EXTRA_HIGH_XHDPI = 320;
    var ret;
    
    switch (Ti.Platform.displayCaps.dpi) {
    case DENSITY_SMALL_LDPI:
    ret = (dipUnits * (Ti.Platform.displayCaps.dpi / DENSITY_SMALL_LDPI));
    break;
    
    case DENSITY_BASELINE_MDPI:
    ret = (dipUnits * (Ti.Platform.displayCaps.dpi / DENSITY_BASELINE_MDPI));
    break;
    
    case DENSITY_HIGH_HDPI:
    ret = (dipUnits * (Ti.Platform.displayCaps.dpi / DENSITY_HIGH_HDPI));
    break;
    
    case DENSITY_EXTRA_HIGH_XHDPI:
    ret = (dipUnits * (Ti.Platform.displayCaps.dpi / DENSITY_EXTRA_HIGH_XHDPI));
    break;
    
    default:
    ret = dipUnits;
    }
    
    return ret;
    }
    
    function pixelsToDipUnits(pixels)
    {
    var DENSITY_SMALL_LDPI = 120;
    var DENSITY_BASELINE_MDPI = 160;
    var DENSITY_HIGH_HDPI = 240;
    var DENSITY_EXTRA_HIGH_XHDPI = 320;
    var ret;
    
    switch (Ti.Platform.displayCaps.dpi) {
    case DENSITY_SMALL_LDPI:
    ret = (dipUnits / (Ti.Platform.displayCaps.dpi / DENSITY_SMALL_LDPI));
    break;
    
    case DENSITY_BASELINE_MDPI:
    ret = (dipUnits / (Ti.Platform.displayCaps.dpi / DENSITY_BASELINE_MDPI));
    break;
    
    case DENSITY_HIGH_HDPI:
    ret = (dipUnits / (Ti.Platform.displayCaps.dpi / DENSITY_HIGH_HDPI));
    break;
    
    case DENSITY_EXTRA_HIGH_XHDPI:
    ret = (dipUnits / (Ti.Platform.displayCaps.dpi / DENSITY_EXTRA_HIGH_XHDPI));
    break;
    
    default:
    ret = dipUnits;
    }
    
    return ret;
    }
    
    — answered January 9th 2013 by Marcelino Jorge Romero
    permalink
    2 Comments
    • Sorry, but there are three problems with Jorge's code.

      1. All of those formulas evaluate to dipUnits, because all of the divisions evaluate to 1.
      2. The switch statement is an unnecessary complexity…they all evaluate to ret = (dipUnits * (Ti.Platform.displayCaps.dpi / Ti.Platform.displayCaps.dpi).
      3. Even if the formulas were corrected (ret = (dipUnits * (Ti.Platform.displayCaps.dpi / DENSITY_BASELINE_MDPI)), putting them in a switch statement is future-limiting, because when another density comes out, the switch statement doesn't allow for it.

      — commented January 9th 2013 by Shawn Lipscomb
    • omg yes you are right Shawn, what an error! My apologies…! Unfortunately i can't delete or modify the post. :( I hope none will get confused from my post.
      I didn't understand the purpose of the function i guess, once again my apologies.

      — commented January 9th 2013 by Marcelino Jorge Romero
The ownership of individual contributions to this community generated content is retained by the authors of their contributions.
All trademarks remain the property of the respective owner.