Comment utiliser glide pour télécharger une image dans un bitmap?

141

Le téléchargement d'une URL dans un ImageViewest très simple avec Glide:

Glide
   .with(context)
   .load(getIntent().getData())
   .placeholder(R.drawable.ic_loading)
   .centerCrop()
   .into(imageView);

Je me demande si je peux aussi télécharger dans un Bitmap? Je voudrais télécharger dans un bitmap brut que je peux ensuite manipuler à l'aide d'autres outils. J'ai parcouru le code et je ne vois pas comment le faire.

JohnnyLambada
la source

Réponses:

176

Assurez-vous que vous êtes sur la dernière version

implementation 'com.github.bumptech.glide:glide:4.10.0'

Kotlin:

Glide.with(this)
        .asBitmap()
        .load(imagePath)
        .into(object : CustomTarget<Bitmap>(){
            override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
                imageView.setImageBitmap(resource)
            }
            override fun onLoadCleared(placeholder: Drawable?) {
                // this is called when imageView is cleared on lifecycle call or for
                // some other reason.
                // if you are referencing the bitmap somewhere else too other than this imageView
                // clear it here as you can no longer have the bitmap
            }
        })

Taille du bitmap:

si vous souhaitez utiliser la taille d'origine de l'image utilisez le constructeur par défaut comme ci-dessus, sinon Vous pouvez passer la taille souhaitée pour le bitmap

into(object : CustomTarget<Bitmap>(1980, 1080)

Java:

Glide.with(this)
        .asBitmap()
        .load(path)
        .into(new CustomTarget<Bitmap>() {
            @Override
            public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
                imageView.setImageBitmap(resource);
            }

            @Override
            public void onLoadCleared(@Nullable Drawable placeholder) {
            }
        });

Ancienne réponse:

Avec compile 'com.github.bumptech.glide:glide:4.8.0'et ci-dessous

Glide.with(this)
        .asBitmap()
        .load(path)
        .into(new SimpleTarget<Bitmap>() {
            @Override
            public void onResourceReady(Bitmap resource, Transition<? super Bitmap> transition) {
                imageView.setImageBitmap(resource);
            }
        });

Pour compile 'com.github.bumptech.glide:glide:3.7.0'et ci-dessous

Glide.with(this)
        .load(path)
        .asBitmap()
        .into(new SimpleTarget<Bitmap>() {
            @Override
            public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
                imageView.setImageBitmap(resource);
            }
        });

Maintenant, vous pourriez voir un avertissement SimpleTarget is deprecated

Raison:

Le point principal de la désapprobation de SimpleTarget est de vous avertir de la manière dont il vous tente de rompre le contrat d'API de Glide. Plus précisément, il ne fait rien pour vous forcer à cesser d'utiliser les ressources que vous avez chargées une fois que SimpleTarget est effacé, ce qui peut entraîner des plantages et une corruption graphique.

La SimpleTargetphoto peut être utilisée tant que vous vous assurez de ne pas utiliser le bitmap une fois que l'imageView est effacée.

Max
la source
10
Je suis sur Glide 4.0 et je n'arrive pas à trouver .asBitmap ()
Chris Nevill
8
Pour les appels synchrones, utilisez Glide.with (this) .asBitmap (). Load (pictureUrl) .submit (100, 100) .get (). Cela peut être utile lorsque vous souhaitez ajouter une icône dans la notification via .setLargeIcon (bitmap)
Yazon2006
1
@Max ce travail est pour moi dans l'implémentation 'com.github.bumptech.glide: glide: 3.6.1'
Bipin Bharti
2
@Nux assurez-vous que vous êtes sur la dernière version4.9.0
Max
1
.asBitmap()devrait être mis après with(this)s'il n'est pas résolu.
Alston
177

Je ne connais pas assez Glide, mais il semble que si vous connaissez la taille cible, vous pouvez utiliser quelque chose comme ceci:

Bitmap theBitmap = Glide.
        with(this).
        load("http://....").
        asBitmap().
        into(100, 100). // Width and height
        get();

Il semble que vous puissiez réussir -1,-1et obtenir une image en taille réelle (uniquement basée sur des tests, vous ne pouvez pas la voir documentée).

Remarque into(int,int)renvoie a FutureTarget<Bitmap>, vous devez donc envelopper ceci dans un bloc try-catch couvrant ExecutionExceptionet InterruptedException. Voici un exemple d'implémentation plus complet, testé et fonctionnel:

class SomeActivity extends Activity {

    private Bitmap theBitmap = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // onCreate stuff ...
        final ImageView image = (ImageView) findViewById(R.id.imageView);

        new AsyncTask<Void, Void, Void>() {
            @Override
            protected Void doInBackground(Void... params) {
                Looper.prepare();
                try {
                    theBitmap = Glide.
                        with(SomeActivity.this).
                        load("https://www.google.es/images/srpr/logo11w.png").
                        asBitmap().
                        into(-1,-1).
                        get();
                 } catch (final ExecutionException e) {
                     Log.e(TAG, e.getMessage());
                 } catch (final InterruptedException e) {
                     Log.e(TAG, e.getMessage());
                 }
                 return null;
            }
            @Override
            protected void onPostExecute(Void dummy) {
                if (null != theBitmap) {
                    // The full bitmap should be available here
                    image.setImageBitmap(theBitmap);
                    Log.d(TAG, "Image loaded");
                };
            }
        }.execute();
    }
}

Suite à la suggestion de Monkeyless dans le commentaire ci-dessous (et cela semble être la méthode officielle aussi ), vous pouvez utiliser un SimpleTarget, éventuellement associé à override(int,int)pour simplifier considérablement le code. Cependant, dans ce cas, la taille exacte doit être fournie (tout ce qui est inférieur à 1 n'est pas accepté):

Glide
    .with(getApplicationContext())
    .load("https://www.google.es/images/srpr/logo11w.png")
    .asBitmap()
    .into(new SimpleTarget<Bitmap>(100,100) {
        @Override
        public void onResourceReady(Bitmap resource, GlideAnimation glideAnimation) {
            image.setImageBitmap(resource); // Possibly runOnUiThread()
        }
    });

comme suggéré par @hennry si vous avez besoin de la même image, utiliseznew SimpleTarget<Bitmap>()

outlyer
la source
4
Pour la postérité, vous n'avez pas besoin de la tâche asynchrone, utilisez simplement .override (int, int) et / ou un SimpleTarget
Sam Judd
2
@Monkeyless merci, j'ai élargi ma réponse pour inclure votre suggestion.
outlyer
33
Si vous voulez obtenir un bitmap à sa taille d'origine, il vaut mieux passer Target.SIZE_ORIGINALà la fois pour la largeur et la hauteur du bitmap au lieu de -1
Alex Bonel
5
Vous obtiendrez le bitmap en taille réelle si vous ne fournissez aucun paramètre pour SimpleTargetce type:new SimpleTarget<Bitmap>(){....}
Henry
3
Dans Glide 4.0.0+, utilisez .asBitmap () before.load () et .submit (100, 100) au lieu de .into (100, 100)
Yazon2006
16

Il semble que remplacer la Targetclasse ou l'une des implémentations comme BitmapImageViewTargetet remplacer la setResourceméthode pour capturer le bitmap pourrait être la voie à suivre ...

Ceci n'a pas été testé. :-)

    Glide.with(context)
         .load("http://goo.gl/h8qOq7")
         .asBitmap()
         .into(new BitmapImageViewTarget(imageView) {
                     @Override
                     protected void setResource(Bitmap resource) {
                         // Do bitmap magic here
                         super.setResource(resource);
                     }
         });
lame
la source
3
Le Bitmap ne prendra-t-il pas la largeur / hauteur de l'imageView? J'espère obtenir le Bitmap original non modifié.
JohnnyLambada
Pour Glide 4.0.0+, utilisez .asBitmap () before.load ()
Saeed
10

METTRE À JOUR

Maintenant, nous devons utiliser Custom Targets

CODE D'ÉCHANTILLON

    Glide.with(mContext)
            .asBitmap()
            .load("url")
            .into(new CustomTarget<Bitmap>() {
                @Override
                public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {

                }

                @Override
                public void onLoadCleared(@Nullable Drawable placeholder) {
                }
            });

Comment utiliser glide pour télécharger une image dans un bitmap?

La réponse ci-dessus est correcte mais obsolète

car dans la nouvelle version de Glide implementation 'com.github.bumptech.glide:glide:4.8.0'

Vous trouverez ci-dessous une erreur dans le code

  • Le .asBitmap()n'est pas disponible dansglide:4.8.0

entrez la description de l'image ici

  • SimpleTarget<Bitmap> est obsolète

entrez la description de l'image ici

Voici la solution

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ImageView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.request.Request;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.SizeReadyCallback;
import com.bumptech.glide.request.target.Target;
import com.bumptech.glide.request.transition.Transition;



public class MainActivity extends AppCompatActivity {

    ImageView imageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        imageView = findViewById(R.id.imageView);

        Glide.with(this)
                .load("")
                .apply(new RequestOptions().diskCacheStrategy(DiskCacheStrategy.NONE))
                .into(new Target<Drawable>() {
                    @Override
                    public void onLoadStarted(@Nullable Drawable placeholder) {

                    }

                    @Override
                    public void onLoadFailed(@Nullable Drawable errorDrawable) {

                    }

                    @Override
                    public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {

                        Bitmap bitmap = drawableToBitmap(resource);
                        imageView.setImageBitmap(bitmap);
                        // now you can use bitmap as per your requirement
                    }

                    @Override
                    public void onLoadCleared(@Nullable Drawable placeholder) {

                    }

                    @Override
                    public void getSize(@NonNull SizeReadyCallback cb) {

                    }

                    @Override
                    public void removeCallback(@NonNull SizeReadyCallback cb) {

                    }

                    @Override
                    public void setRequest(@Nullable Request request) {

                    }

                    @Nullable
                    @Override
                    public Request getRequest() {
                        return null;
                    }

                    @Override
                    public void onStart() {

                    }

                    @Override
                    public void onStop() {

                    }

                    @Override
                    public void onDestroy() {

                    }
                });

    }

    public static Bitmap drawableToBitmap(Drawable drawable) {

        if (drawable instanceof BitmapDrawable) {
            return ((BitmapDrawable) drawable).getBitmap();
        }

        int width = drawable.getIntrinsicWidth();
        width = width > 0 ? width : 1;
        int height = drawable.getIntrinsicHeight();
        height = height > 0 ? height : 1;

        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
        drawable.draw(canvas);

        return bitmap;
    }
}
Nilesh Rathod
la source
Si vous essayez asBItmap avant .load, cela ne vous donnera aucune erreur
Vipul Chauhan
@Spritzig quel problème vous rencontrez maintenant
Nilesh Rathod
@NileshRathod Il ne me montre pas d'icône aucune erreur, rien mais seulement ne montre pas l'icône.
nideba
@NileshRathod Avez-vous trouvé le problème?
nideba
7

C'est ce qui a fonctionné pour moi: https://github.com/bumptech/glide/wiki/Custom-targets#overriding-default-behavior

import com.bumptech.glide.Glide;
import com.bumptech.glide.request.transition.Transition;
import com.bumptech.glide.request.target.BitmapImageViewTarget;

...

Glide.with(yourFragment)
  .load("yourUrl")
  .asBitmap()
  .into(new BitmapImageViewTarget(yourImageView) {
    @Override
    public void onResourceReady(Bitmap bitmap, Transition<? super Bitmap> anim) {
        super.onResourceReady(bitmap, anim);
        Palette.generateAsync(bitmap, new Palette.PaletteAsyncListener() {  
            @Override
            public void onGenerated(Palette palette) {
                // Here's your generated palette
                Palette.Swatch swatch = palette.getDarkVibrantSwatch();
                int color = palette.getDarkVibrantColor(swatch.getTitleTextColor());
            }
        });
    }
});
Stephen Kaiser
la source
4

Si vous souhaitez affecter une image bitmap dynamique à des variables bitmap

Exemple pour kotlin

backgroundImage = Glide.with(applicationContext).asBitmap().load(PresignedUrl().getUrl(items!![position].img)).into(100, 100).get();

Les réponses ci-dessus n'ont pas fonctionné pour moi

.asBitmap devrait être avant le .load("http://....")

ramana vv
la source
4
.into (100, 100) est obsolète, utilisez .submit (100, 100)
Yazon2006
pourquoi le f glide désapprouve-t-il des trucs comme ça? c'est pratiquement le même usage ...
kkarakk
2

MISE À JOUR POUR UNE NOUVELLE VERSION

Glide.with(context.applicationContext)
    .load(url)
    .listener(object : RequestListener<Drawable> {
        override fun onLoadFailed(
            e: GlideException?,
            model: Any?,
            target: Target<Drawable>?,
            isFirstResource: Boolean
        ): Boolean {
            listener?.onLoadFailed(e)
            return false
        }

        override fun onResourceReady(
            resource: Drawable?,
            model: Any?,
            target: com.bumptech.glide.request.target.Target<Drawable>?,
            dataSource: DataSource?,
            isFirstResource: Boolean
        ): Boolean {
            listener?.onLoadSuccess(resource)
            return false
        }

    })
    .into(this)

ANCIENNE RÉPONSE

La réponse de @ outlyer est correcte, mais il y a quelques changements dans la nouvelle version de Glide

Ma version: 4.7.1

Code:

 Glide.with(context.applicationContext)
                .asBitmap()
                .load(iconUrl)
                .into(object : SimpleTarget<Bitmap>(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL) {
                    override fun onResourceReady(resource: Bitmap, transition: com.bumptech.glide.request.transition.Transition<in Bitmap>?) {
                        callback.onReady(createMarkerIcon(resource, iconId))
                    }
                })

Remarque: ce code s'exécute dans UI Thread, vous pouvez donc utiliser AsyncTask, Executor ou autre chose pour la concurrence (comme le code de @ outlyer) Si vous voulez obtenir la taille d'origine, mettez Target.SIZE_ORIGINA comme code. N'utilisez pas -1, -1

Mạnh Hoàng Huynh
la source
4
SimpleTarget <Bitmap> est obsolète dans la nouvelle version
Nainal
-1

Version plus récente:

GlideApp.with(imageView)
    .asBitmap()
    .override(200, 200)
    .centerCrop()
    .load(mUrl)
    .error(R.drawable.defaultavatar)
    .diskCacheStrategy(DiskCacheStrategy.ALL)
    .signature(ObjectKey(System.currentTimeMillis() / (1000*60*60*24))) //refresh avatar cache every day
    .into(object : CustomTarget<Bitmap>(){
        override fun onLoadCleared(placeholder: Drawable?) {}
        override fun onLoadFailed(errorDrawable: Drawable?) {
            //add context null check in case the user left the fragment when the callback returns
            context?.let { imageView.addImage(BitmapFactory.decodeResource(resources, R.drawable.defaultavatar)) }
        }
        override fun onResourceReady(
            resource: Bitmap,
            transition: Transition<in Bitmap>?) { context?.let { imageView.addImage(resource) } }
    })
mrj
la source