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).
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.
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.
This is the typical area of supporting multiple screen sizes for android. Basically, in my cards game it was really too much to provide the setof 52 cards duplicated for the 3 folders (ld, md, hd). The reasion is the increased app size by quite a bit.
So I was wondering, if I only provide high density folder then would the device scale down the images to appropriate densities. I mean if all what I was doing before was resizing the images down then the scaling down by the device would be same. right?
If I do that (porviding only high density folder), will the image end up taking the same physical size on low density screen (I am using high density as it is generally to scal down than up).
Thank you
PS: Please don't give me the android website. I want your answer/experience
The answer is, it will scale them down for you, but the resulting images will be lower in quality than those provided at the correct density, depending on how it is downscaled and by what percentage. It may or may not be that noticeable depending on the type of graphics, but fine lines and single-pixel details will be most noticeably different.
I have a game card too and i have put all my high-res cards in res.raw.
It should be the same in drawable-nodpi.
On all the device tested, the cards render very good. The phone just scale the cards up or down depending on the screen size.
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)
Android Development help please.
Can somone tell me how I might increase the quality of background images in my app? I have been using Photoshop where the images look great, then I save for the web as a png...then add it to my app... Then on the phone the image looks a little blurred.
Whats the best way to increase my image quality?
I would make sure you're saving it at an adequate resolution. I'm will to bet that "save for web" reduces the resolution to 72 dpi which may not be enough for an android handset. In photoshop, try bumping the resolution of the final png to something like 300 dpi and see if that makes a difference. From there you can experiment with different resolutions to figure out what's the smallest value you can use and still have a crisp image. Alternatively, you could just look for the documented resolution requirements.
The apparent quality of your images may also depend in the type of device you are displaying the images on. For example, if your image is saved as 72px x 72px in your image editor, then displayed with a size defined using 72 scaled pixels (sp) in android on a high pixel-density device, then the OS will stretch the image before display. As such, the pixel density of the display device can affect the apparent image quality.
You can provide different resolution images for different pixel densities by using the hdpi, mdpi and ldpi folders for drawables. See these links for more info:
Screens support
Icon design