

Glide图片加载库的使用
source link: http://www.androidchina.net/5022.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Glide是 Google推荐的图片加载库,它可以支持来自url,Android资源,文件,Uri中的图片加载,同时还支持gif图片的加载,以及各种图片显示前的bitmap处理(例如:圆角图片,圆形图片,高斯模糊,旋转,灰度等等),缓存处理,请求优先级处理,动画处理,缩略图处理,图片大小自定义等等.可谓是非常的强大.
1.添加Glide库
需要在build.gradle中加入依赖,目前最新的版本是3.7.0,Glide库地址
compile 'com.github.bumptech.glide:glide:3.7.0'
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);
ImageView targetView = (ImageView) findViewById(R.id.iv_target);
Glide.with(
this
).
load(url).
asBitmap().
//强制处理为bitmap
into(targetView);
//显示到目标View中
}
}
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);
}
}
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);
}
}
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);
ImageView targetView = (ImageView) findViewById(R.id.iv_target);
Glide.with(
this
).
load(uri).
asBitmap().
into(targetView);
}
}
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);
}
}
效果图:
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);
}
}
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);
}
}
另外,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);
}
}
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);
}
}
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);
}
}
磁盘缓存,磁盘缓存通过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);
}
}
12.缓存设置
在GlideModule 中,我们可以设置磁盘缓存的位置,磁盘缓存的大小和内存缓存的大小,同时还可以设置图片的显示质量.
要是用GlideModule ,需要创建它的实现类,然后在manifests中申明实现类的全类路径:
<
meta-data
android:name
=
"com.example.mchenys.httputilsdemo.image.glide.module.SimpleGlideModule"
android:value
=
"GlideModule"
/>
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) {
}
}
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);
}
}
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);
}
}
通过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
)
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);
}
}
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);
}
}
下面贴出常用的几个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()"
;
}
}
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 +
")"
;
}
}
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()"
;
}
}
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;
}
}
高斯模糊处理
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 +
")"
;
}
}
网上提供的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);
}
}
RenderScript处理高斯模糊
android4.3之后可使用,需要在build.gradle中配置:
defaultConfig {
//BlurTransformation
renderscriptTargetApi 23
renderscriptSupportModeEnabled true
}
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;
}
}
16.动画处理
通过animate()方法可以设置xml文件定义的4种补间动画(alpha、scale、translate、rotate)
例如:
res\anim\left_in.xml
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
<
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
>
使用方式:
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);
}
}
处理此外,还可以通过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);
}
}
转载请注明:Android开发中文站 » Glide图片加载库的使用
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK