I understand that we import different sizes of an image file into the different drawable folders (hdpi, xhdpi usw) to avoid downscaling on different screen resolutions. This costs memory and could make the image look distorted.
This is what I don't understand and i have found no proper explanation anywhere:
Does the image in pixels have to perfectly fit the containing ImageView's size or is it just important that the image comes close to it? Because in both scenarios the process of downscaling will happen.
Is the process of downscaling the memory intensive part or is it the size of the image file that is in the cache? For example: Is a 10% too large image better for performance than a 200% larger image?
When I prepare image assets, is it enough when they come close to the target size or do I have to make sure that there will be 0 scaling?
Lets say i have an ImageView with 100x100dp and an xhdpi screen draws 2 pixels for 1 dp, does my drawable have to be exactly 200x200px or can it be like 220x220px?
I talk about local images in the drawable folder here.
Related
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).
I had different nine-patch images for different screens. However, I encountered an issue
android drawable image takes lot of memory compared to its disk size
So, I decided to use, for now, nodpi with hdpi image size.
Since, I have limited understanding, I was wondering what should be the image size I should put in drawable-nodpi folder.
Should I put hdpi images or xxxhdpi images? Or something else?
Please help me understand.
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.
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 have images that need to scale to the screen's size. The images will also have text in it that needs to be translated to a second language. So there will be two versions of each image to start, one for each language.
Google recommends having an image resource per density. So I'd take my two images and multiply them by four: xhdpi, hdpi, mdpi, and ldpi. But then Google say to have different image resource for different screen sizes. This multiplies my images by four again: xlarge, large, normal, and small. I don't want to create 32 copies of every image!
I'm wondering if there is anything wrong with making the images for xlarge screens and xhdpi densities only. IE – Best quality. Let Android scale down the images for lower densities per its standards for dp units. And when I draw on smaller screens, I could use the Canvas class to scale down further. I could cache the resulting scaled Bitmap object for use every time it needs to redraw the bitmap to avoid expensive scaling computations running over and over.
Is there any drawback to doing this? Or is there a better way to avoid making so many copies of the same image?
There will be a performance penalty in downscaling large images on smaller (low-end) devices. Whether this will be noticeable depends on the number of images you have to show.
The same holds, mutatis mutandis, for memory.
I create bitmaps only for the highest xhdpi pixel density, and then test on other screen types.
If a bitmap looks bad on some lower-density screen, I remake it specifically for that density. And this happens quite rarely...
Also, making special bitmaps for different screen sizes (small/xlarge) is not needed - just make your ImageView-s smaller/larger - image scaling is not a slow operation, so in most cases you don't need to worry about it either (unless your bitmaps cover the whole screen).