Can I use just one png image big enough for all densities? Or do I need to create one png image for every density?
I tries placing just one png image in drawable folder but it becomes blurry. So I placed that same image in the drawable-xxhdpi (my test device density) and it shows correctly (clear). I guess that the blurry effect is because it is multiplying for the scale factor of the screen density. The idea should be to say to Android to take the big image (xxxhdpi) and make it smaller (never bigger).
Related
most resources have pointed out that when we using (ldpi, mdpi,hdpi, xhdpi,xxhdpi,xxxhdpi), the android doesn't need to rescale image and we won't have cpu overhead for rescaling image.
but i didn't got that point yet, suppose i have an icon image with all size that already mentioned (36px, 48px, 72px, 96px, 144px and 192px), well, in bellow code you see i use 40dp that it doesn't match any above sizes, so android would rescale the image again, then what is advantage if multiple drawable?
<ImageView
android:layout_width="40dp"
android:layout_height="40dp"
android: src="#drawable/icon"
/>
You'll often not have an image with an exact Pixel match for the DPs you describe in the layout -- like the case you describe above. When this happens Android will still need to do some scaling.
The benefit isn't CPU savings, its Memory savings.
Scaling operations on large images can require a great deal of memory, especially if scaling from small to large, or large to small.
If you're starting with an image that is close and only need to scale a little, the memory cost is less significant.
If an image is w500px, h500px, that is 250000 pixels. Even if that image is a jpg and compressed to be 10kb on the disk, scaling requires Android to convert to RGB or ARGB which is 3 or 4 bytes per pixel.
4 bytes x 250000 = 1M of memory.
500px on a device that is XXXHDPI is only about 1 inch on the screen.
So you can see how this can add up quickly.
EDIT: This might be useful https://developer.android.com/topic/performance/graphics/load-bitmap.html
Contrary to what Aaron says, the benefit of providing these images is not about system resources, it is about how your app will look to users on different devices. By providing high-resolution copies of the same image, users on high-resolution devices will see crisp, clear images instead of upscaled fuzzy images.
Your question mentions specific pixel dimensions for an image. I assume these values are taken from https://developer.android.com/guide/practices/screens_support.html
36x36 (0.75x) for low-density
48x48 (1.0x baseline) for medium-density
72x72 (1.5x) for high-density
96x96 (2.0x) for extra-high-density
144x144 (3.0x) for extra-extra-high-density
192x192 (4.0x) for extra-extra-extra-high-density
When you provide all of these different resolutions for your image, you are not providing different physical sizes. Of course 144x144 is three times larger than 48x48, but this 144x144 image will not appear three times larger when the user sees it on their device.
The system will only choose to display the 144x144 image when the user has a device with a high-resolution screen. This means the individual pixels in their display will be smaller, which means the 144x144 image will take up the same physical space as the 48x48 would on a lower-resolution screen.
In short: all of the images in this example are 48dp x 48dp.
Now, if you display this image in an ImageView that is 40dp x 40dp, the image will either be cropped or scaled down. But this has nothing to do with the extra images you've provided. Whether on a very low-resolution screen or a very high-resolution screen, the system will still be stuffing a 48x48 image into a 40x40 container.
Update
Here's an example. I've used Android Studio's New -> Image Asset menu to create an image. You can see that AS generates multiple copies of the same image with different dimensions:
Next, I create two emulators:
Nexus S (hdpi): http://www.gsmarena.com/samsung_google_nexus_s-3620.php
Nexus 5 (xxhdpi): http://www.gsmarena.com/lg_nexus_5-5705.php
And then I run an app that just displays my image on both of them:
You can see that the status bars, action bars, and the little android all appear the same size. But the Nexus S is displaying the hdpi image (48px x 48px) while the Nexus 5 is displaying the xxhdpi image (96px x 96px). Both look sharp!
Finally, I delete all copies of my image except for the mdpi one. Now both emulators use the mdpi image, but you can see that they still display at the same size. The image's intrinsic size is 32dp x 32dp, so even though both emulators are using a 32px x 32px image, both have to scale it up (the Nexus S has to scale it 1.5x and the Nexus 5 has to scale it 3x).
As you can see, the little android is the same size, but it looks much worse. This is why you provide copies of the same image at different resolutions: so that your images always appear crisp!
I'm trying to make an activity with an image that is the same height as the screen. I tried going to easy route, and just using a really big image and then scaling it down within the app, but when I run it on a device with a smaller screen, I get an error saying the device ran out of memory. I was hoping to make several drawable folders for each dpi (drawable-mdpi, drawable-hdpi, etc.). I looked up the pixel dimensions for splash screens, but when I resize my image to fit those dimensions (https://stackoverflow.com/a/15744389/5909429), the image only fills about half the screen on my smaller device.
What dimensions should I actually use, or am I using the drawable folders wrong?
[...]or am I using the drawable folders wrong?
Yes and no. I don't know about any "perfect" values for your picture dimensions, and I doubt that there are any, due to the fact that there are too many different phones to support.
The usage of dpi ensures that everything has the same size. If you were to put a ruler on your screens on a xxxhdpi and a ldpi device, both pictures would be the same size. This is dpi.
What you are trying to do is filling a phone screen. This has not much to do with dpi, but is about the actual pixel size of the screen. If you have a 1920x1080 phone display, you want an image with the same resolution. This does not say anything about dpi or screen density, and it has frankly nothing to do with it.
To properly scale down your image—and not running into OOM—you can either use a designated image loading library, like Glide, or Picasso, or you can take a look at BitmapFactory which lets you supply a inSampleSize to load the image in the size needed yourself. The official documentation can be found here at Loading large bitmaps efficiently.
I have an application that uses ImageViews to show some pictures. The image sizes are 320x480px.
I use some animation to move these pictures to the center of the screen and when the phone has the resolution of 320x480, it works great.
However, when I tried it on emulator with the resolution of 240*320, there were some problems:
The ImageView is still 320x480 so it looks way too big
The animation that uses the screen resolution can't move the pictures to the center, it is at least 20-30 px off
I learned the when dealing with pictures, Android dynamically changes resolution of them to make the images fit in. How could I set that these images should be resized according to screen resolution?
It's hard to say what's wrong without seeing any code. Android resizes images from res/drawable according your screen resolution (ldpi, mdpi, hdpi, etc.). If you place pictures in res/drawable-nodpi, they will not be scaled. You could also use the density dependent folders res/drawable-ldpi, res/drawable-mdpi, res/drawable-hdpi etc. You should definitely read the docs here.
I believe that android:adjustViewBounds="true" and android:scaleType="fitCenter" is what I needed. The ImageViews are scaled down to 240x320 and the animation works well.
Interesting that the upscaling is not proper. When I used in the emulator at 480x800, my ImageView is scaled up to 480x720 so I get black edges. Any idea for that?
This might be a quick answer but I must not know what to search for as I can't find anyone talking about it! I have some png files in my drawables folder that are 88x88 pixels. I run my app and have a log print out the size of the images and it claims they are 176x176. What gives? Is something expanding my images before they go into the apk or is my phone really only half the resolution it claims?
BitmapFactory.decodeResource scales images in the Drawable folder according to the DPI of the device (it generates a higher resolution image for high resolution screens).
If you don't want the image to be scaled on decoding, place it in the folder Drawable-nodpi
From this guide:
"By default, Android scales your bitmap drawables (.png, .jpg, and .gif files) and Nine-Patch drawables (.9.png files) so that they render at the appropriate physical size on each device. For example, if your application provides bitmap drawables only for the baseline, medium screen density (mdpi), then the system scales them up when on a high-density screen, and scales them down when on a low-density screen. This scaling can cause artifacts in the bitmaps. To ensure your bitmaps look their best, you should include alternative versions at different resolutions for different screen densities."
So yes, your screen is probably xhdpi with density 2, so size of your image from unspecified drawables folder would be x2.
i am putting the image in three of the drawable,drawable-hdpi and drawable-ldpi for supporting all type of screen but when i see the output of background image in 240*320 screen resolution the background image is not as clear as origional so my question is where to, means in which folder i put the background image for supporting it all type of screen size and density, maens then my image should not distorted or bluer...
i am using the background image of size:320*480
thanks
make one folder name
drawable-nodpi
put your image in that and use it and dont keep that image in other folders.
the image will not be scaled or stretched.
Anoher Way
the best way is to make 3 different size images and put int drawable-ldpi(240X320),drawable-mdpi(320X480),drawable-hdpi(480X800) folder with the same name.
TO LEARN MORE PLEASE VISIT THIS LINK.
Supporting Multiple SCreens
You can put different same image in drawable-hdpi,mdpi and ldpi.Depending on the density of devices they will take the images from the corresponding folder.
With different devices you should have same image but with different size and density.for You can search in internet the specifications of devices.If density is less than 160 then put image in ldpi,if 160 then use mdpi and if 240 or above use hdpi.Also change the size of image to the screen size of corresponding device.Hope it will help.