如何使用滑动下载图像到位图?

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

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

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

244834 次浏览

看起来重写 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);
}
});

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

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

看起来您可以通过 -1,-1,并获得一个完整的图像(纯粹基于测试,无法看到它的文档)。

注意,into(int,int)返回一个 FutureTarget<Bitmap>,因此必须将它包装在涵盖 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 在下面的注释(和 这似乎也是官方的方式)中的建议,您可以使用 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()
}
});

由@henry 如果您需要相同的图像,然后使用 new SimpleTarget<Bitmap>()建议

更新

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

这就是对我起作用的: 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());
}
});
}
});

确保你在 最新版本

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

老答案:

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 被清除。

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

例如 kotlin

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

以上的回答对我不起作用

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

更新新版本

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 Thread 中运行,因此您可以使用 AsyncTask、 Execator 或其他方法进行并发(比如@outlyer 的代码) 如果您想获得原始大小,请将 Target.SIZE _ ORIGINA 作为我的代码,不要使用 -1,-1

更新

现在我们需要使用 强 > 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 implementation 'com.github.bumptech.glide:glide:4.8.0'

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

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

enter image description here

  • 不推荐使用 SimpleTarget<Bitmap>

enter image description here

这是解决办法

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

新版本:

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

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

幻灯片版本4.10.0: With (context) . download (mImageUrl) . subit () . get ()

在 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'

完整答案

我必须添加一个 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)
}

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

下面的示例使用 Glide 将图像下载到位图中。

步骤1-在 build.gradle 中添加以下依赖项: Module: app

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

步骤2-将以下代码添加到 res/layp/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>

步骤3-将以下代码添加到 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) {
}
});
}
}

步骤4-将以下代码添加到 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>

让我们尝试运行您的应用程序。