I am developing android apps for years now, and I always struggled with the part of resizing all icons for all different screen densities.
A couple of days ago I developed a utility for making this task easy and released it's source. But I received the following comment:
"If you have a mdpi device, and an app only has xhdpi resources, the system will scale the xhdpi resources down to mdpi size automatically."
So, I should not create all icons in different sizes for all screen densities??? Have I been wasting effort and time all this years?
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.
http://developer.android.com/guide/practices/screens_support.html
But you did not wast effort and time because to ensure your bitmaps look their best, you should include alternative versions at different resolutions for different screen densities.
Also this will give better performance
Related
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.
This is the question of its own kind may be some one has come across same condition which I have to face many times when it comes on UI and graphics.
And insist to forget about different screen sizes and resolution and just focus on the dps. Where as all the designers focus on the Resolutions and pixels.
So if I have to make the background screen for the splash activity so then What I am supposed to tell him If I want him to design for all folders I mean
mdpi, hpi, xhdpi , xxhdpi , xxxhdpi.
So first question is what size should I tell them to draw and for mdpi and hdpi and xhdpi and xxhdpi and xxxhdpi ? what should I tell them ?
Android designing is I think really very tough if you want to support different devices of different densities.
what would you suggest to make the the Graphics for all devices and what resolution should be the starting point ?
In the particular case of images that are meant to be backgrounds, it's okay to have a reasonably large image (1280x1920) and stick it in the drawable-nodpi folder.
Otherwise, for icons, your designer needs to learn about dp sizes. Then ideally they'll create a nice big high-res icon (say 512x512px), and either you or they will scale it to the appropriate sizes using something like Android Asset Studio
Tell your designer to make high resolution image,that means xxxhdpi or xxhdpi as per your requirement. so that we can converting it to lower resolution.
If you are using android studio then you can try this plugin.
by this you have to use Scaled Drawable import
To have just 'drawable' folder(if doesn't exist, I create) is enough to create suitable image size rate for all devices? or Should I create image size rate for each folder(hdpi, mdpi, ldpi, xhdpi) ?
res/drawable/ is equivalent to res/drawable-mdpi/. The suffix-less name is there for backwards compatibility, before the densities were added in Android 1.5 or thereabouts.
is enough to create suitable image size rate for all devices?
If you do not mind Android scaling your images up and down for other densities, yes. Usually, the quality will degrade the further the density is from the starting point (in this case, -mdpi.
Should I create image size rate for each folder(hdpi, mdpi, ldpi, xhdpi) ?
That depends on the image and the results of the automatic scaling. Many developers will ship a couple of densities, but not all of them, and tending to aim towards higher densities (e.g., -xhdpi). But, you are welcome to do what you want, so long as you feel that your users will be comfortable with the image quality that you deliver to them.
You can have drawables with the same filename in the different dawable-{}dpi folders.
Depending on the display density the drawables from the correpsonding folders are picked.
You can read up here
Almost every application should have alternative drawable resources for different screen densities, because almost every application has a launcher icon and that icon should look good on all screen densities. Likewise, if you include other bitmap drawables in your application (such as for menu icons or other graphics in your application), you should provide alternative versions or each one, for different densities. Have a look at this link: http://developer.android.com/guide/practices/screens_support.html
If I add a large image to xxxhdpi folder does it gets resized automatically by Android to smaller images for other screen resolutions?
And if yes from which version of Android is this supported?
You shouldn't really need xxxhdpi. It was only introduced because of the way that launcher icons are scaled on the Nexus 5's launcher.
So throw your image into xxhdpi and it will scale down for other devices. The only issue you'll have is quality. You'd get higher quality out of the image if you scale it yourself.
Adding to my comment, this is from Android Developers - Supporting Multiple Screens.
Provide different bitmap drawables for different screen densities
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.
And from a Roman Nurik post
I talk about some of the key aspects of Android 4.4 KitKat that all Android designers should be aware of. Specifically:... 7) The introduction of new XXXHDPI (640dpi) launcher icon assets due to the Nexus 5 launcher's icon scaling behavior.
So it seems that it will scale, and that the resolution xxxhdpi is a newer implementation. I really would avoid using xxxhdpi images in an application unless you plan on using them specifically and for a good reason as they are going to be large files.
Edit
It does seem xxxhdpi was introduced in 4.3, as stated in this Android Police Article. Either way, it hasn't been around for long and isn't used by many devices at this point, so I still say that unless you have an explicit reason to use a xxxhdpi image it isn't worth the space and scaling issues you might encounter by using it.
It was first spotted in the 4.3 source (see Android Police) and its distribution is currently less than 0.1% (see Screen Sizes and Densities). Although the images would scale down you should include lower resolutions (I would go with mdpi, hdpi and xhdpi without xxxhdpi) to ensure both high image quality and high performance.
In my application I have to use hundreds of bitmap icons and we want to support multiple screen.
And through the documents at android developer, it seems that it is the only way to create these icons for different devices with different dpi.
If this is true, we will have a hard work, so I want to know if there is an alternative to avoid this?
Given the number of icons that you're dealing with, creating multiple versions of each manually is clearly out of the question.
I suggest that you create your icons at the xhdpi resolution, and come up with an automated process (perhaps using something like ImageMagick, and the scripting language of your choice) to produce the lower resolutions as part of your build process.
You don't have to provide different bitmap resources for all possible pixel densities, but ideally you would provide low dpi (ldpi), medium dpi (mdpi), high dpi (hdpi) and extra-high dpi (xhdpi) icon resources.
If you don't provide all of the above, the Android system will automatically pick the closest matching resource and scale it to match the actual screen pixel density.
Please visit Android Asset Studio wherein this site will provide all types of dp icon images of your requirement.
In your case, go for Generic icons section or Menu icons section.
Hope this helps.
You can put your images in /res/drawable, then Android would scale them according to dpi in order to keep the image to be roughly the same physical size regardless of display density. In this case an image would be unmodified in MDPI, 1.5x larger in HDPI, 2x larger in XHDPI, and 3x larger in XXHDPI.
You can also put them in /res/drawable-nodpi, in which case no image rescaling would be applied, but it is hardly ideal as the same image would be physically 3x smaller in XXHDPI than in MDPI.
All of the above methods have serious cons, so really the most sensible method is to put the correct sized images in their respective DPI folders. Your images should be drawn in a much larger resolution, so it should just be a matter of rescaling each image to different DPI sizes.