【问题标题】:Get Bitmap from ImageView loaded with Picasso从加载毕加索的 ImageView 中获取 Bitmap
【发布时间】:2014-09-01 03:55:15
【问题描述】:

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

这一切都很好,直到我开始使用 Picasso 图像加载库。现在我正在将图像加载到 ImageView 中,但我不知道如何获取返回的位图,以便将其存储在文件或静态字典中。这让事情变得更加困难。因为这意味着它每次都尝试从服务器加载图像,这是我不希望发生的事情。有没有办法在将位图加载到 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);

下面这行是我尝试检索位图时抛出空指针异常,我认为这是因为毕加索需要一段时间才能将图像添加到 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);
    }
}

任何帮助将不胜感激,谢谢!

【问题讨论】:

  • 毕加索不会每次都从服务器加载图像。只有在第一次然后它从缓存目录加载。

标签: android bitmap imageview picasso


【解决方案1】:

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

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

Java,带有旧版本的毕加索:

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,Picasso 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 是一个枚举,它让您知道从哪个源加载位图(三个源是DISKMEMORYNETWORK。(Source) . Square Inc. 还提供了一种通过使用here 解释的调试指示器来查看位图从何处加载的可视方式。

希望这会有所帮助!

【讨论】:

  • onPrepareLoad 中的问号和 onBitmapFailed 拯救了我的一天。
  • 我无法覆盖 Target 的方法,我收到错误“此类型是最终类型,因此无法继承自”..
  • 您使用的是什么版本的毕加索?看起来它可能在最新的东西中被重命名为BitmapTarget
  • 仅供参考,以防有人犯了我犯的错误。请确保您从 com.square.picasso 中选择“目标”界面,就像 i.stack.imgur.com/Xvmbb.png 一样。否则你将找不到那个 onBitmapLoaded 方法。上面的 kotlin 代码对我有用。
  • 我尝试了同样的方法,但图片没有加载到我的 recycleview 中。
【解决方案2】:

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

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

【讨论】:

  • 这也可以用 Drawable 来完成吗? (我尝试将 tp 附加到 EditText)我没有收到任何错误,但它不起作用
【解决方案3】:

既然您使用的是毕加索,您不妨充分利用它。它包括一个强大的缓存机制。

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

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

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

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

您还可以使用Picasso.Builder 指定您的Cache 实例来自定义您的实例,并且您可以指定您的Downloader 以进行更精细的控制。 (Picasso 中有一个OkDownloader 的实现,如果您在应用中包含OkHttp,它会自动使用。)

【讨论】:

    【解决方案4】:

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

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

    希望对你有所帮助。

    【讨论】:

    • imageView.getDrawable() 为空
    【解决方案5】:

    使用这个

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

    希望对你有帮助

    【讨论】:

    • onSuccess() 不提供 Bitmap 对象。
    猜你喜欢
    • 1970-01-01
    • 2017-05-09
    • 2020-05-02
    • 2015-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-09
    • 2016-03-12
    相关资源
    最近更新 更多