As the parameterless BitmapDrawable
constructor is deprecated, we have to give resource id to the constructor.
BitmapDrawable bitmapDrawable = new BitmapDrawable(res, bmap);
Where res
is generally getResources()
.
Why does the constructor need it and how can we define that value if we are using a general image cache?
Why does the constructor need it?
From the docs of BitmapDrawable(Resources res, Bitmap bitmap)
:
Create drawable from a bitmap, setting initial target density based on the display metrics of the resources.
So, that is needed in order to set an initial target density using the display metrics, and the DisplayMetrics
would be fetched from the Resources
that you are providing as a parameter to BitmapDrawable
.
How can we define that value if we are using a general image cache?
Sorry, cannot understand the question. Can you rephrase?
If I have already scaled the Bitmap myself, why does BitmapDrawable need resources?
How can BitmapDrawable
know, that you have already scaled the Bitmap
? Normally, if you are creating a BitmapDrawable
you shouldn't take care of scaling it on your own, that's why the API is designed that way.
It seems like the only way to avoid scaling when converting a Bitmap to a Drawable is to use the deprecated constructor?
Although it sounds bad, but you can see how classes from transition framework use that constructor, e.g. ChangeBounds
, Crossfade
.
I've dug sources a bit and found out this chunk of code in Bitmap
class:
static public int scaleFromDensity(int size, int sdensity, int tdensity) {
if (sdensity == DENSITY_NONE || tdensity == DENSITY_NONE || sdensity == tdensity) {
return size;
}
// Scale by tdensity / sdensity, rounding up.
return ((size * tdensity) + (sdensity >> 1)) / sdensity;
}
This is being called in following chain:
* BitmapDrawable#constructor
* BitmapDrawable#updateLocalState()
* BitmapDrawable#computeBitmapSize()
* Bitmap#getScaledWidth()
* scaleFromDensity(getWidth(), mDensity, targetDensity)
What if you explicitly set the density of your Bitmap
to DENSITY_NONE
? Then the if
check will evaluate to true
and no scaling would be performed.
Bitmap bitmap = ...
bitmap.setDensity(Bitmap.DENSITY_NONE);
Haven't tested, just making assumptions based on sources.
In this constructor getResources() is needed "to set initial target density based on the display metrics of the resource". I understand it this way - you take the display metrics, that contain information about size, density, font scaling, and pass this info to constructor. Probably if you will have in your res/
folder image in different sizes - in appropriate sub folders, like drawable-ldpi
, drawable-hdpi
- you will get different information.
To use it in image cache, you need to pass a Context to it, and then invoke like this: Context ctx; ctx.getResources();
Hope that helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With