Why developers must provide different images for different screen densities (ldpi, mdpi, hdpi, xhdpi) ?
Why don't we just provide one big image for big density (e.g. hdpi or xhdpi) ?
There are couple of reasons why you might want to do this:
Resizing on the fly takes resources (CPU/memory) and thus slows your app
You might not be satisfied with resizing algorithm or know how to resize your image to get better end result (think of the case when you have vectors for your image)
you might want to use different image for different densisies at all (think of the case when your image contain text. You might want to ommit text on low density image if there is not enough space to show it)
If you do provide big images android will have to scale them wish isn't really optimal because it will waste energy and slow your app.
Related
I want to create a full screen image which supports multiple screen sizes in android.
I know that there are 5 different sizes mdpi, hdpi, xdpi, xxdpi, xxxdpi. I also know that creating a 9 patch image seems to be the ideal solution. The problem is that the Android documentation always talks in dps, and dpis for the different screen densities (mdpi, hdpi, xdpi, xxdpi, xxxdpi) but as a developer at the end of the day I need to make the image in pixels.
So to avoid stretching, compression or any other distortion what should be the pixel sizes of the 5 images that I should make? Or are there other images sizes also to be made? I have spent a lot of time on this already, so if anybody has encountered and solved this problem then please post the screen sizes and why those sizes were chosen.
EDIT:
Is there any specific link I can refer to. I want the pixel*pixel sizes of the images to make which will handle each case properly. I know they will be approx, but I want good user experience with the least number of images, so that the apk size is small.
You can get many screen sizes on various devices. If you want the image not being altered and fit the screen exactly the size it is, you would need to create images for all possible screens.
The five groups you mentioned are for densities not for sizes. This is to have your icons and other objects roughly the same physical size across possible devices.
Your are probably looking for size qualifiers
Hi Guys And Ladies and the Others,
I develop a project. It have a lot of images. And it just run on 4.0 and above device. So If I resize all of images to xxhdpi, xhdpi blabla, the size of application became very huge. If Am I just create 72x72 (hdpi size), is it just enough ? Or do you suggest anything else ?
Thanks a lot for the answer..
The proper way to do it is to have different bitmaps for each density. This is because high density images are ideally not just high resolution copies: they're custom designed with more detail in. Also, low density devices tend to be underpowered, and so have a hard time scaling down high resolution images.
It does depend on your application and your needs, though. You might find that your application runs at a decent speed, and looks OK, with just one image of each type.
Something else you should consider is whether you can use vector graphics for some of it, or a ninepatch, which will scale automatically.
Lower quality images end up getting stretched on higher resolution screens, which can look pixelated. If you need to cut down on images, there are a number of approaches that I would suggest:
Consider the format. If you need a rasterized image, does it need to be a PNG rather than a compressed JPEG image, for example? Can you get away with using an SVG (which would allow you to support all sizes and resolutions using a single image asset)?
For rasterized images, consider whether you can tune the compression ratio.
Try supporting the highest resolution, and then skip a few resolutions in between and provide some lower resolution images for lower resolutions where details appear lossy or where you seem to be getting a performance hit from downscaling the high resolution image (that is, xxhdpi will probably be fine on xhdpi and hdpi, but then you will likely want to provide separate mdpi and ldpi images).
I have an image application like a SlideShow on Android and want to support multiple screen resolutions viz. ldpi,mdpi,hdpi etc. I have a large number of images and having a copy of every image for each screen resolution will make my application size big. How to package them in an efficient manner so that the application size remains small ?
In order to support multiple screen densities, you don't really have to provide all of the images per density (in case they look about the same, only resized).
You could simply put the highest quality images on drawable-xhdpi or drawable-xxhdpi, and downscale&view the images at runtime for other screens (Android does it automatically, but in some cases you might want to do further downscaling, depending on the images).
The downside is it requires more work on lower density screens, and images might look different than what you want them to be.
It's a common thing to put icons in different densities folders so that the resizing won't damage the quality in any way (including the blurry effect).
My app supports various screen densities from ldpi to xhdpi. It contains some drawables (images) that need to be displayed properly on all densities.
I'm wondering how many various resolutions of the drawables are actually necessary to provide, considering that Android runtime is scaling resources when it cannot find one for the appropriate density.
If you provide only mdpi drawables, they will be scaled up on hdpi/xhdpi (blurry) and scaled down on ldpi screen.
However, if you provide only xhdi resources, then they will be scaled down on all lower density screens. Scaling down doesn't make them blurry and they will look fine.
So why bother providing drawables for other densities than xhdpi?
There are several reasons to used prescaled drawables:
Scaling down to lower resolutions takes resources (CPU time, memory and it drains your battery faster), especially if you have a lot of images this might be undesired.
Scaling down a large image might result in worse quality than using a 'pre-tuned' smaller image. Especially if your images are based on a vector original. Or they contain very fine lines or details, which will get lost when due to the scaling.
For example:
becomes
See here for the source of these images and more information on scaling artifacts.
On lower resolutions the image pixels are larger (or the image gets smaller), so it might be required to remove certain aspects of the image to keep it clear/understandable.
Your assumption about scaling resources isn't correct. Some large images may still look nice when they are scaled down, but this isn't the general case. If the image has smooth transitions and no gradients, it will be nicely scaled down. Images that contain sharp transitions or contain text for example will look ugly in lower resolutions.
If you make the scaling down yourself the result might be better compared to auto scaling plus your app doesnt consume resources for scaling if the drawables are prepared.
Not necessary but for example, you can use different layouts with different drawables for different screen resolutions. You have the option to do it. If you and your users are satisfied with the result, then cool. If you need different behavior in different densities and resolutions, then this feature comes really useful.
I'm writing an application where I will need a number of full screen bitmap backgrounds. Based on my naive reading of Supporting Multiple Screens in the Android documentation, to cover all my bases I should probably have 16 versions of each bitmap: all pairs of [ small, normal, large, xlarge ] and [ ldpi, mdpi, hdpi, xhdpi ]. This should reduce the work the CPU has to do for scaling the images, but will come at great storage cost.
However, this seems wildly inefficient for two reasons:
Not all of these combinations are found in practice.
As I'm just rendering vector art for each physical size (without respect for DPI), pairs like large/mdpi and normal/hdpi (which are both ~ 480x854 pixels) are duplicate files.
So, should I just provide really large images and let the system scale them down? Bite the bullet and provide a lot of duplicate images? Avoid the issue altogether and cobble some code solution with raw resources? Any other ideas? Thanks.
EDIT: Apparently you can create XML bitmap drawables which alias an actual bitmap. That solves the second inefficiency argument. Still, I wonder, what combinations of these do others provide in practice?
You would only provide images at different resolutions if you want that piece of art to be a constant size, regardless of the screen dpi it is displayed on. An icon or a button would be an example of this.
For the background images described here, you don't care what the image dpi is -- you only care what the x * y dimensions are. So you don't have to produce the cross-product of sizes vs. dpi. You only need consider the 4 screen size categories.
And within the 4 screen size categories, you only need store one of the larger sizes (xlarge or large) and let the framework scale that up or down as needed. You can also do the scaling programmatically, to ensure that you don't change the aspect ratio of your background, and you don't crop it.
See also Android game working on all screen sizes which will hopefully attract a better answer.
I would advise providing images for ldpi, mdpi, hdpi and optionally xhdpi (depending on your target users). That will allow you to cover the most commonly used resolutions just fine.
If you end up with the feeling that your application is getting too large (either by deciding to add all possible image sizes or other reasons), you can also look into allowing your application to be moved to an SD card. That way, storage won't be much of an issue anymore. (http://developer.android.com/guide/appendix/install-location.html)