Android 从加载了毕加索的 ImageView 中获取位图

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24682217/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 08:34:51  来源:igfitidea点击:

Get Bitmap from ImageView loaded with Picasso

androidbitmapimageviewpicasso

提问by shadowarcher

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:

这一切都很好,直到我开始使用毕加索图像加载库。现在我正在将图像加载到 ImageView 中,但我不知道如何获取返回的位图,以便我可以将其存储在文件或静态字典中。这让事情变得更加困难。因为这意味着它每次都尝试从服务器加载图像,这是我不想发生的事情。有没有办法在将 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 it threw a null pointer exception, I assume this is because it takes a while for Picasso to add the image to the ImageView

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

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

回答by jguerinet

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.

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

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:

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

Java, with an older version of Picasso:

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, with version 2.71828 of Picasso:

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

        })

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.

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

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.

附带说明一下,如果您想知道图像的来源,可以使用相同的方法访问该信息。上述方法的第二个参数Picasso.LoadedFrom from是一个枚举,让你知道从位图是从(三个来源是装有何种源DISKMEMORYNETWORK。(来源)方公司还提供了观看的可视化的方式,其中位图是通过使用此处解释的调试指示器加载的。

Hope this helps !

希望这可以帮助 !

回答by Gilad Haimov

Picasso gives you direct control over the downloaded images. To save downloaded images into file do something like this:

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

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

Where:

在哪里:

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

回答by njzk2

Since you are using Picasso, you may as well want to take full advantage of it. It includes a powerful caching mechanism.

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

Use picasso.setDebugging(true)on your Picassoinstance to view what kind of caching occurs (images are loaded from disk, memory or network). See : http://square.github.io/picasso/(debug indicators)

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

The default instance of Picasso is configured with (http://square.github.io/picasso/javadoc/com/squareup/picasso/Picasso.html#with-android.content.Context-)

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

LRU memory cache of 15% the available application RAM

Disk cache of 2% storage space up to 50MB but no less than 5MB. (Note: this is only available on API 14+ or if you are using a standalone library that provides a disk cache on all API levels like OkHttp)

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

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

You can also specify your Cacheinstance using Picasso.Builderto customize your instance, and you can specify your Downloaderfor finer control. (There is an implementation of OkDownloaderin Picasso which is used automatically if you include OkHttpin your app.)

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

回答by Thialyson Martins

In this example I used to set the background of a colapsing toolbar.

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

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

}

I hope it helped you.

我希望它对你有帮助。

回答by Madi

Use this

用这个

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

    @Override
    public void onError() {

    }
});

Hope it help you

希望对你有帮助