192

Downloading a URL into an ImageView is very easy using Glide:

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

I'm wondering if I can download into a Bitmap as well? I'd like to download into a raw bitmap that I can then manipulate using other tools. I've been through the code and don't see how to do it.

AskNilesh
  • 67,701
  • 16
  • 123
  • 163
JohnnyLambada
  • 12,700
  • 11
  • 57
  • 61

15 Answers15

267

Make sure you are on the Lastest 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
            }
        })

Bitmap Size:

if you want to use the original size of the image use the default constructor as above, else You can pass your desired size for 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) {
            }
        });

Old Answer:

With compile 'com.github.bumptech.glide:glide:4.8.0' and below

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

For compile 'com.github.bumptech.glide:glide:3.7.0' and below

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

Now you might see a warning SimpleTarget is deprecated

Reason:

The main point of deprecating SimpleTarget is to warn you about the ways in which it tempts you to break Glide's API contract. Specifically, it doesn't do anything to force you to stop using any resource you've loaded once the SimpleTarget is cleared, which can lead to crashes and graphical corruption.

The SimpleTarget still can be used as long you make sure you are not using the bitmap once the imageView is cleared.

Atiq
  • 14,435
  • 6
  • 54
  • 69
  • 11
    I'm on Glide 4.0 and can't seem to find .asBitmap() – Chris Nevill Aug 24 '17 at 17:26
  • Be careful, you should supply the limit image size to be scaled otherwise there's a chance the image could be large than which OpenGL can handle (approximate 4000 * 4000) and couldn't be loaded. Example: new SimpleTarget(512,512) – Hoang Nguyen Huu Sep 13 '17 at 15:30
  • Has to be called from main thread, otherwise throws exception! – Jemshit Feb 14 '18 at 13:08
  • 11
    For synchronous calls use Glide.with(this).asBitmap().load(pictureUrl).submit(100, 100).get(). It can be usefull when you want to add icon in notification through .setLargeIcon(bitmap) – Yazon2006 Jun 12 '18 at 19:01
  • 1
    @Max this work's for me in implementation 'com.github.bumptech.glide:glide:3.6.1' – Bipin Bharti Aug 04 '18 at 07:44
  • So, how do I get error callback ? for example, which callback invoked if the image fails to load. – theapache64 May 21 '19 at 14:49
  • 2
    @Nux make sure you are on the latest version `4.9.0` – Atiq Jun 11 '19 at 02:50
  • 4
    `.asBitmap()` should be put after `with(this)` if it's unresolved. – Alston Sep 13 '19 at 08:13
  • This worked like a charm for Glide version 4.11.0 too. But is this asynchronous? – Istiak Morsalin Mar 14 '20 at 13:11
  • This help me lot..work like charm. Also using apply(new RequestOptions().format(DecodeFormat.PREFER_ARGB_8888)) helps me to support best quality with no outofmemory... – Mahbubur Rahman Khan Mar 24 '20 at 17:52
  • `Glide.with(application).asBitmap().load(pictureUrl).circleCrop().submit().get()` works fine for notification icon also in addition to @Yazon2006 suggestion – lasec0203 Sep 19 '20 at 04:44
208

I'm not familiar enough with Glide, but it looks like if you know the target size, you can use something like this:

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

It looks like you can pass -1,-1, and get a full size image (purely based on tests, can't see it documented).

Note into(int,int) returns a FutureTarget<Bitmap>, so you have to wrap this in a try-catch block covering ExecutionException and InterruptedException. Here's a more complete example implementation, tested and working:

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

Following Monkeyless' suggestion in the comment below (and this appears to be the official way too), you can use a SimpleTarget, optionally coupled with override(int,int) to simplify the code considerably. However, in this case the exact size must be provided (anything below 1 isn't accepted):

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

as suggested by @hennry if you required the same image then use new SimpleTarget<Bitmap>()

UPDATE

 bitmap = Glide.with(c).asBitmap().load( "url").submit().get();
Rohaitas Tanoli
  • 624
  • 4
  • 16
outlyer
  • 3,933
  • 2
  • 14
  • 18
  • When I tried this, I ended up with this error: ` java.util.concurrent.ExecutionException: java.lang.NullPointerException: Attempt to read from field 'int android.graphics.Bitmap$Config.nativeInt' on a null object reference at com.bumptech.glide.request.RequestFutureTarget.doGet(RequestFutureTarget.java:208)` – JohnnyLambada Dec 10 '14 at 17:55
  • @JohnnyLambada That looks like an error generated when accessing the image (does it load correctly if you don't try extracting the bitmap?). The code on my updated answer does work for me. I've also noticed how `into(-1,-1)` appears to work to get the full size image, I'd try that too. – outlyer Dec 10 '14 at 20:07
  • My problem was my test subject was a gif. DOH. This is the correct answer -- thanks! – JohnnyLambada Dec 11 '14 at 02:19
  • 4
    For posterity, you don't need the async task, just use .override(int, int) and/or a SimpleTarget – Sam Judd Dec 12 '14 at 23:51
  • 2
    @Monkeyless thanks, I've expanded my answer to include your suggestion. – outlyer Dec 13 '14 at 02:32
  • 35
    If you want to achieve a bitmap in original size it's better to pass ```Target.SIZE_ORIGINAL``` for both width and height of bitmap instead of -1 – Alex Bonel Jun 26 '15 at 11:48
  • What if image path is required as I have to send image for copping – ingsaurabh Nov 17 '15 at 07:30
  • 2
    @AlexBonel's suggestion is right. -1 crashed on me. Use TARGET_SIZE_ORIGINAL to get original size – SIr Codealot Jan 26 '16 at 19:25
  • 6
    You will get the full size bitmap if you don't provide any parameter for `SimpleTarget` like this : `new SimpleTarget(){....}` – Henry Nov 08 '16 at 08:25
  • GlideAnimation not found. – Nouman Ch Apr 05 '18 at 13:07
  • 4
    In Glide 4.0.0+ use .asBitmap() before.load() and .submit(100, 100) instead of .into(100, 100) – Yazon2006 Jun 12 '18 at 19:03
  • On android o, "Glide.with(context).load(R.drawable.ic_default_danmu_head).asBitmap().centerCrop().into(size, size).get()" returns null. – Allen Vork Jun 21 '18 at 03:12
  • FutureTarget is deprecated as well as SimpleTarget! – Nux Jun 10 '19 at 13:24
  • 1
    Bitmap bm = Glide.with(context).asBitmap().load(path).submit().get(); – Divyanshu Kumar Feb 26 '20 at 04:59
17

It looks like overriding the Target class or one of the implementations like BitmapImageViewTarget and overriding the setResource method to capture the bitmap might be the way to go...

This is untested. :-)

    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);
                     }
         });
blad
  • 665
  • 5
  • 8
11

UPDATE

Now we need to use Custom Targets

SAMPLE CODE

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

How does one use glide to download an image into a bitmap?

The above all answer are correct but outdated

because in new version of Glide implementation 'com.github.bumptech.glide:glide:4.8.0'

You will find below error in code

  • The .asBitmap() is not available in glide:4.8.0

enter image description here

  • SimpleTarget<Bitmap> is deprecated

enter image description here

Here is 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;
    }
}
AskNilesh
  • 67,701
  • 16
  • 123
  • 163
10

This is what worked for 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());
            }
        });
    }
});
Shreyash Mahajan
  • 23,386
  • 35
  • 116
  • 188
Stephen Kaiser
  • 1,545
  • 14
  • 10
9

If you want to assign dynamic bitmap image to bitmap variables

Example for kotlin

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

The above answers did not work for me

.asBitmap should be before the .load("http://....")

Ramana V V K
  • 1,245
  • 15
  • 24
  • 5
    .into(100, 100) is deprecated use .submit(100, 100) – Yazon2006 Jun 12 '18 at 18:58
  • why the f does glide deprecate stuff like this? it's practically the same usage... – Karan Harsh Wardhan Mar 30 '19 at 09:41
  • 1
    @KaranHarshWardhan I agree. It appears that the glide team uses "deprecated" to mean: discourage the use because we think it's a bad idea. While the more common meaning in computing is: discourage the use because it will be removed in future versions. I prefer it be exclusively as a notice of future removal. – timeSmith Feb 13 '23 at 23:48
6

UPDATE FOR NEW 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)

OLD ANSWER

@outlyer's answer is correct, but there're some changes in new Glide version

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

Note: this code run in UI Thread, thus you can use AsyncTask, Executor or somethings else for concurrency (like @outlyer's code) If you want to get original size, put Target.SIZE_ORIGINA as my code. Don't use -1, -1

3

for Glide version 4.10.0: Glide.with(context).download(mImageUrl).submit().get()

beokh
  • 191
  • 2
  • 3
3

Kotlin Function

inline fun getBitmap(imageUrl: String, block: (Bitmap?) -> Unit) {
        return try {
            val url = URL(imageUrl)
            val image = BitmapFactory.decodeStream(url.openConnection().getInputStream())
            block(image)
        } catch (e: IOException) {
            println(e)
            block(null)
        }
    }
abhi
  • 961
  • 9
  • 13
2

Newer 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
  • 589
  • 1
  • 7
  • 17
2

Kotlin's way -

fun Context.bitMapFromImgUrl(imageUrl: String, callBack: (bitMap: Bitmap) -> Unit) {
    GlideApp.with(this)
        .asBitmap()
        .load(imageUrl)
        .into(object : CustomTarget<Bitmap>() {
            override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
                callBack(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
            }
        })
}
Anoop M Maddasseri
  • 10,213
  • 3
  • 52
  • 73
2

in kotlin you can use

CoroutineScope(Dispatchers.IO).launch {
      Glide.with(this@&YourActivity).asBitmap().load(imageUrl)                           
                        .listener(object : RequestListener<Bitmap> {
                            override fun onLoadFailed(
                                e: GlideException?,
                                model: Any?,
                                target: Target<Bitmap>?,
                                isFirstResource: Boolean
                            ): Boolean {
                                  Log.e("GlideException" ,"${e.message}")
                                return false
                            }

                            override fun onResourceReady(
                                resource: Bitmap?,
                                model: Any?,
                                target: Target<Bitmap>?,
                                dataSource: DataSource?,
                                isFirstResource: Boolean
                            ): Boolean {
                                resource?.let {bitmap->
                                    //here your bitmap is ready you can use it
                                }
                                return false
                            }

                        })
                        .submit().get()//by using this line glide lib behave as synchronously(block instructions until the task is completed) and by removing this line you can use it as a asynchronously(without blocking other operations)  
}

I am using

api 'com.github.bumptech.glide:glide:4.12.0'
kapt 'com.github.bumptech.glide:compiler:4.12.0'
Abdur Rehman
  • 1,247
  • 10
  • 13
2

Complete Answer

I had to add a try-catch block because now Glide Crashes the app if the URL is invalid.

  return try {
            Glide.with(context)
                .asBitmap()
                .load(imageURL)
                .listener(object : RequestListener<Bitmap> {
                    override fun onLoadFailed(
                        e: GlideException?,
                        model: Any?,
                        target: Target<Bitmap>?,
                        isFirstResource: Boolean
                    ): Boolean {
                        Log.e(
                            TAG,
                            "Texture from ResourceID $resourceId could not be Loaded. " +
                                    "Using default Texture"
                        )
                        return false
                    }

                    override fun onResourceReady(
                        resource: Bitmap?,
                        model: Any?,
                        target: Target<Bitmap>?,
                        dataSource: DataSource?,
                        isFirstResource: Boolean
                    ): Boolean {
                        return false
                    }
                })
                .placeholder(DEFAULT_IMAGE)
                .error(DEFAULT_IMAGE)
                .submit()
                .get()
        } catch (ex: Exception) {
            return fromResource(DEFAULT_IMAGE)
        }
Hitesh Sahu
  • 41,955
  • 17
  • 205
  • 154
2

This example Glide to download an image into a bitmap.

Step 1 - Add the following dependency in build.gradle: Module: app

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

Step 2 − Add the following code to res/layout/activity_main.xml.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   tools:context=".MainActivity">
   <ImageView
      android:id="@+id/imageView"
      android:layout_width="match_parent"
      android:layout_height="match_parent" />
</RelativeLayout>

Step 3 − Add the following code to src/MainActivity.java

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.widget.ImageView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.target.CustomTarget;
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).asBitmap().load("https://www.google.es/images/srpr/logo11w.png").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) {
         }
      });
   }
}

Step 4 − Add the following code to androidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="app.com.sample">
   <uses-permission android:name="android.permission.INTERNET"/>
   <application
      android:allowBackup="true"
      android:icon="@mipmap/ic_launcher"
      android:label="@string/app_name"
      android:roundIcon="@mipmap/ic_launcher_round"
      android:supportsRtl="true"
      android:theme="@style/AppTheme">
         <activity android:name=".MainActivity">
            <intent-filter>
               <action android:name="android.intent.action.MAIN" />
               <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
         </activity>
   </application>
</manifest>

Let's try to run your application.

Suresh B B
  • 1,387
  • 11
  • 13
0

In the latest version of Glide, we can do this

val bitmap = Glide.with(context)
        .asBitmap()
        .load("url")
        .submit()
        .get()
nimi0112
  • 2,065
  • 1
  • 18
  • 32