Glide是 Google推荐的图片加载库,它可以支持来自url,Android资源,文件,Uri中的图片加载,同时还支持gif图片的加载,以及各种图片显示前的bitmap处理(例如:圆角图片,圆形图片,高斯模糊,旋转,灰度等等),缓存处理,请求优先级处理,动画处理,缩略图处理,图片大小自定义等等.可谓是非常的强大.
1.添加Glide库
需要在build.gradle中加入依赖,目前最新的版本是3.7.0,Glide库地址
compile 'com.github.bumptech.glide:glide:3.7.0'
- 1
- 1
2.加载网络图片
/**
* Created by mChenys on 2016/6/6.
*/
public class TestGlideActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
String url = "http://www.qq745.com/uploads/allimg/141106/1-141106153Q5.png";
ImageView targetView = (ImageView) findViewById(R.id.iv_target);
Glide.with(this).
load(url).
asBitmap(). //强制处理为bitmap
into(targetView);//显示到目标View中
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
3.加载资源图片
public class TestGlideActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
int resourceId = R.drawable.test;
ImageView targetView = (ImageView) findViewById(R.id.iv_target);
Glide.with(this).
load(resourceId).
asBitmap().
into(targetView);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
4.加载本地文件图片
public class TestGlideActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
File file = new File(Environment.getExternalStorageDirectory(), "test.jpg");
ImageView targetView = (ImageView) findViewById(R.id.iv_target);
Glide.with(this).
load(file).
asBitmap().
into(targetView);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
5.从Uri中加载
/**
* Created by mChenys on 2016/6/6.
*/
public class TestGlideActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
Uri uri = Uri.parse("android.resource://" + this.getPackageName() + "/" + R.drawable.test);
ImageView targetView = (ImageView) findViewById(R.id.iv_target);
Glide.with(this).
load(uri).
asBitmap().
into(targetView);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
6.加载gif图片
public class TestGlideActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
ImageView targetView = (ImageView) findViewById(R.id.iv_target);
Glide.with(this).
load(R.drawable.smail).
asGif().//注意:这里显示的指明了要加载的是gif图片,当然即使不指明,glide也会自己判断.
into(targetView);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
效果图:
7.设置默认图片和加载失败时显示的图片
public class TestGlideActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
ImageView targetView = (ImageView) findViewById(R.id.iv_target);
Glide.with(this).
load(R.drawable.test).
asBitmap().
placeholder(R.drawable.bg_loading).//加载中显示的图片
error(R.drawable.bg_error).//加载失败时显示的图片
into(targetView);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
8.淡入显示效果
public class TestGlideActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
ImageView targetView = (ImageView) findViewById(R.id.iv_target);
Glide.with(this).
load(R.drawable.test).
placeholder(R.drawable.bg_loading).//加载中显示的图片
error(R.drawable.bg_error).//加载失败时显示的图片
crossFade().//淡入显示,注意:如果设置了这个,则必须要去掉asBitmap
into(targetView);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
另外,crossFade还可以接收一个参数来设置淡入显示效果的持续时间,crossFade(int duration);
如果你想直接显示图片,而不是淡入显示图片,则可以通过dontAnimate()方法设置.
9.调整图片像素大小
public class TestGlideActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
ImageView targetView = (ImageView) findViewById(R.id.iv_target);
Glide.with(this).
load(R.drawable.test).
placeholder(R.drawable.bg_loading).//加载中显示的图片
error(R.drawable.bg_error).//加载失败时显示的图片
crossFade(1000).//淡入显示的时间,注意:如果设置了这个,则必须要去掉asBitmap
override(80,80).//设置最终显示的图片像素为80*80,注意:这个是像素,而不是控件的宽高
into(targetView);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
10.设置CenterCrop,FitCenter
CenterCrop,FitCenter都是对目标图片进行裁剪,了解过ImageView的ScaleType属性就知道,这2种裁剪方式在ImageView上也是有的,分别对应ImageView的ImageView.ScaleType.CENTER_CROP和mageView.ScaleType.FIT_CENTER的.
public class TestGlideActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
ImageView targetView = (ImageView) findViewById(R.id.iv_target);
targetView.setScaleType(ImageView.ScaleType.FIT_CENTER);
Glide.with(this).
load(R.drawable.test).
placeholder(R.drawable.bg_loading).//加载中显示的图片
error(R.drawable.bg_error).//加载失败时显示的图片
crossFade(1000).//淡入淡出,注意:如果设置了这个,则必须要去掉asBitmap
override(80,80).//设置最终显示的图片像素为80*80,注意:这个是像素,而不是控件的宽高
centerCrop().//中心裁剪,缩放填充至整个ImageView
into(targetView);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
11.缓存策略设置
内存缓存设置,通过skipMemoryCache(boolean)来设置是否需要缓存到内存,默认是会缓存到内存的.
/**
* Created by mChenys on 2016/6/6.
*/
public class TestGlideActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
ImageView targetView = (ImageView) findViewById(R.id.iv_target);
targetView.setScaleType(ImageView.ScaleType.FIT_CENTER);
Glide.with(this).
load(R.drawable.test).
placeholder(R.drawable.bg_loading).//加载中显示的图片
error(R.drawable.bg_error).//加载失败时显示的图片
crossFade(1000).//淡入淡出,注意:如果设置了这个,则必须要去掉asBitmap
override(80,80).//设置最终显示的图片像素为80*80,注意:这个是像素,而不是控件的宽高
centerCrop().//中心裁剪,缩放填充至整个ImageView
skipMemoryCache(true).//跳过内存缓存
into(targetView);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
磁盘缓存,磁盘缓存通过diskCacheStrategy(DiskCacheStrategy)来设置,DiskCacheStrategy一共有4种模式:
- DiskCacheStrategy.NONE:什么都不缓存
- DiskCacheStrategy.SOURCE:仅缓存原图(全分辨率的图片)
- DiskCacheStrategy.RESULT:仅缓存最终的图片,即修改了尺寸或者转换后的图片
- DiskCacheStrategy.ALL:缓存所有版本的图片,默认模式
public class TestGlideActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
ImageView targetView = (ImageView) findViewById(R.id.iv_target);
targetView.setScaleType(ImageView.ScaleType.FIT_CENTER);
Glide.with(this).
load(R.drawable.test).
placeholder(R.drawable.bg_loading).//加载中显示的图片
error(R.drawable.bg_error).//加载失败时显示的图片
crossFade(1000).//淡入淡出,注意:如果设置了这个,则必须要去掉asBitmap
override(80, 80).//设置最终显示的图片像素为80*80,注意:这个是像素,而不是控件的宽高
centerCrop().//中心裁剪,缩放填充至整个ImageView
skipMemoryCache(true).//跳过内存缓存
diskCacheStrategy(DiskCacheStrategy.RESULT).//保存最终图片
into(targetView);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
12.缓存设置
在GlideModule 中,我们可以设置磁盘缓存的位置,磁盘缓存的大小和内存缓存的大小,同时还可以设置图片的显示质量.
要是用GlideModule ,需要创建它的实现类,然后在manifests中申明实现类的全类路径:
<meta-data
android:name="com.example.mchenys.httputilsdemo.image.glide.module.SimpleGlideModule"
android:value="GlideModule" />
- 1
- 2
- 3
- 1
- 2
- 3
GlideModule 的实现类,需要实现applyOptions方法:
/**
* 所以你知道要创建一个额外的类去定制 Glide。
* 下一步是要全局的去声明这个类,让 Glide 知道它应该在哪里被加载和使用。
* Glide 会扫描 AndroidManifest.xml 为 Glide module 的 meta 声明。
* 因此,你必须在 AndroidManifest.xml 的 <application> 标签内去声明这个SimpleGlideModule。
* Created by mChenys on 2016/6/10.
*/
public class SimpleGlideModule implements GlideModule {
public static DiskCache cache;
@Override
public void applyOptions(Context context, GlideBuilder builder) {
// 在 Android 中有两个主要的方法对图片进行解码:ARGB8888 和 RGB565。前者为每个像素使用了 4 个字节,
// 后者仅为每个像素使用了 2 个字节。ARGB8888 的优势是图像质量更高以及能存储一个 alpha 通道。
// Picasso 使用 ARGB8888,Glide 默认使用低质量的 RGB565。
// 对于 Glide 使用者来说:你使用 Glide module 方法去改变解码规则。
builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);
//设置缓存目录
File cacheDir = PathUtils.getDiskCacheDir(context, CacheConfig.IMG_DIR);
cache = DiskLruCacheWrapper.get(cacheDir, DiskCache.Factory.DEFAULT_DISK_CACHE_SIZE);// 250 MB
builder.setDiskCache(new DiskCache.Factory() {
@Override
public DiskCache build() {
return cache;
}
});
//设置memory和Bitmap池的大小
MemorySizeCalculator calculator = new MemorySizeCalculator(context);
int defaultMemoryCacheSize = calculator.getMemoryCacheSize();
int defaultBitmapPoolSize = calculator.getBitmapPoolSize();
int customMemoryCacheSize = (int) (1.2 * defaultMemoryCacheSize);
int customBitmapPoolSize = (int) (1.2 * defaultBitmapPoolSize);
builder.setMemoryCache(new LruResourceCache(customMemoryCacheSize));
builder.setBitmapPool(new LruBitmapPool(customBitmapPoolSize));
}
@Override
public void registerComponents(Context context, Glide glide) {
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
13.设置图片请求的优先级
Glide 可以用 Priority 枚举来设置图片的加载优先级,这样我们就可以针对那些需要显示的图片设置高的优先级了.
Priority 有4种级别:
Priority.LOW
Priority.NORMAL
Priority.HIGH
Priority.IMMEDIATE
例如:
/**
* 高优先级加载
* @param url
* @param imageView
* @param listener
*/
public static void loadImageWithHighPriority(Object url,ImageView imageView, final LoaderListener listener) {
if (url == null) {
if (listener != null) {
listener.onError();
}
} else {
Glide.with(imageView.getContext()).
load(url).
asBitmap().
priority(Priority.HIGH).//高优先级
dontAnimate().
listener(new RequestListener<Object, Bitmap>() {
@Override
public boolean onException(Exception e, Object model, Target<Bitmap> target, boolean isFirstResource) {
if (null != listener) {
listener.onError();
}
return false;
}
@Override
public boolean onResourceReady(Bitmap resource, Object model, Target<Bitmap> target, boolean isFromMemoryCache, boolean isFirstResource) {
if (null != listener) {
listener.onSuccess();
}
return false;
}
}).into(imageView);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
14.设置加载缩略图
通过设置缩略图,我们可以在显示目标图片之前先展示一个第分辨率或者其他图片,当全分辨率的目标图片在后台加载完成后,
Glide会自动切换显示全像素的目标图片.
设置缩略图有2种方式:
通过thumbnail(float)指定0.0f~1.0f的原始图像大小,例如全像素的大小是500*500,如果设置为thumbnail为0.1f,即目标图片的10%,显示的缩略图大小就是50*50;
public class TestGlideActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
ImageView targetView = (ImageView) findViewById(R.id.iv_target);
Glide.with(this).
load(R.drawable.test).
placeholder(R.drawable.bg_loading).//加载中显示的图片
error(R.drawable.bg_error).//加载失败时显示的图片
crossFade(1000).//淡入淡出,注意:如果设置了这个,则必须要去掉asBitmap
override(80, 80).//设置最终显示的图片像素为80*80,注意:这个是像素,而不是控件的宽高
centerCrop().//中心裁剪,缩放填充至整个ImageView
skipMemoryCache(true).//跳过内存缓存
diskCacheStrategy(DiskCacheStrategy.RESULT).//保存最终图片
thumbnail(0.1f).//10%的原图大小
into(targetView);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
通过thumbnail(DrawableRequestBuilder)方式来指定缩略图,该缩略图可以使用load的所有方式(网络,文件,uri,资源)加载.
public class TestGlideActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
ImageView targetView = (ImageView) findViewById(R.id.iv_target);
//缩略图请求
DrawableRequestBuilder<String> thumbnailRequest = Glide
.with(this)
.load("http://www.qq745.com/uploads/allimg/141106/1-141106153Q5.png");
Glide.with(this).
load(R.drawable.test).
// placeholder(R.drawable.bg_loading).//加载中显示的图片
// error(R.drawable.bg_error).//加载失败时显示的图片
// crossFade(1000).//淡入淡出,注意:如果设置了这个,则必须要去掉asBitmap
override(80, 80).//设置最终显示的图片像素为80*80,注意:这个是像素,而不是控件的宽高
centerCrop().//中心裁剪,缩放填充至整个ImageView
skipMemoryCache(true).//跳过内存缓存
diskCacheStrategy(DiskCacheStrategy.RESULT).//保存最终图片
thumbnail(thumbnailRequest).//设置缩略图
into(targetView);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
15.Transformations Bitmap
在显示目标图片之前,我们可以对目标图片的Bitmap进行相应的处理,例如::圆角图片,圆形图片,高斯模糊,旋转,灰度等等.
只需要实现Transformation接口即可,该接口的transform方法会返回显示图片前的Bitmap对象,在该方法中对
Bitmap的任何处理,都会影响到最终的显示结果.
当然,如果你只是想要对图片做常规的 bitmap 转换,你可以继承抽象类BitmapTransformation,它简化了Transformation接口的实现,这应该能覆盖大部分的应用场景了。
使用的时候,通过transform(Transformation… transformations)来设置.例如:
public class TestGlideActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
ImageView targetView = (ImageView) findViewById(R.id.iv_target);
Glide.with(this).
load(R.drawable.test).
asBitmap().
transform(new BlurTransformation(this)).//高斯模糊处理
into(targetView);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
下面贴出常用的几个Bitmap的转换处理的代码,在github上也有glide-transformations-master库.
圆图处理
public class CropCircleTransformation implements Transformation<Bitmap> {
private BitmapPool mBitmapPool;
public CropCircleTransformation(Context context) {
this(Glide.get(context).getBitmapPool());
}
public CropCircleTransformation(BitmapPool pool) {
this.mBitmapPool = pool;
}
@Override
public Resource<Bitmap> transform(Resource<Bitmap> resource, int outWidth, int outHeight) {
Bitmap source = resource.get();
int size = Math.min(source.getWidth(), source.getHeight());
int width = (source.getWidth() - size) / 2;
int height = (source.getHeight() - size) / 2;
Bitmap bitmap = mBitmapPool.get(size, size, Bitmap.Config.ARGB_8888);
if (bitmap == null) {
bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
}
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
BitmapShader shader =
new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP);
if (width != 0 || height != 0) {
// source isn't square, move viewport to center
Matrix matrix = new Matrix();
matrix.setTranslate(-width, -height);
shader.setLocalMatrix(matrix);
}
paint.setShader(shader);
paint.setAntiAlias(true);
float r = size / 2f;
canvas.drawCircle(r, r, r, paint);
return BitmapResource.obtain(bitmap, mBitmapPool);
}
@Override public String getId() {
return "CropCircleTransformation()";
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
圆角处理
public class RoundedCornersTransformation implements Transformation<Bitmap> {
private BitmapPool mBitmapPool;
private int radius;
private int margin;
public RoundedCornersTransformation(Context context, int radius, int margin) {
this(Glide.get(context).getBitmapPool(), radius, margin);
}
public RoundedCornersTransformation(BitmapPool pool, int radius, int margin) {
mBitmapPool = pool;
this.radius = radius;
this.margin = margin;
}
@Override
public Resource<Bitmap> transform(Resource<Bitmap> resource, int outWidth, int outHeight) {
Bitmap source = resource.get();
int width = source.getWidth();
int height = source.getHeight();
Bitmap bitmap = mBitmapPool.get(width, height, Bitmap.Config.ARGB_8888);
if (bitmap == null) {
bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
}
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setShader(new BitmapShader(source, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
canvas.drawRoundRect(new RectF(margin, margin, width - margin, height - margin), radius, radius,
paint);
return BitmapResource.obtain(bitmap, mBitmapPool);
}
@Override public String getId() {
return "RoundedTransformation(radius=" + radius + ", margin=" + margin + ")";
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
灰度处理
public class GrayscaleTransformation implements Transformation<Bitmap> {
private BitmapPool mBitmapPool;
public GrayscaleTransformation(Context context) {
this(Glide.get(context).getBitmapPool());
}
public GrayscaleTransformation(BitmapPool pool) {
mBitmapPool = pool;
}
@Override
public Resource<Bitmap> transform(Resource<Bitmap> resource, int outWidth, int outHeight) {
Bitmap source = resource.get();
int width = source.getWidth();
int height = source.getHeight();
Bitmap.Config config =
source.getConfig() != null ? source.getConfig() : Bitmap.Config.ARGB_8888;
Bitmap bitmap = mBitmapPool.get(width, height, config);
if (bitmap == null) {
bitmap = Bitmap.createBitmap(width, height, config);
}
Canvas canvas = new Canvas(bitmap);
ColorMatrix saturation = new ColorMatrix();
saturation.setSaturation(0f);
Paint paint = new Paint();
paint.setColorFilter(new ColorMatrixColorFilter(saturation));
canvas.drawBitmap(source, 0, 0, paint);
return BitmapResource.obtain(bitmap, mBitmapPool);
}
@Override public String getId() {
return "GrayscaleTransformation()";
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
旋转处理
public class RotateTransformation extends BitmapTransformation {
private float rotateRotationAngle = 0f;
public RotateTransformation(Context context, float rotateRotationAngle) {
super(context);
this.rotateRotationAngle = rotateRotationAngle;
}
@Override
protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
Matrix matrix = new Matrix();
matrix.postRotate(rotateRotationAngle);
return Bitmap.createBitmap(toTransform, 0, 0, toTransform.getWidth(), toTransform.getHeight(), matrix, true);
}
@Override
public String getId() {
return "rotate" + rotateRotationAngle;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
高斯模糊处理
public class BlurTransformation implements Transformation<Bitmap> {
private static int MAX_RADIUS = 25;
private static int DEFAULT_DOWN_SAMPLING = 1;
private Context mContext;
private BitmapPool mBitmapPool;
private int mRadius;
private int mSampling;
public BlurTransformation(Context context) {
this(context, Glide.get(context).getBitmapPool(), MAX_RADIUS, DEFAULT_DOWN_SAMPLING);
}
public BlurTransformation(Context context, BitmapPool pool) {
this(context, pool, MAX_RADIUS, DEFAULT_DOWN_SAMPLING);
}
public BlurTransformation(Context context, BitmapPool pool, int radius) {
this(context, pool, radius, DEFAULT_DOWN_SAMPLING);
}
public BlurTransformation(Context context, int radius) {
this(context, Glide.get(context).getBitmapPool(), radius, DEFAULT_DOWN_SAMPLING);
}
public BlurTransformation(Context context, BitmapPool pool, int radius, int sampling) {
mContext = context;
mBitmapPool = pool;
mRadius = radius;
mSampling = sampling;
}
public BlurTransformation(Context context, int radius, int sampling) {
mContext = context;
mBitmapPool = Glide.get(context).getBitmapPool();
mRadius = radius;
mSampling = sampling;
}
@Override
public Resource<Bitmap> transform(Resource<Bitmap> resource, int outWidth, int outHeight) {
Bitmap source = resource.get();
int width = source.getWidth();
int height = source.getHeight();
int scaledWidth = width / mSampling;
int scaledHeight = height / mSampling;
Bitmap bitmap = mBitmapPool.get(scaledWidth, scaledHeight, Bitmap.Config.ARGB_8888);
if (bitmap == null) {
bitmap = Bitmap.createBitmap(scaledWidth, scaledHeight, Bitmap.Config.ARGB_8888);
}
Canvas canvas = new Canvas(bitmap);
canvas.scale(1 / (float) mSampling, 1 / (float) mSampling);
Paint paint = new Paint();
paint.setFlags(Paint.FILTER_BITMAP_FLAG);
canvas.drawBitmap(source, 0, 0, paint);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
try {
bitmap = RSBlur.blur(mContext, bitmap, mRadius);
} catch (RSRuntimeException e) {
bitmap = FastBlur.blur(bitmap, mRadius, true);
}
} else {
bitmap = FastBlur.blur(bitmap, mRadius, true);
}
return BitmapResource.obtain(bitmap, mBitmapPool);
}
@Override public String getId() {
return "BlurTransformation(radius=" + mRadius + ", sampling=" + mSampling + ")";
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
网上提供的FastBlur,可兼容低版本的高斯模糊处理
public class FastBlur {
public static Bitmap blur(Bitmap sentBitmap, int radius, boolean canReuseInBitmap) {
Bitmap bitmap;
if (canReuseInBitmap) {
bitmap = sentBitmap;
} else {
bitmap = sentBitmap.copy(sentBitmap.getConfig(), true);
}
if (radius < 1) {
return (null);
}
int w = bitmap.getWidth();
int h = bitmap.getHeight();
int[] pix = new int[w * h];
bitmap.getPixels(pix, 0, w, 0, 0, w, h);
int wm = w - 1;
int hm = h - 1;
int wh = w * h;
int div = radius + radius + 1;
int r[] = new int[wh];
int g[] = new int[wh];
int b[] = new int[wh];
int rsum, gsum, bsum, x, y, i, p, yp, yi, yw;
int vmin[] = new int[Math.max(w, h)];
int divsum = (div + 1) >> 1;
divsum *= divsum;
int dv[] = new int[256 * divsum];
for (i = 0; i < 256 * divsum; i++) {
dv[i] = (i / divsum);
}
yw = yi = 0;
int[][] stack = new int[div][3];
int stackpointer;
int stackstart;
int[] sir;
int rbs;
int r1 = radius + 1;
int routsum, goutsum, boutsum;
int rinsum, ginsum, binsum;
for (y = 0; y < h; y++) {
rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
for (i = -radius; i <= radius; i++) {
p = pix[yi + Math.min(wm, Math.max(i, 0))];
sir = stack[i + radius];
sir[0] = (p & 0xff0000) >> 16;
sir[1] = (p & 0x00ff00) >> 8;
sir[2] = (p & 0x0000ff);
rbs = r1 - Math.abs(i);
rsum += sir[0] * rbs;
gsum += sir[1] * rbs;
bsum += sir[2] * rbs;
if (i > 0) {
rinsum += sir[0];
ginsum += sir[1];
binsum += sir[2];
} else {
routsum += sir[0];
goutsum += sir[1];
boutsum += sir[2];
}
}
stackpointer = radius;
for (x = 0; x < w; x++) {
r[yi] = dv[rsum];
g[yi] = dv[gsum];
b[yi] = dv[bsum];
rsum -= routsum;
gsum -= goutsum;
bsum -= boutsum;
stackstart = stackpointer - radius + div;
sir = stack[stackstart % div];
routsum -= sir[0];
goutsum -= sir[1];
boutsum -= sir[2];
if (y == 0) {
vmin[x] = Math.min(x + radius + 1, wm);
}
p = pix[yw + vmin[x]];
sir[0] = (p & 0xff0000) >> 16;
sir[1] = (p & 0x00ff00) >> 8;
sir[2] = (p & 0x0000ff);
rinsum += sir[0];
ginsum += sir[1];
binsum += sir[2];
rsum += rinsum;
gsum += ginsum;
bsum += binsum;
stackpointer = (stackpointer + 1) % div;
sir = stack[(stackpointer) % div];
routsum += sir[0];
goutsum += sir[1];
boutsum += sir[2];
rinsum -= sir[0];
ginsum -= sir[1];
binsum -= sir[2];
yi++;
}
yw += w;
}
for (x = 0; x < w; x++) {
rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
yp = -radius * w;
for (i = -radius; i <= radius; i++) {
yi = Math.max(0, yp) + x;
sir = stack[i + radius];
sir[0] = r[yi];
sir[1] = g[yi];
sir[2] = b[yi];
rbs = r1 - Math.abs(i);
rsum += r[yi] * rbs;
gsum += g[yi] * rbs;
bsum += b[yi] * rbs;
if (i > 0) {
rinsum += sir[0];
ginsum += sir[1];
binsum += sir[2];
} else {
routsum += sir[0];
goutsum += sir[1];
boutsum += sir[2];
}
if (i < hm) {
yp += w;
}
}
yi = x;
stackpointer = radius;
for (y = 0; y < h; y++) {
// Preserve alpha channel: ( 0xff000000 & pix[yi] )
pix[yi] = (0xff000000 & pix[yi]) | (dv[rsum] << 16) | (dv[gsum] << 8) | dv[bsum];
rsum -= routsum;
gsum -= goutsum;
bsum -= boutsum;
stackstart = stackpointer - radius + div;
sir = stack[stackstart % div];
routsum -= sir[0];
goutsum -= sir[1];
boutsum -= sir[2];
if (x == 0) {
vmin[y] = Math.min(y + r1, hm) * w;
}
p = x + vmin[y];
sir[0] = r[p];
sir[1] = g[p];
sir[2] = b[p];
rinsum += sir[0];
ginsum += sir[1];
binsum += sir[2];
rsum += rinsum;
gsum += ginsum;
bsum += binsum;
stackpointer = (stackpointer + 1) % div;
sir = stack[stackpointer];
routsum += sir[0];
goutsum += sir[1];
boutsum += sir[2];
rinsum -= sir[0];
ginsum -= sir[1];
binsum -= sir[2];
yi += w;
}
}
bitmap.setPixels(pix, 0, w, 0, 0, w, h);
return (bitmap);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
RenderScript处理高斯模糊
android4.3之后可使用,需要在build.gradle中配置:
defaultConfig {
//BlurTransformation
renderscriptTargetApi 23
renderscriptSupportModeEnabled true
}
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
public class RSBlur {
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
public static Bitmap blur(Context context, Bitmap blurredBitmap, int radius) throws RSRuntimeException {
try {
RenderScript rs = RenderScript.create(context);
Allocation input = Allocation.createFromBitmap(rs, blurredBitmap, Allocation.MipmapControl.MIPMAP_NONE,
Allocation.USAGE_SCRIPT);
Allocation output = Allocation.createTyped(rs, input.getType());
ScriptIntrinsicBlur blur = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
blur.setInput(input);
blur.setRadius(radius);
blur.forEach(output);
output.copyTo(blurredBitmap);
rs.destroy();
} catch (RSRuntimeException e) {
blurredBitmap = FastBlur.blur(blurredBitmap, radius, true);
}
return blurredBitmap;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
16.动画处理
通过animate()方法可以设置xml文件定义的4种补间动画(alpha、scale、translate、rotate)
例如:
res\anim\left_in.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="@android:integer/config_mediumAnimTime"
android:fromXDelta="-50%p"
android:toXDelta="0"/>
<alpha
android:duration="@android:integer/config_mediumAnimTime"
android:fromAlpha="0.0"
android:toAlpha="1.0"/>
</set>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
使用方式:
public class TestGlideActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
ImageView targetView = (ImageView) findViewById(R.id.iv_target);
Glide.with(this).
load(R.drawable.test).
asBitmap().
animate(R.anim.left_in).//加载xml文件定义的动画
into(targetView);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
处理此外,还可以通过animate指定属性动画:
public class TestGlideActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
ImageView targetView = (ImageView) findViewById(R.id.iv_target);
ViewPropertyAnimation.Animator animationObject = new ViewPropertyAnimation.Animator() {
@Override
public void animate(View view) {
//设置属性动画
ObjectAnimator moveIn = ObjectAnimator.ofFloat(view, "translationX", -500f, 0f);
ObjectAnimator rotate = ObjectAnimator.ofFloat(view, "rotation", 0f, 360f);
ObjectAnimator fadeInOut = ObjectAnimator.ofFloat(view, "alpha", 1f, 0f, 1f);
ObjectAnimator moveTop = ObjectAnimator.ofFloat(view, "translationY", 0f, -2000, 0f);
AnimatorSet animSet = new AnimatorSet();
//先左进,然后旋转伴随淡入效果,最后移动向上
animSet.play(rotate).with(fadeInOut).after(moveIn).before(moveTop);
animSet.setDuration(5000);
animSet.start();
}
};
Glide.with(this).
load(R.drawable.test).
asBitmap().
animate(animationObject).//加载属性动画
into(targetView);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29