Is it necessary to have image resources for different screen density? - android

When I started learning Android, the course that I took mentioned about screen densities in a very early stage.
And it encouraged me to generate image resources for HDPI, XDPI, XXDPI and XXXDPI.
Whenever I get an image from designer, it is a XXDPI image and I will generate other versions using a plugin of Android Studio.
Later I started to doubt if this is really necessary.
As far as I can observe, the only benefit of having different resources for different screen density, is that I can use wrap_content for ImageView and the image will keep the same size in different screen densities.
But this can be completely replaced by using a dp value for the ImageView.
On the other hand, I observed quite a number of drawbacks:
Since multiple images are included, APK size increase (not 100% sure, may someone confirm?)
This approach can sometimes increase memory usage, if you unnecessarily used a very high resolution image (e.g. a fullscreen background image). See this post for example.
Extra effort of generating different images
It is a nightmare if you need to have different drawable resources for another product flavor
So I start to think that why not just put a high resolution image in nodpi folder and let Android scales down for you? I never observed any observable drop in image quality. Will this cause any memory issue in a device with lower screen density?

Related

Clarifications about android drawable folders

Until now, I did not pay too much attention to how to store drawable resources.
I usually generate multiple versions of an icon and store them under the drawable-mdpi, drawable-hdpi, drawable-xhdpi, ... folders.
For other images for which I don't have multiple versions, I inconsistently store them under drawable-nodpi or drawable.
However, I recently encountered an issue related that bring all my attention to that. I stored a 100KB image under the drawable folder. However, my app was regularly crashing, stating it could not allocate 18MB!
After some searches, the reason was that the image was scaled to fit the screen resolution and it resulted in a way heavier image. The fix was to move it under the drawable-nodpi folder which prevents that scaling.
So now, I am trying to better understand where I should locate my images and how this scaling effect works to optimize my app on that part.
I have done plenty of searches, but resources are limited or unclear on that subject and the official documentation kinda really sucks.
I am aware of the official explanation for the drawable or drawable-nodpi, but it does not clarify everything.
Typically:
How does the scaling work? Let's say I have res/drawable-mdpi/image.png. Does that mean the image is scaled if I have a screen different from mdpi, or will it also be scaled on mdpi screens resulting in possibly heavier image size on every device?
Following previous question, if the image is not scaled for mdpi screens but scaled for any others, then does that mean that if I provide a version of this image for every screen density, the scale will never happen? Or at the opposite, if the image is scaled also on mdpi devices, then having different version of the same image for each screen density will still scale the image, but using the version of the image matching the screen density of the device?
How to deal with icons for which I do not have multiple versions? I am afraid that if I put this single version in mdpi, it just scales it and uses so much more memory than necessary. In such case, should I put any icon for which I do not have different versions under nodpi?
On the other hand, if whenever you put an image in mdpi, hdpi, ... it scales it even on devices matching the density, then should I just move everything under nodpi or some high resolution like xxxhdpi where it can only be downscaled?
Thanks
Let's say I have res/drawable-mdpi/image.png. Does that mean the image is scaled if I have a screen different from mdpi
Yes.
or will it also be scaled on mdpi screens resulting in possibly heavier image size on every device?
No.
if I provide a version of this image for every screen density, the scale will never happen?
Yes. Your APK will be larger, due to the 7 copies of the drawable.
How to deal with icons for which I do not have multiple versions?
Option #1: Decide what density that particular version belongs in, and put it there. Android will upsample or downsample the image for devices operating at other densities.
Option #2: Put it in -anydpi or -nodpi, in which case Android will not upsample or downsample it. However, in this case, you need to be controlling the size of the image yourself (e.g., in the ImageView).
Option #3: Replace the icon with one that either you have all relevant densities or one that is an SVG that works as a vector drawable when imported using the Vector Asset Wizard in Android Studio.
The decision-making needs to be based both on memory consumption and what the result looks like. A low-memory solution that looks awful is unlikely to be a good choice.
should I just move everything under nodpi
Probably not.
or some high resolution like xxxhdpi where it can only be downscaled?
Probably not. It is unlikely that a massively downscaled version of your icon will look very good.

Android drawable: different densities or scale

I have designed an in-app keypad for my Android application and I need to provide an image for every key. Currently I've only loaded one large image for each one that is being scaled down to adjust to the layout. Also, this looks nice in every resolution.
Is this approach acceptable or should I provide different images for different screen densities? Currently I've placed those inside the generic drawable directory.
You should. Some mobiles with lower resolution, usually won't have much memory. Loading large images in small screen takes too much memory, which might end up crashing. So if you give different images, then according to density it will take appropriate images. check this out.
It's acceptable in some cases but certainly not optimal.
For best memory performance and the least amount of artifacts I would still recommend to provide alternative bitmap resources for different densities, like the Android documentation recommends.

Android: Background image resolution?

I am developing an android application which displays an image as background. I have read the documentation and it says that Mdpi should be the base line and all other dpi's should be relative to it. But I am not able to decide what should be the resolution of background image in pixels I should for all the dpi's?
Any suggestion?
The best approach depends but, to save space and retain resolution at all densities, include only a single image in your app. When your activities load, use a scaled load based on the the DisplayMetrics of the device. If you aren't worried about resolution, then scaling up from MPDI is fine (but I'm pretty sure you're asking because resolution at the higher densities is a concern, and based on your background image size).
The advice for "starting" with MDPI has to do with the numeric scaling that is needed and being able to conceptualize it. In other words, it is easiest to "think" about how scaling works on Android when you start with MDPI. After that, your use-case is far more important.
There are many examples for scaling images based on your needs. Do not forget to use caching whenever possible, if your application loads several.
Another thing to consider is the extended heap memory, if you encounter OOME because of iamge handling issues.

Scaling images automatically instead of pre-defined images

I'm quite new to Android development. My understanding is that you can create several versions of the same image with different sizes and put them into the folders drawable-ldpi, drawable-mdpi, drawable-hdpi.
It seems obvious to me that you can handle this problem "the lazy way" by just resizing one image depending on the device's pixel density. For this I programmatically find out what density the device has, like ldpi. The implementation itself is not the problem. I'm just afraid of any drawbacks (that prevent me later from running the app on different devices).
So, are there any (major) drawbacks of scaling images automatically ?
In which of the three folders do I put the image so that the compiler can find it?
You would put the image in your regular drawable folder. That way any phone can find it.
While you can programatically shrink images, shrinking usually has the effect of reducing image detail and causing jaggies.
Adding in smaller assets will also reduce memory usage on smaller phones. Keep in mind that some Android phones are notoriously bad with memory (see: HTC Status), so any and all savings help.
I would recommend just photoshop scaling images down large images yourself. For smaller images, it is not as big a deal.
Android does auto-scale and it works fine in some cases, but it doesn't work for many, notably small images with important details like text. Scaling a larger image down blurs those details. Scaling a smaller image up is worse. This is why icons files have been multi-resolution since the very early days of GUIs. To wit, text scaling is hugely complicated. Ask any font designer, and note Adobe built a company on algorithms to do it automatically.
it's on mdpi folder. It'll change the size automatically. But is not recommended since the image quality drops.

android developers - what do you need from the designer?

i am NOT an android developer and im trying to understand what they need in terms of graphical resources to make an app that functions across many android devices.
i have (tried to) read this page http://developer.android.com/guide/practices/screens_support.html , but find it somewhat bewildering. they talk as if screen density is the important thing "Supply alternative bitmap drawables for different screen densities" but then, if you dont know the size of the screen, you cant really think in terms of layout. is the idea to make buttons and logos that are the same size on all screens with the same density, such that on a large screen there is just a bunch of space, and on the small screen its all packed in tight? i dont understand how just thinking in pixel density gets me any closer to knowing what to provide.
are you supposed to create resources for every screen size AND pixel density? say it aint so.
anyway can somebody tell me... if you were developing an app what do you need for graphics? is it possible to provide graphics that are large and just let them scale down? is it inevitable that the devloper will have to mess with the graphics himself anyway? or can he be provided with sets of png files of certain sizes that will be ready to use?
thanks!
Here's what we do at my work place. Suppose we get a desing for the app. We make our designer create 3 psds versions for the same desing. the 3 psd's are for the 3 ranges of desnity. The size used for the psd are
240*320 (Low Density)
320*480 (Medium Density)
480*800 (High Density)
Most of the time when I write layouts, I use wrap_content which means a view must take the size of the content it wraps. Which works most of the time as I have a density specific version of the design so the image i use as background should be suitable. The thing to note is that, in android you can can put the 3 sizes of the same image in different folders such as drawable/ldpi, drawable/hdpi.
Eg: you have a bg.png and have a version for large phones and a version for small phones. You put the big bg.png into hdpi folder and the small png in the ldpi folder. Android will automatically select the appropriate image based on the phone density. But you need to make sure the file name is the same.
There are cases where you need to resize you background images without makeing the image looking too scaled. For this android uses the draw9patch tool. With this tool you can specify areas which can scale and areas that shouldn't scale.
9 Patch png's are your friend. Read up on them here:
http://developer.android.com/guide/topics/resources/drawable-resource.html#NinePatch
and here:
http://developer.android.com/guide/developing/tools/draw9patch.html
Those are your best bet for any kind of graphic that will stretch nicely (i.e. not gradients, they will come out slightly pixelated on some screens probably) The power of these types of images is that you can tell the system which pixels to repeat if it needs to stretch the graphic. This means that stretching can be done without loss of image quality (again depending on your image and how you choose to make the nine patch. The "show bad patches" button in the draw9patch program will show you potential problems. Hint: keep your repeatable pixels down to 1 on left and 1 on top and you'll have no problems with bad patches) Any graphics that can be made in to 9 patches will only need 1 size since the system can effectively make it whatever size it needs.
are you supposed to create resources for every screen size AND pixel density?
You may if you like. This would ensure that the application will look great across all devices. I understand that this is not feasible for all projects though. In general if you make separate resources for the different densities you'll get something that looks acceptable on most of the devices out there. All of the devices are classified as ldpi, mdpi, or hdpi (there may be an "extra high" level now too, I am not certain off the top of my head) So if you supply graphics for those 3 densities then the system will know where the device falls under and will pull the correct graphics.
is it possible to provide graphics that are large and just let them scale down?
Yes the system will scale down your graphics if needbe. But be aware there are consequences with this approach. First every time the system hast to scale a graphic up or down it is going to taking up CPU and memory to do so. This may not be an issue if you have relatively few things to scale, but if you have many it could cause noticeable lag time during on the lower power phones. Second, To my knowledge all of the graphics in android are raster, which means if you are letting the system scale something up or down image quality is going to decrease some. Again depending on the specific images this may be more or less noticeable on the actually device at runtime.
My best advice is supply them with resources of a few different sizes and run the app on as many different devices as you can. Once you see how your different resources look on the devices of different sizes you'll have a much better feel for which ones you need to supply to get the UI looking as consistent as possible across the largest swath of screen sizes and densities.

Categories

Resources