【问题标题】:How does one use glide to download an image into a bitmap?如何使用 glide 将图像下载到位图中?
【发布时间】:2015-02-08 05:38:09
【问题描述】:

使用 Glide 将 URL 下载到 ImageView 非常容易:

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

我想知道我是否也可以下载到Bitmap?我想下载一个原始位图,然后我可以使用其他工具进行操作。我已经浏览了代码,但不知道该怎么做。

【问题讨论】:

    标签: android android-glide


    【解决方案1】:

    确保您使用的是Lastest version

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

    科特林:

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

    位图大小:

    如果你想使用图像的原始大小,使用上面的默认构造函数,否则你可以传递你想要的位图大小

    into(object : CustomTarget&lt;Bitmap&gt;(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) {
                }
            });
    

    旧答案:

    compile 'com.github.bumptech.glide:glide:4.8.0' 及以下

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

    compile 'com.github.bumptech.glide:glide:3.7.0' 及以下

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

    现在您可能会看到警告 SimpleTarget is deprecated

    原因:

    弃用 SimpleTarget 的主要目的是警告您 它诱使您违反 Glide 的 API 合同的方式。 具体来说,它不会强制您停止使用任何 清除 SimpleTarget 后加载的资源,这可以 导致崩溃和图形损坏。

    SimpleTarget 仍然可以使用,只要您确保在清除 imageView 后不使用位图。

    【讨论】:

    • 我在 Glide 4.0 上似乎找不到 .asBitmap()
    • 对于同步调用,使用 Glide.with(this).asBitmap().load(pictureUrl).submit(100, 100).get()。当您想通过 .setLargeIcon(bitmap) 在通知中添加图标时,它会很有用
    • @Max 这项工作是为我实现的 'com.github.bumptech.glide:glide:3.6.1'
    • @Nux 确保您使用的是最新版本4.9.0
    • .asBitmap() 应该放在with(this) 之后,如果它没有解决的话。
    【解决方案2】:

    我对 Glide 还不够熟悉,但是看起来如果你知道目标大小,你可以使用这样的东西:

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

    看来你可以通过-1,-1,得到一张全尺寸图片(纯基于测试,看不到文档记录)。

    注意into(int,int) 返回一个FutureTarget&lt;Bitmap&gt;,所以你必须将它包装在一个覆盖ExecutionExceptionInterruptedException 的try-catch 块中。这是一个更完整的示例实现,经过测试和工作:

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

    按照以下评论中的 Monkeyless 建议(和 this appears to be the official way too),您可以使用 SimpleTarget,可选地与 override(int,int) 结合使用,以显着简化代码。但是,在这种情况下,必须提供确切的大小(不接受小于 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()
            }
        });
    

    按照@hennry 的建议如果您需要相同的图片,请使用new SimpleTarget&lt;Bitmap&gt;()

    更新

     bitmap = Glide.with(c).asBitmap().load( "url").submit().get();
    

    【讨论】:

    • 对于后代,您不需要异步任务,只需使用 .override(int, int) 和/或 SimpleTarget
    • @Monkeyless 谢谢,我已经扩展了我的答案以包含您的建议。
    • 如果您想获得原始大小的位图,最好将位图的宽度和高度都传递Target.SIZE_ORIGINAL 而不是-1
    • 如果您不为SimpleTarget 提供任何参数,您将获得完整大小的位图,如下所示:new SimpleTarget&lt;Bitmap&gt;(){....}
    • 在 Glide 4.0.0+ 中使用 .asBitmap() before.load() 和 .submit(100, 100) 而不是 .into(100, 100)
    【解决方案3】:

    看起来覆盖Target 类或BitmapImageViewTarget 之类的实现之一并覆盖setResource 方法来捕获位图可能是要走的路...

    这是未经测试的。 :-)

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

    【讨论】:

    • Bitmap 不会占用 imageView 的宽度/高度吗?我希望得到原始未更改的位图。
    • 对于 Glide 4.0.0+ 使用 .asBitmap() before.load()
    【解决方案4】:

    更新

    现在我们需要使用Custom Targets

    示例代码

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

    如何使用 glide 将图像下载到位图中?

    以上所有答案都正确但已过时

    因为在新版本的 Glide implementation 'com.github.bumptech.glide:glide:4.8.0'

    您会在代码中发现以下错误

    • .asBitmap()glide:4.8.0 中不可用

    • SimpleTarget&lt;Bitmap&gt; 已弃用

    解决办法

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

    【讨论】:

    • 如果您在 .load 之前尝试 asBItmap,那么它不会给您任何错误
    • @Spritzig 你现在面临什么问题
    • @NileshRathod 它不向我显示图标没有错误什么也没有,但只是不显示图标。
    • @NileshRathod 你找到这个问题了吗?
    【解决方案5】:

    这对我有用: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());
                }
            });
        }
    });
    

    【讨论】:

      【解决方案6】:

      如果要将动态位图图像分配给位图变量

      kotlin 的示例

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

      以上答案对我不起作用

      .asBitmap 应该在.load("http://....") 之前

      【讨论】:

      • .into(100, 100) 不推荐使用 .submit(100, 100)
      • 为什么 f glide 会弃用这样的东西?这实际上是相同的用法...
      【解决方案7】:

      新版本更新

      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)
      

      老答案

      @outlyer 的回答是正确的,但是新的 Glide 版本有一些变化

      我的版本:4.7.1

      代码:

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

      注意:此代码在 UI 线程中运行,因此您可以使用 AsyncTask、Executor 或其他东西进行并发(如 @outlyer 的代码) 如果您想获得原始尺寸,请将 Target.SIZE_ORIGINA 作为我的代码。不要使用 -1、-1

      【讨论】:

      • SimpleTarget 在新版本中已弃用
      【解决方案8】:

      对于 Glide 版本 4.10.0: Glide.with(context).download(mImageUrl).submit().get()

      【讨论】:

        【解决方案9】:

        较新的版本:

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

        【讨论】:

          【解决方案10】:

          Kotlin 的方式 -

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

          【讨论】:

            【解决方案11】:

            在 kotlin 中你可以使用

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

            我正在使用

            api 'com.github.bumptech.glide:glide:4.12.0'
            kapt 'com.github.bumptech.glide:compiler:4.12.0'
            

            【讨论】:

              【解决方案12】:

              Kotlin 函数

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

              【讨论】:

                【解决方案13】:

                完整答案

                我必须添加一个 try-catch 块,因为如果 URL 无效,现在 Glide 会使应用程序崩溃。

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

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2021-08-17
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2015-10-30
                  • 1970-01-01
                  • 2017-12-17
                  • 1970-01-01
                  相关资源
                  最近更新 更多