I've been reading the following: http://developer.android.com/guide/practices/screens_support.html
It's about the folders res-long-land-hdpi, res-notlong-land-dpi, res-notlong-port-ldpi etc. And what they actually mean and when they should be used.
The article also says the following:
xlarge screens are at least 960dp x 720dp
large screens are at least 640dp x 480dp
I'm developing for a device that is: 1280 x 720 and one that is 480 x 800
My app will only be available in portrait mode.
So that means i have to put images in the res-long-port-hdpi folder for the first device, and in res-notlong-port-ldpi for the second device right?
Then the next problem i have with this is. I have an image which is 332 x 226 pixels. This looks fine on the first (xlarge) device. But to what size do i have to rescale this image so that i can place it in the (lower resolution) res-xx-xx-ldpi folder?
I'm not sure how to calculate the new sizes for the different folders.
The size ratios should match the nominal pixel densities as Android defines them:
ldpi - 120 pixels/inch; dpi scale = .75 (4 dpi = 3 pixels)
mdpi - 160 pixels/inch; dpi scale = 1 (1 dpi = 1 pixel)
hdpi - 240 pixels/inch; dpi scale = 1.5 (2 dpi = 3 pixels)
xhdpi - 320 pixels/inch; dpi scale = 2 (1 dpi = 2 pixels)
So if you make your xhdpi images twice the size (in pixels) of the mdpi resources, they will be the same dpi, meaning they will be the same physical size on their respective screens.
Related
I have design for my project. It for Nexus 6 with resolution 1440px x 2560px and 493 ppi. My design - 1440px x 2560px.
I know that:
ldpi 120 dpi
mdpi 160 dpi
tvdpi 213 dpi
hdpi 240 dpi
xhdpi 320 dpi
xxhdpi 480 dpi
xxxhdpi 640 dpi
I have - 493 ppi. what's this? I have a button size 100x50 pixels on the design.
how many dpi need button to look as well as in the design?
Hope this helps: Getting Your Apps Ready for Nexus 6 and Nexus 9
Nexus 6
Screen
The Nexus 6 boasts an impressive 5.96” Quad HD screen display at a
resolution of 2560 x 1440 (493 ppi). This translates to ~ 730 x 410 dp
(density independent pixels).
Check your assets
It has a quantized density of 560 dpi, which falls in between the
xxhdpi and xxxhdpi primary density buckets. For the Nexus 6, the
platform will scale down xxxhdpi assets, but if those aren’t
available, then it will scale up xxhdpi assets.
EDIT:
Consider this line
2560 x 1440 (493 ppi). This translates to ~ 730 x 410 dp (density
independent pixels)
It implies the scaling factor is 2560/730 = 1440/410 ~ 3.5
For a screen of width 410 and height 730 in dp, if you want to specify a button of half the screen width in dp, the width should be 410/2 = 205 dp which translates to 717px = 205*3.5 (width in dp * scaling factor)
A button of size 100px x 50px would translate to 28 x14 dp (100/3.5 * 50/3.5) on a 410 x 730 dp screen size.
If you are genuinely concerned about proper display resolution (which it sounds like you are) then you should never rely on the generic folders. The folders are there for generalized purposes - not for customized or high value display.
You should use displayMetrics to measure the screen size and select the appropriate asset, or even do customized image scaling. There are a lot of resources around this set of properties, but essentially it allows you to address the issue you are facing: set appropriate margins, padding, resolution, layout, etc. for a highly customized display.
Here are the docs:
http://developer.android.com/reference/android/util/DisplayMetrics.html
And then some "simple" implementations of getting the metrics:
How to get screen display metrics in application class
getting the screen density programmatically in android?
Through as Supporting Different Densities , there are 4 types of screens :
xhdpi
hdpi
mdpi
ldpi
I want to know WHAT IS EXACTLY SCREEN SIZE ( in PIXEL ) of these ? :
normal-xhdpi large-xhdpi
normal-hdpi large-hdpi
normal-mdpi large-mdpi
These screen sizes is given by Eclipse :
xhdpi : 768 x 1280
2560 x 1600
720 x 1280
hdpi : 480 x 800
480 x 854
mdpi : 1280 x 800
1024 x 600
480 x 854
480 x 800
320 x 480
See you are mixing the concepts. small,medium,large and xlarge are screen sizes whereas ldpi,mdpi,hdpi , xhdpi,nodpi and tvdpi are screen densities
According to Android Developer's website
SIZE
small - Resources for small size screens.
normal - Resources for normal size screens. (This is the baseline size.)
large - Resources for large size screens.
xlarge - Resources for extra large size screens.
Density
ldpi Resources for low-density (ldpi) screens (~120dpi).
mdpi Resources for medium-density (mdpi) screens (~160dpi).
(This is the baseline density.)
hdpi Resources for high-density (hdpi) screens (~240dpi).
xhdpi Resources for extra high-density (xhdpi) screens (~320dpi).
nodpi Resources for all densities. These are density-independent resources.
The system does not scale resources tagged with this qualifier,
regardless of the current screen's density.
tvdpi Resources for screens somewhere between mdpi and hdpi; approximately
213dpi. This is not considered a "primary" density group. It is mostly
intended for televisions and most apps shouldn't need it—providing mdpi and
hdpi resources is sufficient for most apps and the system will scale them as
appropriate. If you find it necessary to provide tvdpi resources,
you should size them at a factor of 1.33*mdpi.
For example, a 100px x 100px image for mdpi screens should be 133px x 133px for tvdpi.
Now the minimum resolution of each size is defined below
xlarge screens are at least 960dp x 720dp
large screens are at least 640dp x 480dp
normal screens are at least 470dp x 320dp
small screens are at least 426dp x 320dp
Also from the android Docs
The conversion of dp units to screen pixels is simple: pixels = dps * (density / 160). For example, on 240 dpi screen, 1 dp would equal 1.5 physical pixels. Using dp units to define your application’s UI is highly recommended, as a way of ensuring proper display of your UI on different screens.
Which means two different devices with different densities can have the same number of dp but not same pixels.
This Formula worked for me to get the screen size and convert them into pixels :
float scale = getBaseContext().getResources().getDisplayMetrics().density;
int pixels = (int) (120 * scale + 0.5f);
In iOS preparing graphics is simple. There are either a normal image (height x width) or a retina image which is #2x (2 times height x 2 times width).
However, since I'm new to Android, I see a ton of drawable-* folders in Eclipse where the * can be "hdpi" or "ldpi" or "mdpi" or "xhdpi" or "xxhdpi". Can someone very clearly and simply list for me what I must do to satisfy each of the display possibilities so my images will look right in each instance? I'm envisioning an answer will be a bullet list with each "*" listed and a sub-bullet list including the things that must be done.
I'd also really enjoy an answer that would start with the highest density and greatest dimension image and working down since I'll be creating in Photoshop and will be reducing quality from a master image.
i got this off of this site a while back, it still comes in handy
xlarge screens are at least 960dp x 720dp
large screens are at least 640dp x 480dp
normal screens are at least 470dp x 320dp
small screens are at least 426dp x 320dp
Generalised Dpi values for screens:
ldpi Resources for low-density (ldpi) screens (~120dpi)
mdpi Resources for medium-density (mdpi) screens (~160dpi). (This is the baseline density.)
hdpi Resources for high-density (hdpi) screens (~240dpi).
xhdpi Resources for extra high-density (xhdpi) screens (~320dpi).
Therefore generalised size of your resources (assuming they are full screen):
ldpi
Vertical = 426 * 120 / 160 = 319.5px
Horizontal = 320 * 120 / 160 = 240px
mdpi
Vertical = 470 * 160 / 160 = 470px
Horizontal = 320 * 160 / 160 = 320px
hdpi
Vertical = 640 * 240 / 160 = 960px
Horizontal = 480 * 240 / 160 = 720px
xhdpi
Vertical = 960 * 320 / 160 = 1920px
Horizontal = 720 * 320 / 160 = 1440px
px = dp*dpi/160
In Android Studio just go to File -> New -> Image Asset and create your images right out of the IDE.
On Android we usually handle image sizes in units of "dp" or "dip" which stands for device independent pixel. 1 dip = 1 pixel, on a mdpi screen. There are loads of devices out there with different screen densities, not just normal and retina, so there are multiple DPI buckets a device's screen may fall into:
ldpi (low dpi): around 120 dpi
mdpi (medium dpi): around 160 dpi
hdpi (high dpi): around 240 dpi
xhdpi (xtra high dpi): around 320 dpi
Note that these are buckets, so a device with a 170 dpi screen will count as an mdpi device.
Let's say that you have a vector based image in PS and you need to create an image resource for Android and you'd like to support all these screen densities. Let's say that image needs to be 100x100 dip large. So you create a 100x100 pixel version for mdpi, a 150x150 pixel version for hdpi, 200x200 for xhdpi, and 75x75 for ldpi. You can think of "mdpi - xhdpi" on Android as "normal - retina" on iOS.
As for the larges image size that you can use, I really can't say. There's no hard limit as far as I know, but the device obviously won't be able to load a 20000x20000 bitmap into memory without downsampling because of heap limits.
There is an online tool for that Android Asset Studio
And also there is File|New|Android Icon Set in Eclipse
Have read the doc which is lengthy and still not clear.
Assuming I have an image with size = 120px * 80px, under the default mdpi/160 density, I also need to prepare
ldpi = 90 * 60
hdpi = 180 * 120
xhdpi = 240 * 160
Are the calculation above right? Assume I only have a single layout, so what I need is to prepare the images and place them under the corresponding drawable folders, right?
Thanks
The image sizes you have calculated are correct based on the formula from Google:
pixels = dp * (density / 160)
Knowing the target densities of the various DPIs will allow us to calculate final image sizes:
ldpi = 120 DPI
mdpi = 160 DPI
hdpi = 240 DPI
xhdpi = 320 DPI
Here would be the correct calculation for width, starting with a medium density asset at 120 pixels wide:
ldpi (120 DPI) = 120 * (120 / 160) == 90
mdpi (160 DPI) = 120 * (160 / 160) == 120
hdpi (240 DPI) = 120 * (240 / 160) == 180
xhdpi (320 DPI) = 120 * (320 / 160) == 240
Here would be the correct calculation for height, starting with a medium density asset at 80 pixels tall:
ldpi (120 DPI) = 80 * (120 / 160) == 60
mdpi (160 DPI) = 80 * (160 / 160) == 80
hdpi (240 DPI) = 80 * (240 / 160) == 120
xhdpi (320 DPI) = 80 * (320 / 160) == 160
Making your final images:
ldpi = 90 x 60
mdpi = 120 x 80
hdpi = 180 x 120
xhdpi = 240 x 160
Create the following folders under res/ if they don't already exist and drop the correct assets in:
drawable-ldpi
drawable-mdpi
drawable-hdpi
drawable-xhdpi
Yes, those are the correct sizes.
Yes, just put your various versions in the res/drawable-ldpi, -mdpi, -hdpi, and -xhdpi
folders and you're done.
Depending on your image -- specifically whether it still looks good scaled down automatically -- you could just provide hdpi and xhdpi versions and Android will automatically scale them at run-time for ldpi and mdpi respectively.
Edit: Ok, the calculations are correct. According to the formula px = dp * (dpi / 160) from http://developer.android.com/guide/practices/screens_support.html, where pixels on mdpi = dp.
And here is some additional information:
Dpi tells you how much dots (pixels) are in 1 inch. But it doesn't tell you how much pixels the screen has in total. So, you can have a device, which has, let's say, 400 pixels width and height and the screen has a diagonal of 5 inches. With this you get the dpi value. (Using http://members.ping.de/~sven/dpi.html for example).
Now you have another, device, which has the same dpi value, but has a higher resolution and it's bigger, for example, 1000 x 1000 pixels and also large diagonale.
If you created an image for the first case, of let's say 200 x 200 pixels, it will occupy half of the screen, but in the second case it will be only 1/5 of the screen, although both devices having same dpi, and that's probably not what you want to do.
What I usually do is orientate on the resolution of devices which usually have this dpi (like hdpi -> 480x800, xhdpi -> 720x1280, etc.), and in the layout use dip in combination with scaleType "fitStart", "center", etc. to keep the images proportional. So I put images with different resolutions in ldpi, hdpi and xhdpi folders but I don't use a formula.
There's also the possibility to use screen sizes in combination/instead with dpi, in the case it's necessary:
xlarge screens are at least 960dp x 720dp
large screens are at least 640dp x 480dp
normal screens are at least 470dp x 320dp
small screens are at least 426dp x 320dp
This works with additional folders like dpi.
BTW. Currently it's possible to put different versions of the app in Google Play for different resolutions / screens, so the user doesn't have to download all the files (huge app size, long time downloading, etc.), only the ones necessary for the device.
the scaling ratio of images for the ldpi,mdpi,hdpi,xhdpi is 3:4:6:8 but u think once
1)if there is mobile with ldpi small screen is there then it will be suitable for the screen.
2)if there is mobile with ldpi medium screen is there then the images appear little bit smaller
3)2)if there is mobile with ldpi large screen is there then the images appear smaller.
like this for all the mdpi,hdpi and xhdpi screens.
If there is chance of using nine patch images in your app try those images.
Yes, the calculations on the sizes that you have made are correct.
Now, you need to put them in the respective folders of ldpi , mdpi , hdpi and xhdpi in res/drawable of your project.
Your calculations are correct if your goal is for your image to have (approximately) the same physical size on devices of different pixel densities. The images would go in directories
res/drawable-ldpi
res/drawable-mdpi
res/drawable-hdpi
res/drawable-xhdpi
Android classifies the device into one of these general density classes (which are 120dpi, 160dpi, 240dpi, and 320dpi) and scales images according to those ratios. Since physical devices aren't necessarily exactly one of these densities, the physical size of the image can still vary slightly from device to device. Note that if you don't supply an image for a particular density, Android will generate one by scaling the default/mdpi image. Generally, the result isn't quite to the quality that you would get by providing your own image.
If you run Android Lint, it will tell you about any missing resources (such as forgetting to include a xhdpi image) and it will also tell you if your scaling calculations are substantially off. It's a nice feature to know about.
Note that this entire image scaling approach has nothing to do with screen size, only pixel density. You can also have resource folders for different screen sizes or even for different screen size/density combinations.
However, if you want an image that will display at 120 x 80 pixels regardless of the screen density, the above scheme won't work. Instead, you should put the image in the folder
res/drawable-nodpi
Android won't scale images that it retrieves from there. The result is that your image would be about 3/4" x 1/2" on an mdpi device, 1" x 3/4" on an ldpi device, 3/8" x 1/4" on an xhdpi device, etc.
You can use this to calculate equivalent size in pixels if you know the screen density(dpi) of the device:
equivalentPixels = sizeInDP*(screenDensity/160)
where sizeinDP is the size of widget where you want to display the image. Calculate the sizes in pixels for various screen densities and put them under respective folders.
So if you have an ImageView of size 300dp X 200dp (Width X Height), and the screen density is 320dpi, the image size in pixels should be:
Width = 300*(320/160) = 600px
Height = 200*(320/160) = 400px
Hope this helps!
I have started making graphics for my Android app using Adobe Photoshop. But I am unable to proceed, as the resolution in Photoshop is set in pixels per inch where as the official Google documentation says Android will require images set in dpi. I have searched the web for the conversion between the two but never ended up with any proper formula.
I know that the Android documentation describes the relation as px = dp*dpi/160. But my problem is that if I know dpi where do I get the value of dp to be used in this calculation? Or is there any assumption about the value of dp? I am confused.
Dp are Density independant pixels and are used to generalise the number of pixels a screen has. These are generalised figures taken from http://developer.android.com/guide/practices/screens_support.html
xlarge screens are at least 960dp x 720dp
large screens are at least 640dp x 480dp
normal screens are at least 470dp x 320dp
small screens are at least 426dp x 320dp
Generalised Dpi values for screens:
ldpi Resources for low-density (ldpi) screens (~120dpi)
mdpi Resources for medium-density (mdpi) screens (~160dpi). (This is the baseline density.)
hdpi Resources for high-density (hdpi) screens (~240dpi).
xhdpi Resources for extra high-density (xhdpi) screens (~320dpi).
Therefore generalised size of your resources (assuming they are full screen):
ldpi
Vertical = 426 * 120 / 160 = 319.5px
Horizontal = 320 * 120 / 160 = 240px
mdpi
Vertical = 470 * 160 / 160 = 470px
Horizontal = 320 * 160 / 160 = 320px
hdpi
Vertical = 640 * 240 / 160 = 960px
Horizontal = 480 * 240 / 160 = 720px
Edit - adding xhdpi as they are becoming more popular
xhdpi
Vertical = 960 * 320 / 160 = 1920px
Horizontal = 720 * 320 / 160 = 1440px
These values should be suitable for most xhdpi screens such as TVs and the Nexus 4, including the Nexus 10 (assuming they don't create a new category for this as it is 25k x 16k, don't know as I haven't got hands on one yet).
/Edit
If you use these sizes your images will look great on any screen. Be sure to define sizes in code in dp however, Android will handle the conversion described above on its own.
I don't agree with answer by Michael Allen because the resulting resolutions for ldpi, mdpi, hdpi and xdpi doesn't satisfy the 3:4:6:8 scaling ratios for alternative bitmaps mentioned in the google docs here under 'Alternative Drawables'
http://developer.android.com/guide/practices/screens_support.html#testing
Therefore I would suggest that you take the baseline example that has a minimum size of
470 x 320 dp now using formula from same documentation we calculate full screen resolution for baseline screen size
px = dp * (dpi/160); for baseline px = dp * (160/160) = dp * 1
so px = dp. This means the full screen size for our baseline config. in pixels would be
470 X 320 px (mdpi)
now to follow the 3:4:6:8 scaling ratios for alternative drawables sizes for ldpi, hdpi and xhdpi we need to derive the unit values from mdpi. i.e.
470/4 = 117.5
320/4 = 80
divide by 4 because scaling ratio for mdpi is 4, scaling ratios for ldpi, hdpi and xhdpi are 3,6 and 8 respectively. now just multiply the unit results 117.5 and 80 with these scaling factors
ldpi
117.5 * 3 = 352.5
80 * 3 = 240
mdpi
117.5 * 4 = 470
80 * 4 = 320
hdpi
117.5 * 6 = 705
80 * 6 = 480
xhdpi
117.5 * 8 = 940
80 * 8 = 640
These sizes are now in perfect 3:4:6:8 scaling ratios.
Yes, Dp (Density independant pixels) is all Photoshop will care about. It should not consider what the density of the pixels will be. That image of a super high number of pixels may be put on a super small high definition UI button for all it cares about. Or you may have few pixels for a retro style A0 poster of Tetris. This is because they can get scaled. Few pixels are scaled up for the large area, and many pixels scaled down for the small area on a screen.
So pick your target link to sizes screen size and use that in photoshop. (also check out who uses what... pie chart of sizes used)
For the intuition this site helped me link to blog page:
At run time, the platform transparently handles any scaling of the dp units needed, based on the actual density of the screen in use.
(the platform does the scaling- the density ratio handling is done by Android; not you) and this is extremely relevant to the UI:
Using dp units to define your application’s UI is highly recommended, as a way of ensuring proper display of your UI on different screens.
Because you want the UI elements to appear the same on all devices so it will do scaling based on the number of pixels it computes in that formula. And if the dp is scaled in a way so that it becomes too spare or dense, well that won't look good.
As the resolution in Photoshop is set in pixels per inch where as the official Google documentation says Android will require images set in dpi.
The same on all devices so it will do scaling based on the number of pixels it computes in that formula.