Come si usa glide per scaricare un'immagine in una bitmap?


141

Scaricare un URL in un ImageViewè molto semplice usando Glide:

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

Mi chiedo se posso scaricare anche in un Bitmap? Vorrei scaricare in una bitmap non elaborata che posso quindi manipolare utilizzando altri strumenti. Ho controllato il codice e non vedo come farlo.

Risposte:


176

Assicurati di essere sulla versione più recente

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

Dimensione bitmap:

se vuoi usare la dimensione originale dell'immagine usa il costruttore predefinito come sopra, altrimenti puoi passare la dimensione desiderata per bitmap

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

Giava:

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

Vecchia risposta:

Con compile 'com.github.bumptech.glide:glide:4.8.0'e sotto

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

Per compile 'com.github.bumptech.glide:glide:3.7.0'e sotto

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

Ora potresti vedere un avviso SimpleTarget is deprecated

Motivo:

Il punto principale di deprecare SimpleTarget è avvertirti dei modi in cui ti tenta di rompere il contratto API di Glide. In particolare, non fa nulla per costringerti a smettere di usare qualsiasi risorsa che hai caricato una volta cancellato SimpleTarget, il che può portare a arresti anomali e corruzione grafica.

Il SimpleTargetfermo immagine può essere utilizzato purché si assicuri di non utilizzare la bitmap dopo aver eliminato imageView.


10
Sono su Glide 4.0 e non riesco a trovare .asBitmap ()
Chris Nevill il

8
Per le chiamate sincrone utilizzare Glide.with (questo) .asBitmap (). Load (pictureUrl) .submit (100, 100) .get (). Può essere utile quando si desidera aggiungere l'icona nella notifica tramite .setLargeIcon (bitmap)
Yazon2006

1
@Max questo lavoro è per me nell'implementazione 'com.github.bumptech.glide: glide: 3.6.1'
Bipin Bharti

2
@Nux assicurati di essere sull'ultima versione4.9.0
Max

1
.asBitmap()dovrebbe essere messo dopo with(this)se è irrisolto.
Alston,

177

Non ho abbastanza familiarità con Glide, ma sembra che se conosci la dimensione del bersaglio, puoi usare qualcosa del genere:

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

Sembra che tu possa passare -1,-1e ottenere un'immagine a dimensione intera (basata esclusivamente su test, non può vederla documentata).

Nota into(int,int)restituisce a FutureTarget<Bitmap>, quindi devi avvolgerlo in un blocco di prova che copre ExecutionExceptione InterruptedException. Ecco un'implementazione di esempio più completa, testata e funzionante:

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

Seguendo il suggerimento di Monkeyless nel commento qui sotto (e questo sembra essere anche il modo ufficiale ), puoi usare un SimpleTarget, opzionalmente accoppiato con override(int,int)per semplificare notevolmente il codice. Tuttavia, in questo caso deve essere fornita la dimensione esatta (non è accettato nulla al di sotto di 1):

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

come suggerito da @hennry se hai richiesto la stessa immagine, utilizzanew SimpleTarget<Bitmap>()


4
Per i posteri, non è necessario il compito asincrono, basta usare .override (int, int) e / o un SimpleTarget
Sam Judd,

2
@Monkeyless grazie, ho ampliato la mia risposta per includere il tuo suggerimento.
Outlyer

33
Se vuoi ottenere una bitmap nella dimensione originale, è meglio passare Target.SIZE_ORIGINALsia per la larghezza che per l'altezza della bitmap anziché -1
Alex Bonel,

5
Otterrai la bitmap a dimensione intera se non fornisci alcun parametro per SimpleTargetquesto:new SimpleTarget<Bitmap>(){....}
Henry,

3
In Glide 4.0.0+ usa .asBitmap () before.load () e .submit (100, 100) invece di .into (100, 100)
Yazon2006

16

Sembra che sovrascrivere la Targetclasse o una delle implementazioni simili BitmapImageViewTargete sovrascrivere il setResourcemetodo per acquisire la bitmap potrebbe essere la strada da percorrere ...

Questo non è testato. :-)

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

3
Bitmap non assume la larghezza / altezza di imageView? Spero di ottenere la Bitmap inalterata originale.
JohnnyLambada,

Per Glide 4.0.0+ utilizzare .asBitmap () before.load ()
Saeed

10

AGGIORNARE

Ora dobbiamo usare Custom Targets

CODICE DI ESEMPIO

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

Come si usa glide per scaricare un'immagine in una bitmap?

Le risposte soprattutto sono corrette ma obsolete

perché nella nuova versione di Glide implementation 'com.github.bumptech.glide:glide:4.8.0'

Di seguito troverai l'errore nel codice

  • Il .asBitmap()non è disponibile inglide:4.8.0

inserisci qui la descrizione dell'immagine

  • SimpleTarget<Bitmap> è deprecato

inserisci qui la descrizione dell'immagine

Ecco la soluzione

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

Se provi asBItmap prima di .load in modo che non ti dia alcun errore
Vipul Chauhan

@Spritzig quale problema stai affrontando ora
Nilesh Rathod,

@NileshRathod Non mi mostra alcun errore, ma non mostra l'icona.
nideba,

@NileshRathod Hai trovato il problema per questo?
nideba,

7

Questo è ciò che ha funzionato per me: 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());
            }
        });
    }
});

4

Se si desidera assegnare un'immagine bitmap dinamica a variabili bitmap

Esempio per kotlin

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

Le risposte sopra non hanno funzionato per me

.asBitmap dovrebbe essere prima del .load("http://....")


4
.into (100, 100) è obsoleto utilizzare .submit (100, 100)
Yazon2006

perché la f scivola deprecando cose come questa? è praticamente lo stesso uso ...
kkarakk,

2

AGGIORNAMENTO PER NUOVA VERSIONE

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)

VECCHIA RISPOSTA

La risposta di @ outlyer è corretta, ma ci sono alcune modifiche nella nuova versione di Glide

La mia versione: 4.7.1

Codice:

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

Nota: questo codice viene eseguito nel thread dell'interfaccia utente, quindi puoi utilizzare AsyncTask, Executor o qualcos'altro per la concorrenza (come il codice di @ outlyer) Se vuoi ottenere le dimensioni originali, inserisci Target.SIZE_ORIGINA come mio codice. Non usare -1, -1


4
SimpleTarget <Bitmap> è obsoleto nella nuova versione
Nainal

-1

Versione più nuova:

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) } }
    })
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.