In my project I used (Volley + NetworkImageView) to download some images and texts and showing them in a list view.. till here, I don't have any problem.
Now, I want to get bitmaps form NetworkImageView and I tried many methods like the following, but non of them worked for me.
BitmapDrawable drawable = (BitmapDrawable) imageView.getDrawable();
Bitmap bitmap = drawable.getBitmap();
Another method:
imageView.buildDrawingCache();
Bitmap bmap = imageView.getDrawingCache();
Non of them worked..
Any Help is appreciated,,
You cannot get the Bitmap reference as it is never saved in the ImageView.
however you can get it using :
((BitmapDrawable)this.getDrawable()).getBitmap();
beacuse when you set it with Volley u do this:
/**
* Sets a Bitmap as the content of this ImageView.
*
* #param bm The bitmap to set
*/
#android.view.RemotableViewMethod
public void setImageBitmap(Bitmap bm) {
// Hacky fix to force setImageDrawable to do a full setImageDrawable
// instead of doing an object reference comparison
mDrawable = null;
if (mRecycleableBitmapDrawable == null) {
mRecycleableBitmapDrawable = new ImageViewBitmapDrawable(
mContext.getResources(), bm);
} else {
mRecycleableBitmapDrawable.setBitmap(bm);
}
setImageDrawable(mRecycleableBitmapDrawable);
}
however if you set your default image or error image or any other image in any other way you may not get BitmapDrawable but NinePatchDrawable for example.
here is how to check:
Drawable dd = image.getDrawable();
if(BitmapDrawable.class.isAssignableFrom(dd.getClass())) {
//good one
Bitmap bb = ((BitmapDrawable)dd).getBitmap();
} else {
//cannot get that one
}
Related
ALL,
As suggested here I need to make a drawable out of my bitmap. But when I tried to use:
Drawable d = new Drawable( my_bmp);
it shows that this constructor is deprecated in favour of:
Drawable(Bitmap bmp, int resourceId)
How else I can make a drawable out of bitmap?
Thank you.
You can use
Drawable d = new BitmapDrawable(getResources(), my_bmp);
A Drawable that wraps a bitmap and can be tiled, stretched, or
aligned. You can create a BitmapDrawable from a file path, an input
stream, through XML inflation, or from a Bitmap object.
BitmapDrawable(Resources res, Bitmap bitmap)
Create drawable from a bitmap, setting initial target density based on
the display metrics of the resources.
Also look a the public constructors #
http://developer.android.com/reference/android/graphics/drawable/BitmapDrawable.html
try this to load Bitmap as Bitmap Drawable
Create ImgDrawableFromFile(Resources res, String file_name) like below
Drawable d = null;
public Drawable ImgDrawableFromFile(Resources res, String file_name) {
myBitmap = null;
File imgFile = new File(
"/data/data/yourpkgname/app_my_sub_dir/images/" + file_name);
if (imgFile.exists()) {
myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
if (myBitmap != null) {
d = new BitmapDrawable(res, myBitmap);
return d;
} else {
return null;
}
}
return null;
}
Now called this function like
img.setBackgroundDrawable(ImgDrawableFromFile(getResources(), "1.jpg")); // pass your saved file name as second argument
A little late to the party but I see a clear misunderstanding. The answers provided are indeed correct:
Drawable d = new BitmapDrawable(getResources(),bitmap);
In this case getResources() is a method available in the Context or Activity and is only used to find out the screen density and adjust the Drawable accordingly.
So Igor, even if you are loading the image from the cloud, you can still call getResources().
Happy coding
BitmapDrawable(Bitmap bitmap) constructor has been deprecated
you can use
Drawable drawable = new BitmapDrawable(getResources(), bitmap);
source
you can use the BitmapDrawable class to get a Drawable from a bitmap
Bitmap Drawable reference
If Mauro Banze was late to the party then I don't really know what I'm still doing here. But for the ones that come here desperately looking for a solution, here is what I did:
I stumbled over somewhat the same issue when bringing a Project from JavaFX to Android. I wanted to reuse most of my "data" classes which only manage and provide my data and have no affect on the UI.
Enough story telling, here we go:
Problem:
At some point we need a Drawableto get out Bitmap on the screen.
We want to download (from the cloud, the internet, or wherever) this Bitmap and save it for later usage as a Drawable
We can't do that in a non-Context or non-Activity class, as we need the Resources.
So why don't we just save it as a Bitmap until we need it to be drawn (which certainly will happen in a Context or Activity class).
I have created a class called BitmapImage. It looks like this:
public class BitmapImage {
private final Bitmap bitmap;
public BitmapImage (Bitmap bitmap) {
this.bitmap = bitmap;
}
public Bitmap getBitmap() {
return bitmap;
}
public Drawable getDrawable(Resources res) {
return new BitmapDrawable(res,getBitmap());
}
This very simple class "saves" the Bitmap. Thus, rather then working with a Drawable you work with the BitmapImage until you really desperately need the Drawable.
At that point, you should be in your Activity or Context and there you can call Drawable foo = anyBitmapImage.getDrawable(getResource()).
in my app i change the resource of an ImageView a lot of times with this method:
private void setIcon(int id, int imageSource) {
((ImageView)findViewById(id)).setBackgroundResource(imageSource);
}
After a while i get an OutOfMemoryException. Is there a better method to free the old resource (image) before i load the new one?
EDIT
private void setIcon(int id, int imageSource) {
ImageView imageView = (ImageView)findViewById(id);
Drawable bg= imageView.getBackground();
if(bg != null && bg instanceof BitmapDrawable) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) bg;
bitmapDrawable.getBitmap().recycle();
if(D)Log.d(TAG, "recycled bitmap");
}
Bitmap bm = BitmapFactory.decodeResource(getResources(), imageSource);
imageView.setImageBitmap(bm);
}
Before setting the new background, try to clear the memory for the old one, like this:
Drawable bg = image.getBackground();
if(bg != null && bg instanceof BitmapDrawable) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) bg;
bitmapDrawable.getBitmap().recycle();
}
Do you have specific reasons to set the backgroundResource? Can't you simply use image.setResource(). That way it is easier to obtain the bitmap and recycle it.
Edit: if you only want one image (no overlays or something) than this is easier (and how it's supposed to be):
ImageView image = (ImageView)findViewById(id);
image.setImageResource(imageSource);
Using bitmaps:
Bitmap bm = BitmapFactory.decodeResource(getResources(), id);
image.setImageBitmap(bm);
image.getDrawable(); // will return a BitmapDrawable
In my app I want to swap images at runtime when user clicks on it.
there are two imageviews when user click on first image and then click on second image at the same time I'm fetching bitmap of first imageview's image and assigning to second imageview for this I used following code:
public Bitmap createBitmap(ImageView imageview) {
imageview.setDrawingCacheEnabled(true);
imageview.buildDrawingCache(false);
if(imageview.getDrawingCache() != null) {
Bitmap bitmap = Bitmap.createBitmap(imageview.getDrawingCache());
imageview.setDrawingCacheEnabled(false);
return bitmap;
} else {
return null;
}
}
Code is working fine but the cache not cleared every time and the bitmap created with previous cache so how I can clear a bitmap cache?
This is a sample e.g. where i use to Free the native object associated with this bitmap.
Bitmap bitmap;
public Bitmap createBitmap(ImageView imageview) {
if (bitmap != null) {
bitmap.recycle();
bitmap = null;
}
bitmap = Bitmap.createBitmap(imageview.getDrawingCache());
// Your Code of bitmap Follows here
}
Before use of Bitmap just free the object.
use bitmap.recycle(); before valuating your bitmaps to clear their cache before recreating it.
I get an Bitmap from internal storage or from the internet. When I try to display it in a ImageView, it works on different Emulator versions but not on my Galaxy S I9000. The Bitmap simply doesn't show up.
protected void onPostExecute (Bitmap bmp) {
progressBar.setVisibility(View.INVISIBLE);
if (bmp != null) {
imageView.setImageBitmap(bmp);
imageView.setVisibility(View.VISIBLE);
}
}
This is highly likely to be an underlying issue with openGL not accepting textures larger than 2400x2400. It doesn't cause crashes, but fails by not displaying the Bitmap in an ImageView.
You should always ensure that the Bitmap is smaller than 2400 in both dimensions and resize it before setting it on your view if it is larger.
I used this method to help me in displaying the image
public static Drawable ToDrawable(Resources r, byte[] encodedString)
{
if (encodedString == null)
return null;
Bitmap bmp = BitmapFactory.decodeByteArray(encodedString, 0, encodedString.length);
Drawable drawable = new BitmapDrawable(r, bmp);
// bmp.recycle();
return drawable;
}
I tried to get Bitmap attached to an ImageView, using ImageView.getDrawingCache(); But I found that the returned Bitmap was not the same as I'd like to get from the ImageView. It was always smaller than the real image.
I had known that, the method getDrawingCache() should not have the view if it is bigger than the screen as the visible portion of the view is only drawn and the cache holds only what is drawn.
Could I get the whole bitmap attached to a ImageView?
If you just want the Bitmap from a ImageView the following code may work for you:-
Bitmap bm=((BitmapDrawable)imageView.getDrawable()).getBitmap();
I think that's what you wanted.
If your drawble is not always an instanceof BitmapDrawable
Note: ImageView should be set before you do this.
Bitmap bitmap;
if (mImageView.getDrawable() instanceof BitmapDrawable) {
bitmap = ((BitmapDrawable) mImageView.getDrawable()).getBitmap();
} else {
Drawable d = mImageView.getDrawable();
bitmap = Bitmap.createBitmap(d.getIntrinsicWidth(), d.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
d.draw(canvas);
}
Your bitmap is stored in bitmap.
Voila!
Easiest way is to set tag in ImageView.
imageView.setImageBitmap(bitmap);
imageView.setTag(bitmap);
To get Tag from it
imageView.getTag();