I have an ImageView with these attributes:
android:layout_width="match_parent"
android:layout_height="160dp"
UI developer asks me for the size of Image that I want in px. What size should I ask? Should I ask different size for different devices?
Note
I don't have an ImageView with specific height and width. My ImageView width is match_parent not a specific width.
All the answers say that I should use a converter, How can I convert match_parent to px?
According to answers, I should ask about six images, shouldn't I?
You should give highest screen density in pixels to your UI developer then scale to lower densities on your own.
Normally an android app will support screen densities ldpi at min and xxxhdpi at max.
Step1: If you want the image size is 160 x 160 dp then give the UI developer the highest image size associated with max screen density.
160 x 4 = 640x640 px (why multiply by 4? I will explain later)
Step 2: Scale the image 640x640 px to lower size based on screen densities
ldpi: 160 x 0.75 = 120x120 px
mdpi: 160 x 1 = 160x160 px
hdpi: 160 x 1.5 = 240x240 px
xhdpi: 160 x 2 = 320x320 px
xxhdpi: 160 x 3 = 480x480 px
xxxhdpi: 160 x 4 = 640x640 px
Tips: Find your image size corresponds with mdpi density screen (known as base density or 1X density) then scale to other densities by the following formula
Update: From https://material.io/tools/devices/, screen size for base density screen is 360x640 px. So your ImageView size will be 360x160 px on 1X density screen.
ldpi: 270x120 px
mdpi: 360x160 px
hdpi: 540x240 px
xhdpi: 720x320 px
xxhdpi: 1280x480 px
xxxhdpi: 1440x640 px
Why are you not using Vector drawable?
Why use Vectors?
Data can be represented in original resolution without generalization.
Graphical outputs of the images are more pleasing than the created as raster image
Another very important reason of using vector graphics rather than raster is their size. Vector objects are much smaller than raster image format. If we have the full-size image to update, the vector file might only take few kilobytes of space on your system, where the same image in medium resolution bitmap format might not place on CD ROM.
You should use SVG images in your project.
Create SVG instead of PNG files
Ok, you want to set image height of size 160dp (since it is in dp, this is the size in mdpi). So you to have to ask UI developer to make you image of height 4 times of that. Image Height = 4 * 160. After that you can use Batch drawable importer from android studio, to make image for all differrent resolutions. Hope it helps.
Different Devices has Different sizes
android:adjustViewBounds="true" is automaticaly pickup height of image
so you can this,
<ImageView
android:id="#+id/ivImage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"/>
You should go with 1440x640 for largest size.
If you want to support multiple devices with multiple images you can have 5 standard image slicings.
mdpi : 360x160
hdpi : 540x240
xhdpi : 720x320
xxhdpi : 1080x480
xxxhdpi : 1440x640
I came up with these image sizes, because if you look at most common display sizes, largest of them is 1440x2960 of Samsung Galaxy S8. (I am aware of 2160x3840, but it is not main stream and I would even say its outright crazy).
In your case you have width set to match_parent which in every case of largest (or even custom) DPI, will be 1440px at most, so you can be damn sure that 99% of the time it will not exceed it. (Most current devices with 9:18 or 9:X ratio devices also feature 1440 px width in almost every case if they go more than 1080. Check out resolutions of latest devices released.)
So you can settle at 1440 px of width. Now height of your ImageView is 160dp. Which can be (as suggested by everyone else) 160*4 = 640 px for largest default DPI xxxhdpi. The reason that you should consider height for standard dpis because it is fixed to some dp (160dp) and this may change for custom dpi devices, so you can support maximum devices with this, 640px size. Hope I was clear about size suggestion.
To provide good graphical qualities on devices with different pixel densities, you should provide multiple versions of each bitmap in your app - one for each density bucket, at a corresponding resolution. Otherwise, Android must scale your bitmap so it occupies the same visible space on each screen, resulting in scaling artifacts such as blurring.
Figure 1. Relative sizes for bitmaps at different density sizes
There are several density buckets available for use in your apps. Table 1 describes the different configuration qualifiers available and what screen types they apply to.
Table 1. Configuration qualifiers for different pixel densities.
To create alternative bitmap drawables for different densities, you should follow the 3:4:6:8:12:16 scaling ratio between the six primary densities. For example, if you have a bitmap drawable that's 48x48 pixels for medium-density screens, all the different sizes should be:
36x36 pixels (0.75x) for low-density (ldpi)
48x48 pixels (1.0x baseline) for medium-density (mdpi)
72x72 pixels (1.5x) for high-density (hdpi)
96x96 pixels (2.0x) for extra-high-density (xhdpi)
144x144 pixels (3.0x) for extra-extra-high-density (xxhdpi)
192x192 pixels (4.0x) for extra-extra-extra-high-density (xxxhdpi)
Then, place the generated image files in the appropriate subdirectory under res/ and the system will pick the correct one automatically based on the pixel density of the device your app is running on:
res/
drawable-xxxhdpi/
awesome-image.png
drawable-xxhdpi/
awesome-image.png
drawable-xhdpi/
awesome-image.png
drawable-hdpi/
awesome-image.png
drawable-mdpi/
awesome-image.png
Then, any time you reference #drawable/awesomeimage, the system selects the appropriate bitmap based on the screen's dpi. If you don't provide a density-specific resource for that density, the system picks the next best match and scales it to fit the screen.
Tip: If you have some drawable resources that the system should never scale (perhaps because you perform some adjustments to the image yourself at runtime), you should place them in a directory with the nodpi configuration qualifier. Resources with this qualifier are considered density-agnostic and the system will not scale them.
Official Source: Screen Densities
This is an official size chart given by Material Design Or you can ask for xxxhpdi which is 1440 x 2960 px based image and use this site to get all the images with various densities.
When you get images with various densities, no need to specify height and width in px layout. Keep the images with same name and use match_parent. Android will automatically choose the image according to the device.
try this source code
Display display = getWindowManager().getDefaultDisplay();
String displayName = display.getName(); // minSdkVersion=17+
Log.i(TAG, "Pantalla = " + displayName);
// Tamaño en píxeles
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
Log.i(TAG, "Ancho = " + width);
Log.i(TAG, "Alto = " + height);
// dpi
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int heightPixels = metrics.heightPixels;
int widthPixels = metrics.widthPixels;
int densityDpi = metrics.densityDpi;
float xdpi = metrics.xdpi;
float ydpi = metrics.ydpi;
Log.i(TAG, "Ancho en píxeles = " + widthPixels);
Log.i(TAG, "Alto en píxeles = " + heightPixels);
Log.i(TAG, "Densidad dpi = " + densityDpi);
Log.i(TAG, "x dpi = " + xdpi);
Log.i(TAG, "y dpi = " + ydpi);
// Deprecated
int screenHeight = display.getHeight();
int screenWidth = display.getWidth();
Log.i(TAG, "Alto de pantalla = " + screenHeight);
Log.i(TAG, "Ancho de pantalla = " + screenWidth);
// Orientación
int orientation = getResources().getConfiguration().orientation;
Log.i(TAG, "Orientación = " + orientation);
Yes you would need to take multiple images for different screen sizes, if you do not want to use vectors and wish to use images (png,etc.) instead.
Since you have width as match_parent, in this case take the images with the max screen width for different density buckets:-
MDPI -> 320 px
HDPI -> 480 px
XHDPI -> 640 px
XXHDPI -> 1080 px
One dp is a virtual pixel unit that's roughly equal to one pixel on a medium-density screen (160dpi; the "baseline" density).
According to the above statement , you the find the heigth for the images :-
MDPI -> 160 px
HDPI -> 240 px
XHDPI -> 320 px
XXHDPI -> 480 px
How to calculate :-
Consider, 160 dp would be 160 px in mdpi(1x).
160 dp would be 240 px in hdpi (1.5x).
and so on..
OR using the function px = dp * (dpi / 160)
For HDPI , dpi is 240
px = 160 * 240/160
px = 240
For dpi list refer this
This helped me to figure it out, and make things clear
You can refer this
ldpi: 270x120 px
mdpi: 360x160 px
hdpi: 540x240 px
xhdpi: 720x320 px
xxhdpi: 1280x480 px
xxxhdpi: 1440x640 px
Related
I would like to create a background image for different resolutions in Android. So I need the values (in pixel) for ldpi, mdpi, hdpi,xhdpi and xxhdpi. It is important that the image will not be blurred.
I have already read the Documentation about multiple screen support but there are sizes in dp instead of pixel.
Try follow below android icon graphy size reference for various device screen resolutin.
ldpi mdpi hdpi xhdpi xxhdpi xxxhdpi
Launcher And Home 36*36 48*48 72*72 96*96 144*144 192*192
Action Bar And Tab 24*24 32*32 48*48 64*64 96*96 128*128
Notification 18*18 24*24 36*36 48*48 72*72 96*96
Background 320*426 320*470 480*640 720*1280 1080*1920 1440*2560
there is no full list of screen resolutions, there are no fixed values in pixels for ldpi, mdpi, hdpi,xhdpi and xxhdpi. Every android device may have different resolution. If you want to fill all resolutions you will have to create too many images. If you put them in your app, it will make the app size huge. Maybe a better approach is to use composite image for background.
According to android documentation
mdpi is baseLine size
we can use it to measure all other scales , that mean if mdpi (scale 1) equal 1 xhdpi (scale 2) should equal 2 , multiplay mdpi sizes in scale value
all sizes width x height in pixel
xxxhdpi: 1280x1920 px // 4x
xxhdpi : 960x1440 px // 3x
xhdpi : 640x960 px // 2x
hdpi : 480x800 px // 1.5 x at least 480x720
mdpi : 320x480 px // baseline = 1x
ldpi : 240x360 px // .75 x
** notice I add xxhdpi with 3.0x scale to image*
xhdpi: 640x960 px
hdpi: 480x800 px
mdpi: 320x480 px
ldpi: 240x320 px
i think it is rather easy to convert the DP into pixels in andorid java i am achieving this with this function that i created
int getPixels(Context context, float dp) {
return (int) (context.getResources().getDisplayMetrics().density * dp + .5f);
}
hopefully this is helpful for people,
and kindly do share your views on it, as i would like to get this conversion as accurate as possible, thankyou
I'm a bit confused as to what resolutions I should be saving my images in for the different drawable folders. Is there a general formula for it? For example,if I want an image to take up 10% of the height and the full width of the screen, roughly how would I calculate what different resolutions I should save the image in?
This is android's guidelines for icons. Obviously not all drawables are icons, but maybe this helps you get started.
36x36 for low-density
48x48 for medium-density
72x72 for high-density
96x96 for extra high-density
From here: http://developer.android.com/guide/practices/screens_support.html
According to android documentation here
http://developer.android.com/guide/practices/screens_support.html#range
In mdpi (baseline density) 1px = 1dp
and under topic 'Range of screens supported' least resolution for a normal size screen(baseline size) in dp is
470dp X 320dp and since in baseline density 1px = 1dp so baseline screen size in pixels would be
470px X 320px
now for baseline screen size and density 10% of 470px would be 47px and full width is 320px so your baseline drawable will have the following size in pixels
47px X 320px
The scaling ratios for alternative drawables is 3:4:6:8 for ldpi:mdpi:hdpi:xhdpi
this means that the above baseline resolution of your graphic is at scale 4. Now to get resolutions for your graphic in other densities we need to divide the mdpi graphic resolution with 4 to get the unit values
height unit = 47/4 = 11.75
width unit = 320/4 = 80
now reoultions in other densities can be calculated by multiplying unit values with respective scaling ratios
ldpi
11.75 X 3 = 35.25px
80 X 3 = 240px
mdpi (already calculated above, doing it again here for clarity)
11.75 X 4 = 47px
80 X 4 = 320px
hdpi
11.75 X 6 = 70.5px
80 X 6 = 480px
xhdpi
11.75 X 8 = 94px
80 X 8 = 640px
There are different guidelines on Android developer site about how to manage the image size and resolution to support multiple screens.
Refer this How to develop one android application for different screens?
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.
i have made images for an mdpi phone in android.
i want to resize those images for hdpi and ldpi screens.
what is the conversion factor for the dimesions? i have heard that we multiply the height and width of the mdpi image by 1.5 to convert it to a hdpi screen.
what is the accurate conversion factor- for both mdpi to hpdi and mdpi to ldpi?
thank you in advance.
From the Android developer, 0.75 for ldpi, 1.0 for mdpi and 1.5 for hdpi. Note that if you specified the measurements in dp ( density-independent pixels ), Android will take care of the scaling for you.
It scales 1.5 times if the target
density is high density (160->240
virtual dpi), or 0.75 times if the
target density is low density (160 ->
120 virtual dpi).
You could also scale it in the coding, by retrieving the current density and multiply them.
float scale = getContext().getResources().getDisplayMetrics().density; // retrieve current density
newImageWidth = currentImageWidth * scale;
This is a good read regarding density.