How to create BitmapDrawable from a file for different screen densities? - android

Well know that if we put an image 96x96 pixel in folder xxhdpi of project, it will be displayed in 32dp.
Now I have an image file 96x96 pixel, which is located on storage. I create a BitmapDrawable object from that image. All I want is: the image should be displayed in 32dp.
Here is what I tried:
BitmapDrawable bmd = (BitmapDrawable)BitmapDrawable.createFromPath(localFile.getAbsolutePath());
bmd.setTargetDensity(DENSITY_XXHIGH);
But it doesn't work. It looks smaller than 32dp. Can anybody show me how to do it?

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).

Another bitmap's sizes

I added bitmap image to drawable folder with 64x64 sizes. Then I get a reference to this by Bitmap b = BitmapFactory.decodeResource(getResources(), R.drawable.brick); The problem is in output I get an image with 128x128 sizes. I dont use any BitmapFactory.Options. Why it happens?
I added bitmap image to drawable folder with 64x64 sizes
I am going to assume that you mean this literally, and you put the images in res/drawable/. That is a synonym for res/drawable-mdpi/.
The problem is in output I get an image with 128x128 sizes.
That would occur if your device is an -xhdpi device. Android will resample the drawable from -mdpi (~160dpi) to -xhdpi (~320dpi).
Try moving your image to res/drawable-nodpi/.

Images in the 'drawable' folder are resized automatically?

I have a 1280x720px image in the res/drawable folder (not the drawable-hdpi, drawable-ldpi, etc. folder). But at runtime the size is 2560x1440px. How is this possible? Does android resize the images in the drawable folder?
Here is the code:
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.start_image_left);
int h = bitmap.getHeight(), w = bitmap.getWidth();
I'm testing this on a Motorola Moto G gen2.
There's really no reason you should ever put a bitmap into the root drawable directory. It should typically be used for XML drawables only. Bitmaps in the drawable directory will essentially be handled as if they were in drawable-mdpi (scaled up proportionally for other densities).
If your goal is to have a bitmap image that is the same pixel size on all densities, you need to put it in drawable-nodpi. This will cause it to not be scaled.
You are correct, Android automatically scales your image based on the current device configuration. If however, you dont want that behaviour, you can create a bitmap resource file, put in the drawable folder and point it to the drawable you want to use like this
<bitmap xmlns:android="http://schemas.android.com/apk/res/android
android:src="#drawable/yourDrawableHere"
android:gravity="center" />
By specifying the center gravity, android will not scale your image no matter what.
To use this bitmap resource file, in your code, retrieve it like this
Drawable drawable = getResources().getDrawable(R.drawable.yourBitmaoResourceFileName);

setImageDrawable don't scale correctly with no resource images

I'm trying to load a image stored in filesystem into a imageButton. But it not scaling correctly. The file is the same (t700.png) in drawable resources and in filesystem, but the result is diferent.
This work fine:
button.setImageDrawable(getResources().getDrawable(R.drawable.t700));
This change scale / size and get bigger image:
String filePath = VideoActivity.this.getFilesDir()+File.separator+EPGApiService.LOGOS_DIR+File.separator+channel.getLogoFile();
Bitmap bitmap = BitmapFactory.decodeFile(filePath);
BitmapDrawable imgDrawable = new BitmapDrawable( this.getResources(),bitmap);
button.setImageDrawable(imgDrawable);
I need same result..
NOTE:
if I do
BitmapDrawable logoBitmapDrawableFromDisk = new BitmapDrawable(VideoActivity.this.getResources(),logoBitmap);
BitmapDrawable logoBitmapDrawableFromDisk2 = new BitmapDrawable(logoBitmap);
BitmapDrawable logoBitmapDrawableFromRes = (BitmapDrawable) getResources().getDrawable(R.drawable.t700);
The Drawables Bitmaps sizes are not the same!
logoBitmapDrawableFromDisk size is 410x123
logoBitmapDrawableFromDisk2 size is 205x62
logoBitmapDrawableFromRes size is 820x246
The real file is the same. I need the same size on this two ways.
BitmapDrawable(getResources(), bitmap)
Create drawable from a bitmap, setting initial target density based on the display metrics of the resources.
It looks bigger because it is using the resource object to adjust the image to your screen's density.
To avoid that use BitmapDrawable(bitmap)
Or resize your png to look right in a mdpi device.
Then BitmapDrawable(getResources(), bitmap) will give you the correct look in all devices.
The correct way to have same look in all devices is create different icons for each device density.
Start with the dimension for mdpi density. The dimensions for each the other densities should be calculated based in the following values:
hdpi multiply by 1.5
xhdpi multiply by 2
xxhdpi multiply by 3
Each icon should be put under separate folders with the appropriate name depending on density:
mdpi -> res/drawable_mdpi
hdpi -> res/drawable_hdpi
xhdpi -> res/drawable_xhdpi
xxhdpi -> res/drawable_xxhdpi
Set the ImageButton source in xml or use getResources().getDrawable(R.drawable.t700); the device will automatically select the right one.
For more information see this

Retrieve a Bitmap with a Fixed size

When you get a bitmap from a resource for example with:
Bitmap src = BitmapFactory.decodeResource(getResources(), R.drawable.yourimage);
It is automatically scaled depending on the device's screen density. How can I avoid that and retrieve it in its original pixel size whatever the screen density is?
Thanks
What do you mean "It is automatically scaled"? When you call this method Android takes image from folder res/drawable-?dpi - depending on device where app is running. If your ldpi folder contains 30*30px image, mdpi contains 40*40px image and hdpi contains 60*60px, you will get bitmap one of this sizes(depends on device). Android does not change anything.
If you see that on the screen your image scaled somehow, check properties of ImageView.

Categories

Resources