what is advantage of multiple drawable? - android

most resources have pointed out that when we using (ldpi, mdpi,hdpi, xhdpi,xxhdpi,xxxhdpi), the android doesn't need to rescale image and we won't have cpu overhead for rescaling image.
but i didn't got that point yet, suppose i have an icon image with all size that already mentioned (36px, 48px, 72px, 96px, 144px and 192px), well, in bellow code you see i use 40dp that it doesn't match any above sizes, so android would rescale the image again, then what is advantage if multiple drawable?
<ImageView
android:layout_width="40dp"
android:layout_height="40dp"
android: src="#drawable/icon"
/>

You'll often not have an image with an exact Pixel match for the DPs you describe in the layout -- like the case you describe above. When this happens Android will still need to do some scaling.
The benefit isn't CPU savings, its Memory savings.
Scaling operations on large images can require a great deal of memory, especially if scaling from small to large, or large to small.
If you're starting with an image that is close and only need to scale a little, the memory cost is less significant.
If an image is w500px, h500px, that is 250000 pixels. Even if that image is a jpg and compressed to be 10kb on the disk, scaling requires Android to convert to RGB or ARGB which is 3 or 4 bytes per pixel.
4 bytes x 250000 = 1M of memory.
500px on a device that is XXXHDPI is only about 1 inch on the screen.
So you can see how this can add up quickly.
EDIT: This might be useful https://developer.android.com/topic/performance/graphics/load-bitmap.html

Contrary to what Aaron says, the benefit of providing these images is not about system resources, it is about how your app will look to users on different devices. By providing high-resolution copies of the same image, users on high-resolution devices will see crisp, clear images instead of upscaled fuzzy images.
Your question mentions specific pixel dimensions for an image. I assume these values are taken from https://developer.android.com/guide/practices/screens_support.html
36x36 (0.75x) for low-density
48x48 (1.0x baseline) for medium-density
72x72 (1.5x) for high-density
96x96 (2.0x) for extra-high-density
144x144 (3.0x) for extra-extra-high-density
192x192 (4.0x) for extra-extra-extra-high-density
When you provide all of these different resolutions for your image, you are not providing different physical sizes. Of course 144x144 is three times larger than 48x48, but this 144x144 image will not appear three times larger when the user sees it on their device.
The system will only choose to display the 144x144 image when the user has a device with a high-resolution screen. This means the individual pixels in their display will be smaller, which means the 144x144 image will take up the same physical space as the 48x48 would on a lower-resolution screen.
In short: all of the images in this example are 48dp x 48dp.
Now, if you display this image in an ImageView that is 40dp x 40dp, the image will either be cropped or scaled down. But this has nothing to do with the extra images you've provided. Whether on a very low-resolution screen or a very high-resolution screen, the system will still be stuffing a 48x48 image into a 40x40 container.
Update
Here's an example. I've used Android Studio's New -> Image Asset menu to create an image. You can see that AS generates multiple copies of the same image with different dimensions:
Next, I create two emulators:
Nexus S (hdpi): http://www.gsmarena.com/samsung_google_nexus_s-3620.php
Nexus 5 (xxhdpi): http://www.gsmarena.com/lg_nexus_5-5705.php
And then I run an app that just displays my image on both of them:
You can see that the status bars, action bars, and the little android all appear the same size. But the Nexus S is displaying the hdpi image (48px x 48px) while the Nexus 5 is displaying the xxhdpi image (96px x 96px). Both look sharp!
Finally, I delete all copies of my image except for the mdpi one. Now both emulators use the mdpi image, but you can see that they still display at the same size. The image's intrinsic size is 32dp x 32dp, so even though both emulators are using a 32px x 32px image, both have to scale it up (the Nexus S has to scale it 1.5x and the Nexus 5 has to scale it 3x).
As you can see, the little android is the same size, but it looks much worse. This is why you provide copies of the same image at different resolutions: so that your images always appear crisp!

Related

One PNG image for all densities

Can I use just one png image big enough for all densities? Or do I need to create one png image for every density?
I tries placing just one png image in drawable folder but it becomes blurry. So I placed that same image in the drawable-xxhdpi (my test device density) and it shows correctly (clear). I guess that the blurry effect is because it is multiplying for the scale factor of the screen density. The idea should be to say to Android to take the big image (xxxhdpi) and make it smaller (never bigger).

How to use the different densities (mdpi, hdpi, xhdpi, ...)

I see a lot of post on this topic, however I haven't seen an explanation on what image size to take as a reference, let me explain.
I want to add a background image and make it suitable for each phone screen size so from mdpi to xxhdpi (if I'm not talking nonsense)
What size should my base image be?
I used a 600x1200 image and a 1080x1920 then converts using this site
https://romannurik.github.io/AndroidAssetStudio/
Unfortunately I noticed that on my two phones the image was distorted, I'm starting to think my base image size was wrong
So my question
What image size should I take to then create multiple densities ?
Sorry if it's redundant !!!
I'm starting to learn how to adapt and it's not that easy
If you want to create a background picture, your reference size is mdpi with 320x480px. You can then calculate the size according to the factor
hdpi: 1.5 (480x720)
xhdpi: 2.0 (640x960)
xxhdpi: 3.0 (960x1440)
xxxhdpi: 4.0 (1280x1920)
Note however, that nowadays devices have all kinds of other aspect ratios (mostly longer). So you have to design your background in a way, that the outer area does not contain important content. Then use ScaleType CENTER_CROP and your image should not be distorted (https://developer.android.com/reference/android/widget/ImageView.ScaleType)
I think the site is for (mainly launcher) icons.
If your target device's display has 1080x1920 size with xxhdpi (3x) density, just put an image of the size in the res/drawables/xxhdpi folder. No other densities are needed to be prepared. They will be re-scaled from the xxhdpi image if needed.
If you still want to prepare for those densities, first prepare the highest density. If you want to use xxxhdpi (4x), you should start with xxxhdpi sized image. Then scale it down to xxhdpi (3x), xhdpi (2x), hdpi (1.5x) and mdpi (1x).
xxxhdpi (4x): 100%
xxhdpi (3x): 75%
xhdpi (2x): 50%
hdpi (1.5x): 37.5%
mdpi (1x): 25%
Support different pixel densities: Provide alternative bitmaps

minimum pixels of the largest image's side to fit android xxhdpi screen

I'm making an android App that shows images at full screen.
I learned some about dpi and dp, but I didn't find how many pixel must be the largest side of my images (in prospective to good fit also in landscape mode) to appear good in different devices.
As in the documentation, the most used screen configurations are normal with hdpi, xhdpi and xxhdpi density:
So, if my thinking is correct, I can make only one image to fit the xxhdpi to works fine also with the other two densities, and put it in Android Studio under the "res/drawable" folder (without qualifier).
Specifying the image size in dp in the layout, Android should scale the image for the smaller configurations.
But, for the xxhdpi, how many pixel must be the largest side of my image, in pixel, to show good?
Edit: how many pixel must be the longest side of my image to be showed properly in a device with xxhdpi density without the image appearing grainy?
All images are photo, not icons, so I can't use the vector graphics.
By looking at the Android Documentation. One can estimate the size of the picture. look at below picture
So, your image resolution should be in similar resolution
LDPI: 200 X 320px
MDPI: 320 X 480px
HDPI: 480 X 800px
XHDPI: 720 X 1280px
XXHDPI: 960 X 1600px
XXXHDPI: 1440 x 2560px
A little bit of +/- won't affect the outcome because with these standard sizes the aspect ratio of any portrait picture should be respected.
Well, if you put the image which fits the xxxhdpi inside the folder drawable, then it will fit all the screens.
But there is another way to use only one image instead of using multiple images for different resolutions. It's by using svg images which are vector images that will not be affected by zoom in or zoom out.
To use svg you need to follow these instructions:
Make the icon to be icon.svg
In the Android Studio, right click on drawable folder
Choose New -> Vector Asset
Choose Local File (SVG, PSD)
Choose your svg file
Click Next and choose the name
Click Finish
In the app build.gradle add the following inside android block:
vectorDrawables {
useSupportLibrary true
}
In the xml layout file, add the following:
<AppCompatImageView
android:width="wrap_content"
android:height="wrap_content"
app:srcCompat="#drawable/your_svg_file"
/>
Android have ratios defined for a image to set in all different drawables
Android icons require five separate sizes for different screen pixel densities. Icons for lower resolution are created automatically from the baseline.
mdpi: 160 dpi 1×
hdpi: 240 dpi 1.5×
xhdpi: 320 dpi 2×
xxhdpi: 480 dpi 3×
xxxhdpi:640 dpi 4×
Above size is for normal pixel icons. There are fix android size for Action bar, Dialog & Tab icons, Launcher icons & Notification icons
Check this link for more details http://iconhandbook.co.uk/reference/chart/android/
You have to take a look at the current market of smartphones.
Here you can see the screen sizes and resolutions of the most popular devices in the market.
http://screensiz.es/
Order the list in pixel per inch and you will see that top smartphones have resolutions bigger than 500 ppi or another way to see it, much bigger than 72ppi of your images.
If you have enough space to store or mechanism to download images try to test with full quality. If thats too much try to find a compromise. Lower image quality and see the result in high resolution screen.
Note that you didn't posted here the total size of image, in case is bigger than screen size, take a look at total size of image and compress it to fit your needs, maintaining as much as possible the resolution.
Edit: Looking only to size of image in pixels, the current biggest screen in smartphone is 2560 x 1440 pixels, so you wont need any image bigger than this.
If I understand your answer correctly, you are talking about images (pictures of lovely cats and dogs?) and not about icons?
I prefer putting images into the nodpi folder.
nodpi Resources for all densities. These are density-independent
resources. The system does not scale resources tagged with this
qualifier, regardless of the current screen's density.
Afterwards I would create a fullscreen ImageView and let imageView do the scaling if needed

Scaling image resources in Android and Picasso

There are so many material on densities, multiple screen support, so many questions on SO, but I still have not got it.
My goal is simple: display a bitmap as large as available space for ImageView. I need BitMap as I will do some operations on it.
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/figureView" />
I will have some pictures to be used in the bitmap. I will place them in drawables directory. I will reference them with R.drawable.pictureX. I will use Picasso to load them and scale them:
Bitmap bitmap = Picasso.with(getContext()).load(resourceId).resize(w, h).get();
The unclear part for me is all those xxhdpi folders and Android heuristic to select the best.
When a documentation says that Android will automatically scale the image does it apply to my case? I do not want to scale already scaled pictured.
How many dpi variants shall I store in my case and where? Shall I have single file in no-dpi folder or shall I create picture variant for each dpi folder?
How can I determine a dimension for picture resource? It is easy for icons: for example 24x24 dpi and then multiple it with DPI formula. But I want to cover complete screen height. A chapter Configuration examples lists: 240x320 ldpi, 320x480 mdpi, 480x800 hdpi, 720x1280 mdpi, 800x1280 mdpi etc. There are no screen size qualifiers for resources.
Thanks for clarification.
I realized that in fact it is easy to find out Android behavior. I just need each DPI variant different so I can distinguish between them. I put a text with DPI name and pixel resolution inside each picture.
There is a sample GitHub Test DPI project. It has two ImageViews. The first is initialized from XML and Android does scaling. The second is a placeholder that I fill with a BitMap. I entered 200dp as its size and that was correct. Pixel size of MDPI = size in dp.
What I found is logical. Android does not know anything about my intentions. It just selects the best available resource for current DPI.
Nexus 5x uses XXHDPI by default, Samsung SIII Mini uses HDPI. If I delete their default DPI folders, they down-scale higher available variant: XXXHDPI and XHDPI. If I delete all variants except NODPI, this will be used.
And finally if I change the dimensions of ImageView dynamically loaded from source code to 300dp, then it will be scaled and look ugly. Android cannot know at decodeResource execution that I will scale it later and that there is a better resource available.
What remains unknown is how to find out dimensions of picture that fits the screen.
Java:
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inScaled = false;
Bitmap figureBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_test, opt);
ImageView imageView=(ImageView) findViewById(R.id.testView);
imageView.setImageBitmap(figureBitmap);
Activity:
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_test" />
<ImageView
android:id="#+id/testView"
android:layout_width="200dp"
android:layout_height="200dp" />
Update 30th august
Original picture: 230x541 px, loading with
Picasso.with(getContext()).load(R.drawable.amalka).into(target)
stored in nodpi, loaded as 230x541 px Bitmap
stored in xxhdpi, loaded as 230x541 px Bitmap
1.Android will automatically scale image in case when you provided image for one screen dencity and there is no such image for another one. e.g. if you add your image only in drawable-xxxhdpi folder, Android will generate images for xxhdpi, xhdpi screen dencities etc.
2.You can save your image in one folder drawable-xxxhdpi and let Android make the downscale, if you don't like the result you can create images for different dencities on your own.
name dencity scale
mdpi 160dpi x1
hdpi 240dpi x1.5
xhdpi 320dpi x2
xxhdpi 480dpi x3
xxxhdpi 640dpi x4
3.You can define dimensions of your images based on size of you ImageView and dpi scale. For example if your ImageView has width 80dp and height 40dp then your image for drawable-mdpi folder should have size 80x40px because mdpi is a baseline dencity, for drawable-hdpi then you need to have image 120x60px (scale is 1.5) etc. For drawable-xxxhdpi your image will be 320x160px.
If you want your image to fit all the screen on all devices you can use parameter android:scaleType="centerCrop", it will make the image take all the space but little part of image can be hidden depending on screen aspect ratio. You can also try to specify image resorces based on shortest dimension of the available screen area, e.g. drawable-sw720dp. Read more about this here.

What sizes do I scale an image to in order to achieve resolution independance

My app consists of a round ball whose radius I have specified as 35 pixels in the code. The user muse prevent the ball from colliding with other balls.
I have drawn an 800 px by 800 px vector graphic with 72 ppi resolution that I want to use as the bitmap for this image.
What sizes do I scale the image to for the drawable-ldpi, -mdpi and -hdpi folders so that the bitmap is the same size on all devices and also so that the collision detection works fine ? i.e. The app calculates the ball to be 35 pixels but the screen shows a smaller or larger image so the collisions will be all wrong and the user won't know what's going on.
I really don't know much about this so any help will be hugely appreciated.
From the android developer guide:
To create alternative bitmap drawables for different densities, you
should follow the 3:4:6:8 scaling ratio between the four generalized
densities. For example, if you have a bitmap drawable that's 48x48
pixels for medium-density screen (the size for a launcher icon), all
the different sizes should be:
36x36 for low-density
48x48 for medium-density
72x72 for high-density
96x96 for extra high-density
Also, one of the best practices for supporting multiple screen resolutions is: "Do not use hard-coded pixel values in your application code".
Since your applications deals with pixel values at runtime, you might want to read the section Additional Density Considerations and below that section.

Categories

Resources