Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PicassoDrawable cannot be cast to BitmapDrawable #38

Closed
sdqhzhm opened this issue May 22, 2013 · 23 comments
Closed

PicassoDrawable cannot be cast to BitmapDrawable #38

sdqhzhm opened this issue May 22, 2013 · 23 comments

Comments

@sdqhzhm
Copy link

sdqhzhm commented May 22, 2013

onDraw() in my CustomImageView

Drawable drawable = getDrawable();
Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();

java.lang.ClassCastException: com.squareup.picasso.PicassoDrawable cannot be cast to android.graphics.drawable.BitmapDrawable

@JakeWharton
Copy link
Member

If you want access to the Bitmap directly then you'll need to use the Target callbacks. The PicassoDrawable is used to allow fading and the debug indicator.

@hboregio
Copy link

hboregio commented Sep 4, 2013

Hey @JakeWharton I'm having the same issue (I need to access the Drawable after loading the image to apply some effects). What exactly do you mean by the Target callbacks? Thanks.

@dnkoutso
Copy link
Collaborator

dnkoutso commented Sep 4, 2013

private Target target = new Target() {
      @Override
      public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {       
      }

      @Override
      public void onBitmapFailed() {
      }
    }

private void someMethod() {
   Picasso.with(this).load("url").into(target);
}

@Override public void onDestroy() {  // could be in onPause or onStop
   Picasso.with(this).cancelRequest(target);
}

Don't create anonymous class of Target when calling Picasso as might get garbage collected. Keep a member field as a strong reference to prevent it from being gc'ed.

@hboregio
Copy link

hboregio commented Sep 4, 2013

Perfect, thanks!

@trietbui85
Copy link

So, if I load image into an ImageView first. And later, I want to retrieve its Bitmap to share/save..., then I must call Picasso.with(this).load("url").into() twice? One for into(imageview), and one for into(target)?

@JakeWharton
Copy link
Member

If you know you want the Bitmap then you should always use Target and set
it on the ImageView yourself.
On Dec 19, 2013 7:38 AM, "anticafe" notifications@github.com wrote:

So, if I load image into an ImageView first. And later, I want to retrieve
its Bitmap to share/save..., then I must call
Picasso.with(this).load("url").into() twice? One for into(imageview), and
one for into(target)?


Reply to this email directly or view it on GitHubhttps://github.com//issues/38#issuecomment-30938162
.

@kjakah08
Copy link

kjakah08 commented Aug 9, 2014

I am trying to download, insert the image into a Drawable and append to an EditText. I have the following configuration. I do not believe the method onBitmapLoaded, is being called, How can I call that method so the functionality works?

Code:

                        @Override
                        public void onBitmapLoaded(Bitmap bitmap,
                                LoadedFrom loaded) {
                            Drawable drawImage = new BitmapDrawable(
                                    getBaseContext().getResources(), bitmap);


                            messageHistoryText.append(Html.fromHtml("<b>"
                                    + username + ":" + "</b>" + "<br>"));
                            messageHistoryText.append(Html.fromHtml(message
                                    + "<hr>" + "<br>")
                                    + System.getProperty("line.separator") + "");

                            messageHistoryText.append(Html
                                    .fromHtml("<img src = '" + drawImage
                                            + "'/>"));
                        }

@MizzleDK
Copy link

MizzleDK commented Aug 9, 2014

First of all, that's a horrible design. It would never work, but even if it did, it'd be a horrible way of doing things. You can't use a Drawable as the source of an image in HTML. That's just not possible.

I'd suggest you start from scratch and work on a better design that uses Android's native components, i.e. layouts of Views and ViewGroups, rather than what you're trying to do. It'll be easier to deal with, it'll be much better performance-wise and you'll be doing something that feels home on the platform.

Also, this is rather off-topic. Not related to this issue. Ask questions on sites like StackOverflow if you have any issues.

@dallasgutauckis
Copy link

Whoa. Not exactly the worst in the world. After all this concept does
exist. Consider what an emoji is. See
http://developer.android.com/reference/android/text/style/ImageSpan.html
On Aug 8, 2014 8:32 PM, "Michell Bak" notifications@github.com wrote:

First of all, that's a horrible design. It would never work, but even if
it did, it'd be a horrible way of doing things. You can't use a Drawable as
the source of an image in HTML. That's just not possible.

I'd suggest you start from scratch and work on a better design that uses
Android's native components, i.e. layouts of Views and ViewGroups, rather
than what you're trying to do. It'll be easier to deal with, it'll be much
better performance-wise and you'll be doing something that feels home on
the platform.


Reply to this email directly or view it on GitHub
#38 (comment).

@kjakah08
Copy link

kjakah08 commented Aug 9, 2014

Yes, I'm simply building a prototype. Is there a simple configuration to do what I am trying to do. ie. Download image from a URL and then append to an EditText? Either using Picasso or another straightforward configuration?

@MizzleDK
Copy link

MizzleDK commented Aug 9, 2014

@dallasgutauckis There's a big difference between ImageSpan and what he's trying to achieve. He's mixing HTML code and Java objects, expecting it to work.

@kjakah08 Like I said, this isn't really the place for this kind of support. Anyway, you could probably make it work by converting the image data to base64 and use that in your HTML code. It's rather hacky and nasty, though. I wonder if there's not a better way to do what you're looking to do. Downloading an image to display in an EditText seems rather odd.

@dnkoutso
Copy link
Collaborator

dnkoutso commented Aug 9, 2014

Are you using an anonymous Target? Please make your view implement target otherwise it gets gc'ed.

What you do in onBitmapLoaded() is up to you!

@kjakah08
Copy link

kjakah08 commented Aug 9, 2014

@dnkoutso Yes I am using an anonymous target. How can I get the view to implement target?

@dnkoutso
Copy link
Collaborator

dnkoutso commented Aug 9, 2014

public class MyView extends something implements Target

@kjakah08
Copy link

kjakah08 commented Aug 9, 2014

@dnkoutso How can I implement target if the view is within the onCreate in Android? as

protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);

        setContentView(R.layout.message); // messaging_screen);

        messageHistoryText = (EditText) findViewById(R.id.messageHistory);

        messageText = (EditText) findViewById(R.id.message);

@dnkoutso
Copy link
Collaborator

dnkoutso commented Aug 9, 2014

Either update your XML to return your custom view that implements the Target or just have a private field on top of your class that is the target.

Please look online for a short tutorial on how to do this and/or learn about WeakReferences.

@kjakah08
Copy link

kjakah08 commented Aug 9, 2014

@dnkoutso Thank you for the help! Any suggestions for the tutorial?

@kjakah08
Copy link

@dnkoutso Thank you, I discovered the method below, and putting that on another thread seamlessly allowed me to do exactly what I was attempting, no Picasso required:

public static Drawable LoadImageFromWebOperations(String url) {
        try {
            InputStream is = (InputStream) new URL(url).getContent();
            Drawable d = Drawable.createFromStream(is, "src name");
            return d;
        } catch (NullPointerException e) {
            e.printStackTrace();

        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

@akadouri
Copy link

akadouri commented Sep 9, 2014

@kjakah08 Using InputStream won't include image caching

@kjakah08
Copy link

kjakah08 commented Sep 9, 2014

@akadouri Will there be an issue if caching is not enabled?

@akadouri
Copy link

akadouri commented Sep 9, 2014

@kjakah08 you're going to be redowloading the images every time, you also have to wrap that call in an AsyncTask or something or it'll be running on the main thread, and you're also going to have to cancel the call if its not complete by the time the user leaves the screen. The whole point of the Picasso library is that it does the call, cache, transformations, etc for you. If you look at https://github.com/square/picasso/blob/master/picasso/src/main/java/com/squareup/picasso/Downloader.java you can see that they use InputStream to download as well.

@sanatpandey
Copy link

@kjakah08 I am having the same problem, that I want to use the drawables that are generated by the Picasso for Image Caching Purpose, but I am not able to get the same. Here is the code which I am using to access the Bitmap Drawables :

Target targetBitmap = new Target() {

            @Override
            public void onPrepareLoad(Drawable arg0) {

            }

            @Override
            public void onBitmapLoaded(Bitmap arg0, Picasso.LoadedFrom arg1) {
                mBitmap = arg0;
                BitmapDrawable d = new BitmapDrawable(context.getResources(), arg0);

                int margin = 2;
                int border = 0;

                Rect r = new Rect(margin, margin, width - margin, height - margin);

                int imageWidth = r.width();
                int imageHeight = r.height();

                if (imageHeight > r.height() - (border * 2)) {
                    imageHeight = r.height() - (border * 2);
                }

                r.left += ((r.width() - imageWidth) / 2) - border;
                r.right = r.left + imageWidth + border + border;
                r.top += ((r.height() - imageHeight) / 2) + border;
                r.bottom = r.top + imageHeight + border + border;

                Paint p = new Paint();
                p.setColor(0xFFFFFF);

                c.drawRect(r, p);
                r.left += border;
                r.right -= border;
                r.top += border;
                r.bottom -= border;
                d.setBounds(r);
                d.draw(c);
            }

            @Override
            public void onBitmapFailed(Drawable arg0) {

            }
        };

        Picasso.with(context).load(app.getListBookDetails().get(img_num).getImage_150x225()).into(targetBitmap);

But here onBitmapLoaded method is never called. How can I access this method ? Please help if you can. I have scratched everything but has gone all in vain.

Thanks
Sanat

@kjakah08
Copy link

I went away from Picasso and used a java method to pull straight from the
internet, in Android it turned out to be allot easier!

On Mon, Sep 22, 2014 at 9:06 AM, sanatpandey notifications@github.com
wrote:

@kjakah08 https://github.com/kjakah08 I am having the same problem,
that I want to use the drawables that are generated by the Picasso for
Image Caching Purpose, but I am not able to get the same. Here is the code
which I am using to access the Bitmap Drawables :

Target targetBitmap = new Target() {

        @Override
        public void onPrepareLoad(Drawable arg0) {

        }

        @Override
        public void onBitmapLoaded(Bitmap arg0, Picasso.LoadedFrom arg1) {
            mBitmap = arg0;
            BitmapDrawable d = new BitmapDrawable(context.getResources(), arg0);

            int margin = 2;
            int border = 0;

            Rect r = new Rect(margin, margin, width - margin, height - margin);

            int imageWidth = r.width();
            int imageHeight = r.height();

            if (imageHeight > r.height() - (border * 2)) {
                imageHeight = r.height() - (border * 2);
            }

            r.left += ((r.width() - imageWidth) / 2) - border;
            r.right = r.left + imageWidth + border + border;
            r.top += ((r.height() - imageHeight) / 2) + border;
            r.bottom = r.top + imageHeight + border + border;

            Paint p = new Paint();
            p.setColor(0xFFFFFF);

            c.drawRect(r, p);
            r.left += border;
            r.right -= border;
            r.top += border;
            r.bottom -= border;
            d.setBounds(r);
            d.draw(c);
        }

        @Override
        public void onBitmapFailed(Drawable arg0) {

        }
    };

    Picasso.with(context).load(app.getListBookDetails().get(img_num).getImage_150x225()).into(targetBitmap);

But here onBitmapLoaded method is never called. How can I access this
method ? Please help if you can. I have scratched everything but has gone
all in vain.

Thanks
Sanat


Reply to this email directly or view it on GitHub
#38 (comment).

Kimiebi J. Akah
Cell: 614-446-4288

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants