I would like to get advice, pros and cons, about using different resolution graphics or resize them with dip size.
I mean, if my ap will have all possible resolution, one way is to create the pngs for each one, ldp/mdp/hdp/xhdp, but I am thinking that to save work and time maintaining the app, maybe is easier, to include pngs with maximal resolution, xhdp, and to specify the size well in the .xml or in the .java with dip or relative size depending on the screen.
What is your opinion on that? Pros and Cons?
Regards,
Cons (against having only one size): Unnecessary use of memory.
Images are memory-hungry objects, and when you multiply its resolution twice you multiply its memory cost by 4.
Low-resolution devices are likely to have less memory as well and loading unnecessary big images could cause memory exceptions.
Related
Apologies in advance for such a basic question, but this is my first app and I can't quite find a clear answer for my situation. All the images in my app are stored in the drawable folder, I'm NOT downloading any images from the internet. All the information I come across when it comes to multiple image sizes seems to refer to the occasion when the app is fetching images from the internet.
So currently most the images in my app are one size, customized for the largest size - xxxhdpi. However, I understand the app is doing some work to "shrink down" those images for the xxhdpi size screens.
I'm having second thoughts about this one size fits all approach. I'm thinking that perhaps the app doing the work to shrink the image down might take up extra memory and negatively impact performance. I've been looking at the Android Studio Profiler and I've been trying to understand the Graphics Process when I look at the Memory Graph.
More generally speaking, is there a benefit to having the smallest size images possible, even for the xxxhdpi? For example, does it hurt (memory wise or in some other aspect) to use a .png image when I could use a lower quality jpg? Again, just to super clear, this is just in the scenario when the app has all of its images in the drawable folder. My app has options where players can change the game background and other images so I want to be sure I'm optimizing how the images for best performance. Thanks.
Memory. If you load a bitmap of x by y pixels, in memory that takes 4*x*y bytes. For a full screen image, you can expext that to be 4000*1000*4 or 16 MB. That's a good chunk of memory to a small device, which also tends to have less RAM. If instead it needed one at half the resolution, you would have 2000*500*4, or 4 MB.
Obviously this scales with size. The smaller your images, the less memory wasted. I wouldn't argue that you need to provide every size, but if you're using large images I'd provide more than one. Also, for anything that isn't incredibly complex (like icons) I'd consider vector images instead (although that's a CPU time vs memory tradeoff).
You mentioned png vs jpg. There's two things to consider there: apk size and image quality. JPG is smaller, so it will lead to a smaller apk size. PNG is lossless, so it will have higher quality (although whether that matters requires a human visual check- it matters less than you'd think on a lot of things). Interestingly it doesn't effect the amount of memory used at runtime, because both are held in the Bitmap object uncompressed.
Regarding Android's call to provide multiple versions of a bitmap/image, why can't only the highest resolution image be used?
E.g if the xxhdpi image is available - will that be able to scale down to all lower density versions or will it just mean it will scale bigger than the allocated size (View)?
PS: If I'm using a background image, does scaling matter? E.g. should I still provide multiple versions of 1 image to fit different pixel densities?
Usually image scaling operation is resourceful and the outcome might be worse than using pre-scaled image.
It has already been answered several times, but I will answer it again. Btw I'm not myself a big pro in Android, but I will try to answer in the best way possible.
Automatic scaling is a thing in Android, but using that is a waste of resource, we already know that using a PNG Graphic asset is a waste of CPU/GPU power when we can use XML for basic designs (which uses less resources), so why waste more power for downscaling it (which increases app opening time and makes it laggy), simply creating multiple sized images for different display sizes is the best option.
A simple and convenient option is to use a free software like Adobe XD which supports export into different sizes.
Simple answer: Avoid using PNG(or other image format), but when you don't have other options do create multiple sizes to save resources.
I don't get why it's recommended to have a drawable (image) for all densities (ldpi, ..., xxhdpi).
Would it not be better to add one file with the highest needed density (xxxhdpi) and than programmatically scale that image down (e.g. for tab icons I could just set a explicit dp size)?
Therefore I would only have to manage one file and the APK file size would be smaller. I think the performance disadvantage should not be significant.
Update 1:
To be more specific: I never noticed any quality loss when using a high density image (PNG file) which was scaled down to a explicit dp value on my mdpi device.
So I was considering if the disadvantages of managing multiple image files as a coder without a designer (and the higher APK file size) might outweigh the advantages. Especially if I'm going to target newer devices (API >= 17).
Update 2:
In my case I'm more a coder than a designer. In the microphone example image of #mes I could just use a high density version of the left microphone and scale it down with no significant disadvantages?
There's no significant advantage, when designer or you simply reduce image size and put inside the ldpi, actual meaning is to paint another image for small size, because there are many cases, when simply reducing an image size produces inacurate and low quality image, and a good designer will draw another image, with few details in it, this is an example, only in this case worth to put different images in different folders
Therefore I would only have to manage one file and the APK file size would be smaller. I think the performance disadvantage should not be significant.
Yes, you are right, there no significant performance improvements, and also apk size is increases, that's why not worth to downscale the same image.
There are two reasons for this:
Typically, devices with lower density screens also tend to have less powerful hardware for image & graphics processing, along with lower memory.
Its not just the density, it is also the file size and image dimensions that are scaled accordingly.
The Android way of having different drawables for different screen form factors is thus appropriate from a technical standpoint.
First advantage is what mes mentioned: different images for different sizes.
Second advantage is memory/code efficiency: a 1000x1000 pixels image on android will take 1000x1000x4 ~= 3.8 mb of memory which is really wasted on smaller screens which can have 16mb available memory per app. You could try loading the bitmaps efficiently but that's a lot of code to put/maintain for each image and also will have performance issues on some cases.
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.
I am trying to understand the reason for having multiple image sizes. I know there are different size screens with different densities, but wouldn't it be acceptable to just have the largest resolution image and load it to the size you need rather than have lots of different images?
Scaling an image takes considerably more processing power than just loading a pre-rendered one. Also, a naive/simple image scaling algorithm would look pretty low quality compared to one that had been actually properly rendered at the right size in the first place.
You could, I suppose, but what about
Bandwidth
Size of original image
Computational overhead
You are right it is acceptable.
As always this is just about trading speed for disk space.
You decide if you increase the size or have your graphics resize at runtime... it depends on your usecase.
It is because you do not have to be processiing a long file over and over again, imagine lots of visitors onto your site all of them requesting the same image they have different resolutions is better to have different images instead being processing the largest image to have a new one for each request, this is because of performance on the server side with an important concurrency in your site this may carry issues for the Heap Space you must care about data process performance. some times you have to choose in between resources Heap Space, Processor and DataSpace.