web-dev-qa-db-fra.com

Obtenir Bitmap d'ImageView chargé avec Picasso

J'avais une méthode qui charge les images, si l'image n'a pas été chargée avant de la rechercher sur un serveur. Ensuite, il le stocke dans le système de fichiers des applications. S'il se trouve dans le système de fichiers, il charge plutôt cette image, ce qui est beaucoup plus rapide que d'extraire les images du serveur. Si vous avez déjà chargé l'image sans fermer l'application, elle sera stockée dans un dictionnaire statique afin de pouvoir la recharger sans utiliser davantage de mémoire, afin d'éviter les erreurs de mémoire insuffisante.

Tout cela a bien fonctionné jusqu'à ce que je commence à utiliser la bibliothèque de chargement d'images Picasso. Maintenant, je charge des images dans un ImageView, mais je ne sais pas comment récupérer le bitmap renvoyé afin de pouvoir le stocker dans un fichier ou dans le dictionnaire statique. Cela a rendu les choses plus difficiles. parce que cela signifie qu'il essaie de charger l'image à partir du serveur à chaque fois, ce que je ne souhaite pas. Est-il possible d'obtenir le bitmap après l'avoir chargé dans ImageView? Ci-dessous mon 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 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);
    }
}

Toute aide serait grandement appréciée, merci!

10
shadowarcher

Avec Picasso, vous n'avez pas besoin d'implémenter votre propre dictionnaire statique car il est fait automatiquement pour vous. @intrepidkarthi avait raison en ce sens que les images sont automatiquement mises en cache par Picasso lors du premier chargement et que le serveur n'appelle donc pas en permanence pour obtenir la même image. 

Cela étant dit, je me suis trouvé dans une situation similaire: je devais accéder au bitmap qui avait été téléchargé pour pouvoir le stocker ailleurs dans mon application. Pour cela, j'ai modifié un peu la réponse de @Gilad Haimov: 

Java, avec une ancienne version de 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, avec la version 2.71828 de 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?) {}

        })

Cela vous donne accès au bitmap chargé tout en le chargeant de manière asynchrone. Vous devez juste vous rappeler de le définir dans ImageView car ce n'est plus fait automatiquement pour vous. 

En passant, si vous souhaitez savoir d'où provient votre image, vous pouvez accéder à ces informations avec la même méthode. Le deuxième argument de la méthode ci-dessus, Picasso.LoadedFrom from, est une énumération qui vous permet de savoir de quelle source le bitmap a été chargé (les trois sources étant DISK, MEMORY et NETWORK. ( Source ). Square Inc. fournit également une manière visuelle de voir d'où le bitmap a été chargé à l'aide des indicateurs de débogage expliqués ici .

J'espère que cela t'aides !

36
jguerinet

Picasso vous permet de contrôler directement les images téléchargées. Pour enregistrer les images téléchargées dans un fichier, procédez comme suit:

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

Où:

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

Dans cet exemple, j'avais l'habitude de définir l'arrière-plan d'une barre d'outils réductrice.

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

}

J'espère que cela vous a aidé.

0

Puisque vous utilisez Picasso, vous pouvez également en profiter pleinement. Il comprend un mécanisme de mise en cache puissant.

Utilisez picasso.setDebugging(true) sur votre instance Picasso pour afficher le type de mise en cache (les images sont chargées à partir du disque, de la mémoire ou du réseau). Voir: http://square.github.io/picasso/ (indicateurs de débogage)

L'instance par défaut de Picasso est configurée avec ( http://square.github.io/picasso/javadoc/com/squareup/picasso/Picasso.html#with-Android.content.Context- )

Cache mémoire LRU de 15% de la RAM disponible pour l'application

Cache disque de 2% d'espace de stockage jusqu'à 50 Mo mais pas moins de 5 Mo (Remarque: cette option n'est disponible que sur l'API 14+ ou si vous utilisez une bibliothèque autonome fournissant un cache disque à tous les niveaux de l'API, comme OkHttp.)

Vous pouvez également spécifier votre instance Cache en utilisant Picasso.Builder pour personnaliser votre instance, et vous pouvez spécifier votre Downloader pour un contrôle plus précis. (Il existe une implémentation de OkDownloader dans Picasso qui est utilisée automatiquement si vous incluez OkHttp dans votre application.)

0
njzk2