Wie kann man mit glide ein Bild in eine Bitmap herunterladen?

140

Das Herunterladen einer URL in eine ImageViewist mit Glide sehr einfach:

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

Ich frage mich, ob ich auch in eine herunterladen kann Bitmap? Ich möchte eine unformatierte Bitmap herunterladen, die ich dann mit anderen Tools bearbeiten kann. Ich habe den Code durchgesehen und sehe nicht, wie es geht.

Johnny Lambada
quelle

Antworten:

174

Stellen Sie sicher, dass Sie auf der neuesten Version sind

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

Bitmap-Größe:

Wenn Sie die Originalgröße des Bildes verwenden möchten, verwenden Sie den Standardkonstruktor wie oben. Andernfalls können Sie die gewünschte Größe für die Bitmap übergeben

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

Alte Antwort:

Mit compile 'com.github.bumptech.glide:glide:4.8.0'und unten

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

Für compile 'com.github.bumptech.glide:glide:3.7.0'und unter

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

Jetzt sehen Sie möglicherweise eine Warnung SimpleTarget is deprecated

Grund:

Der Hauptgrund für die Ablehnung von SimpleTarget besteht darin, Sie vor den Möglichkeiten zu warnen, mit denen Sie dazu verleitet werden, den API-Vertrag von Glide zu brechen. Insbesondere werden Sie nicht gezwungen, die von Ihnen geladene Ressource nicht mehr zu verwenden, sobald das SimpleTarget gelöscht wurde. Dies kann zu Abstürzen und grafischer Beschädigung führen.

Das SimpleTargetStandbild kann verwendet werden, solange Sie sicherstellen, dass Sie die Bitmap nicht verwenden, sobald die Bildansicht gelöscht wurde.

Max
quelle
10
Ich bin auf Glide 4.0 und kann .asBitmap ()
Chris Nevill
8
Verwenden Sie für synchrone Aufrufe Glide.with (this) .asBitmap (). Load (pictureUrl) .submit (100, 100) .get (). Es kann nützlich sein, wenn Sie ein Symbol in der Benachrichtigung über .setLargeIcon (Bitmap) hinzufügen möchten
Yazon2006
1
@Max diese Arbeit ist für mich in der Implementierung 'com.github.bumptech.glide: glide: 3.6.1'
Bipin Bharti
2
@Nux stellen Sie sicher, dass Sie auf der neuesten Version sind4.9.0
Max
1
.asBitmap()sollte nach gesetzt werden, with(this)wenn es ungelöst ist.
Alston
177

Ich bin mit Glide nicht vertraut genug, aber es sieht so aus, als ob Sie, wenn Sie die Zielgröße kennen, Folgendes verwenden können:

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

Es sieht so aus, als könnten Sie bestehen -1,-1und ein Bild in voller Größe erhalten (nur basierend auf Tests, kann es nicht dokumentiert sehen).

Hinweis into(int,int)gibt a zurück FutureTarget<Bitmap>, daher müssen Sie dies in eine Try-Catch-Blockabdeckung ExecutionExceptionund einwickeln InterruptedException. Hier ist eine vollständigere Beispielimplementierung, die getestet wurde und funktioniert:

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

Nach dem Vorschlag von Monkeyless im Kommentar unten (und dies scheint auch der offizielle Weg zu sein ) können Sie a verwenden SimpleTarget, optional gekoppelt mit override(int,int), um den Code erheblich zu vereinfachen. In diesem Fall muss jedoch die genaue Größe angegeben werden (alles unter 1 wird nicht akzeptiert):

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

wie von @hennry vorgeschlagen, wenn Sie das gleiche Bild benötigen, verwenden Sienew SimpleTarget<Bitmap>()

outlyer
quelle
4
Für die Nachwelt benötigen Sie die asynchrone Aufgabe nicht. Verwenden Sie einfach .override (int, int) und / oder ein SimpleTarget
Sam Judd
2
@ Monkeyless danke, ich habe meine Antwort um Ihren Vorschlag erweitert.
Outlyer
33
Wenn Sie eine Bitmap in Originalgröße erzielen möchten, ist es besser, Target.SIZE_ORIGINALsowohl die Breite als auch die Höhe der Bitmap anstelle von -1 zu übergeben
Alex Bonel
5
Sie erhalten die Bitmap in voller Größe, wenn Sie keine Parameter für SimpleTargetnew SimpleTarget<Bitmap>(){....}
Henry
3
Verwenden Sie in Glide 4.0.0+ .asBitmap () vor.load () und .submit (100, 100) anstelle von .into (100, 100)
Yazon2006
16

Es sieht so aus, als ob das Überschreiben der TargetKlasse oder einer der Implementierungen wie BitmapImageViewTargetund das Überschreiben der setResourceMethode zum Erfassen der Bitmap der richtige Weg sein könnte ...

Dies ist ungetestet. :-)

    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);
                     }
         });
Klinge
quelle
3
Wird die Bitmap nicht die Breite / Höhe der Bildansicht annehmen? Ich hoffe, die ursprüngliche unveränderte Bitmap zu erhalten.
Johnny Lambada
Für Glide 4.0.0+ verwenden Sie .asBitmap () before.load ()
Saeed
10

AKTUALISIEREN

Jetzt müssen wir verwenden Custom Targets

BEISPIELCODE

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

Wie kann man mit glide ein Bild in eine Bitmap herunterladen?

Die vor allem Antwort ist richtig, aber veraltet

denn in neuer Version von Glide implementation 'com.github.bumptech.glide:glide:4.8.0'

Sie finden unten Fehler im Code

  • Das .asBitmap()ist nicht verfügbar inglide:4.8.0

Geben Sie hier die Bildbeschreibung ein

  • SimpleTarget<Bitmap> ist veraltet

Geben Sie hier die Bildbeschreibung ein

Hier ist die Lösung

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
quelle
Wenn Sie asBItmap vor .load versuchen, damit es Ihnen keinen Fehler gibt
Vipul Chauhan
@Spritzig, welches Problem Sie jetzt haben
Nilesh Rathod
@NileshRathod Es zeigt mir kein Symbol kein Fehler nichts, sondern zeigt nur nicht das Symbol.
Nideba
@NileshRathod Hast du das Problem dafür gefunden?
Nideba
7

Dies hat bei mir funktioniert: 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
quelle
4

Wenn Sie Bitmap-Variablen ein dynamisches Bitmap-Bild zuweisen möchten

Beispiel für kotlin

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

Die obigen Antworten haben bei mir nicht funktioniert

.asBitmap sollte vor dem sein .load("http://....")

ramana vv
quelle
4
.into (100, 100) ist veraltet .submit (100, 100)
Yazon2006
Warum gleitet das f so etwas? es ist praktisch die gleiche Verwendung ...
Karkark
2

UPDATE FÜR NEUE 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)

ALTE ANTWORT

Die Antwort von @ outlyer ist korrekt, aber es gibt einige Änderungen in der neuen Glide-Version

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

Hinweis: Dieser Code wird im UI-Thread ausgeführt. Sie können also AsyncTask, Executor oder andere Elemente für die Parallelität verwenden (z. B. @ outlyers Code). Wenn Sie die Originalgröße erhalten möchten, geben Sie Target.SIZE_ORIGINA als meinen Code ein. Verwenden Sie nicht -1, -1

Mạnh Hoàng Huynh
quelle
4
SimpleTarget <Bitmap> ist in der neuen Version veraltet
Nainal
-1

Neuere Version:

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
quelle