从装载Picasso的ImageView获取Bitmap

时间:2014-07-10 16:53:21

标签: android bitmap imageview picasso

我有一个方法可以加载图像,如果图像尚未加载,它将在服务器上查找它。然后将其存储在apps文件系统中。如果它在文件系统中,则会加载该图像,因为这比从服务器中提取图像要快得多。如果您在未关闭应用程序之前加载了图像,它将存储在静态字典中,以便可以在不占用更多内存的情况下重新加载,以避免内存不足错误。

这一切都很好,直到我开始使用Picasso图像加载库。现在我将图像加载到ImageView中,但我不知道如何获取返回的Bitmap,以便将其存储在文件或静态字典中。这使事情变得更加困难。因为这意味着它每次都试图从服务器加载图像,这是我不想发生的事情。有没有办法在将Bitmap加载到ImageView后得到它?以下是我的代码:

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 however 
            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);
    }
}

非常感谢任何帮助,谢谢!

5 个答案:

答案 0 :(得分:40)

使用Picasso,您不需要实现自己的静态字典,因为它是自动完成的。 @intrepidkarthi是正确的,因为Picasso第一次加载时会自动缓存图像,因此它不会经常调用服务器来获取相同的图像。

话虽这么说,我发现自己处于类似情况:我需要访问下载的位图,以便将其存储在应用程序的其他位置。为此,我稍微调整了@Gilad Haimov的答案:

Java,旧版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,毕加索的版本为2.71828:

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?) {}

        })

这使您可以访问加载的位图,同时仍然异步加载它。您只需记住在ImageView中设置它,因为它不再自动为您完成。

另一方面,如果您想知道图像的来源,可以使用相同的方法访问该信息。上述方法的第二个参数Picasso.LoadedFrom from是一个枚举,可以让您知道从哪个源加载位图(三个来源为DISKMEMORY和{{1 (Source)。Square Inc.还提供了一种可视方式,通过使用here解释的调试指示器来查看位图的加载位置。

希望这有帮助!

答案 1 :(得分:8)

Picasso让您直接控制下载的图像。要将下载的图像保存到文件中,请执行以下操作:

Picasso.with(this)
    .load(currentUrl)
    .into(saveFileTarget);

其中:

saveFileTarget = new Target() {
    @Override
    public void onBitmapLoaded (final Bitmap bitmap, Picasso.LoadedFrom from){
        new Thread(new Runnable() {
            @Override
            public void run() {
                File file = new File(Environment.getExternalStorageDirectory().getPath() + "/" + FILEPATH);
                try {
                    file.createNewFile();
                    FileOutputStream ostream = new FileOutputStream(file);
                    bitmap.compress(CompressFormat.JPEG, 75, ostream);
                    ostream.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}

答案 2 :(得分:0)

既然你正在使用毕加索,你也可以充分利用它。它包括一个强大的缓存机制。

picasso.setDebugging(true)实例上使用Picasso来查看发生了哪种缓存(图像是从磁盘,内存或网络加载的)。请参阅:http://square.github.io/picasso/(调试指标)

Picasso的默认实例配置为(http://square.github.io/picasso/javadoc/com/squareup/picasso/Picasso.html#with-android.content.Context-

  

LRU内存缓存可用应用程序RAM的15%

     

2%存储空间的磁盘缓存高达50MB但不低于5MB。 (注意:这仅适用于API 14+或者如果您使用的是在所有API级别(如OkHttp)上提供磁盘缓存的独立库)

您还可以使用Cache指定Picasso.Builder实例来自定义您的实例,并且可以指定Downloader以获得更好的控制权。 (Picasso中有OkDownloader的实现,如果您在应用中加入OkHttp,则会自动使用。

答案 3 :(得分:0)

在这个例子中,我用来设置一个colapsing工具栏的背景。

public class MainActivity extends AppCompatActivity {

 CollapsingToolbarLayout colapsingToolbar;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);

  colapsingToolbar = (CollapsingToolbarLayout) findViewById(R.id.colapsingToolbar);
  ImageView imageView = new ImageView(this);
  String url ="www.yourimageurl.com"


  Picasso.with(this)
         .load(url)
         .resize(80, 80)
         .centerCrop()
         .into(image);

  colapsingToolbar.setBackground(imageView.getDrawable());

}

我希望它对你有所帮助。

答案 4 :(得分:-1)

使用此

Picasso.with(context)
.load(url)
.into(imageView new Callback() {
    @Override
    public void onSuccess() {
        //use your bitmap or something
    }

    @Override
    public void onError() {

    }
});

希望对你有帮助