Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get Bitmap from ImageView loaded with Picasso

I had a method that loads images, if the image has not been loaded before it will look for it on a server. Then it stores it in the apps file system. If it is in the file system it loads that image instead as that is much faster than pulling the images from the server. If you have loaded the image before without closing the app it will be stored in a static dictionary so that it can be reloaded without using up more memory, to avoid out of memory errors.

This all worked fine until I started using the Picasso image loading library. Now I'm loading images into an ImageView but I don't know how to get the Bitmap that is returned so that I can store it in a file or the static dictionary. This has made things more difficult. because it means it tries to load the image from the server every time, which is something I don't want to happen. Is there a way I can get the Bitmap after loading it into the ImageView? Below is my code:

public Drawable loadImageFromWebOperations(String url,
        final String imagePath, ImageView theView, Picasso picasso) {
    try {
        if (Global.couponBitmaps.get(imagePath) != null) {
            scaledHeight = Global.couponBitmaps.get(imagePath).getHeight();
            return new BitmapDrawable(getResources(),
                    Global.couponBitmaps.get(imagePath));
        }
        File f = new File(getBaseContext().getFilesDir().getPath()
                .toString()
                + "/" + imagePath + ".png");

        if (f.exists()) {
            picasso.load(f).into(theView);

This line below was my attempt at retrieving the bitmap it threw a null pointer exception, I assume this is because it takes a while for Picasso to add the image to the ImageView

            Bitmap bitmap = ((BitmapDrawable)theView.getDrawable()).getBitmap();
            Global.couponBitmaps.put(imagePath, bitmap);
            return null;
        } else {
            picasso.load(url).into(theView);
            return null;
        }
    } catch (OutOfMemoryError e) {
        Log.d("Error", "Out of Memory Exception");
        e.printStackTrace();
        return getResources().getDrawable(R.drawable.default1);
    } catch (NullPointerException e) {
        Log.d("Error", "Null Pointer Exception");
        e.printStackTrace();
        return getResources().getDrawable(R.drawable.default1);
    }
}

Any help would be greatly appreciated, thank you!

like image 958
shadowarcher Avatar asked Jul 10 '14 16:07

shadowarcher


People also ask

How will you load an image into an ImageView from an image URL using Picasso?

Image loading using Picasso is very easy, you can do it like this way Picasso. get(). load("http://i.imgur.com/DvpvklR.png").into(imageView); and in their website you can get every details. In your case you can parse every image URL and use RecyclerView to show them along with Picasso.

How do you load an image from a file and set on an ImageView?

If you're working with an Android application, this source code works as a way to load an image from a file: Bitmap bitmap = BitmapFactory. decodeFile(pathToPicture);

Can ImageView display video?

ImageView is a control which display image on android and support RGB image, so setting the data of ImageView every period can generate dynamic video.


1 Answers

With Picasso you don't need to implement your own static dictionary because it is done automatically for you. @intrepidkarthi was right in the sense that the images are automatically cached by Picasso the first time they are loaded and so it doesn't constantly call the server to get the same image.

That being said, I found myself in a similar situation: I needed to access the bitmap that was downloaded in order to store it somewhere else in my application. For that, I tweaked @Gilad Haimov's answer a bit:

Java, with an older version of Picasso:

Picasso.with(this)
    .load(url)
    .into(new Target() {

        @Override
        public void onBitmapLoaded (final Bitmap bitmap, Picasso.LoadedFrom from) {
            /* Save the bitmap or do something with it here */

            // Set it in the ImageView
            theView.setImageBitmap(bitmap); 
        }

        @Override
        public void onPrepareLoad(Drawable placeHolderDrawable) {}

        @Override
        public void onBitmapFailed(Drawable errorDrawable) {}
});

Kotlin, with version 2.71828 of Picasso:

Picasso.get()
        .load(url)
        .into(object : Target {

            override fun onBitmapLoaded(bitmap: Bitmap, from: Picasso.LoadedFrom) {
                /* Save the bitmap or do something with it here */

                // Set it in the ImageView
                theView.setImageBitmap(bitmap)
            }

            override fun onPrepareLoad(placeHolderDrawable: Drawable?) {}

            override fun onBitmapFailed(e: Exception?, errorDrawable: Drawable?) {}

        })

This gives you access to the loaded bitmap while still loading it asynchronously. You just have to remember to set it in the ImageView as it's no longer automatically done for you.

On a side note, if you're interested in knowing where your image is coming from, you can access that information within that same method. The second argument of the above method, Picasso.LoadedFrom from, is an enum that lets you know from what source the bitmap was loaded from (the three sources being DISK, MEMORY, and NETWORK. (Source). Square Inc. also provides a visual way of seeing where the bitmap was loaded from by using the debug indicators explained here.

Hope this helps !

like image 76
jguerinet Avatar answered Sep 21 '22 13:09

jguerinet