您的位置:首页 > 移动开发 > Android开发

【Android】Glide 实现图片再处理(比如在右下角添加 GIF 标识、圆角处理、添加水印等,通过在原 bitmap 的基础上进行再处理)

2017-04-05 11:55 1181 查看
先提前说明,此文有坑,请看完再根据具体情况考虑要不要采用。

依旧是项目需要,需要在列表 item 显示了 GIF 图片的 imageview 的右下角添加 GIF 标识。

查阅了 glide 的方法,发现有个 transform 方法,其作用就是改变原始资源在客户端上最终的展现结果,里面传入 BitmapTransformation(可以多个),我们可以根据需要复写 BitmapTransformation。

下面就以右下角添加 GIF 标识为例子进行说明。

先上效果图:



下面说实现:

首先是自定义 Application:

public class MyApplication extends Application {
private static Context context;

@Override
public void onCreate() {
super.onCreate();

context = getApplicationContext();
}

public static Context getContext(){
return context;
}

}


然后在 AndroidManifest.xml 里面设置 Application:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="...">
<application
...
android:name="xxx.MyApplication">
...
</application>
</manifest>


下面是复写的代码:

public class GifIconTransformation extends BitmapTransformation {
private boolean isGif = false;
private static Paint paint;
private static Bitmap gifbmp;

public GifIconTransformation(Context context, String url) {
super(context);

if (url.toLowerCase().endsWith(".gif")) isGif = true;
}

public GifIconTransformation(Context context, boolean isGif) {
super(context);
this.isGif = isGif;
}

static {
gifbmp = BitmapFactory.decodeResource(DigitApp.getContext().getResources(), R.drawable.ic_gif_white_18dp);

paint = new Paint();
paint.setColor(Color.parseColor("#469de6"));
paint.setStyle(Paint.Style.FILL);
}

@Override
protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
if(isGif) return addGifIcon(toTransform);
else return toTransform;
}

@Override
public String getId() {
return "xxxxxxxx.GifIconTransformation";//xxxxx为对应的包名,用做独立标识
}

private Bitmap addGifIcon(Bitmap oldbitmap) {
int width = oldbitmap.getWidth();
int height = oldbitmap.getHeight();

int gifbmpWidth = gifbmp.getWidth();
int gifbmpHeight = gifbmp.getHeight();

Canvas canvas = new Canvas(oldbitmap);
canvas.drawBitmap(oldbitmap, 0, 0, null);
canvas.drawRect(width - gifbmpWidth - 18, height - gifbmpHeight, width, height, paint);
canvas.drawBitmap(gifbmp, width - gifbmpWidth - 9, height - gifbmpHeight, null);
//canvas.save(Canvas.ALL_SAVE_FLAG);
//canvas.restore();

return oldbitmap;
}
}


现在来简单说明下:

首先,这里的 GIF 图片判断是通过图片链接(因为项目中图片的链接后面会带有格式),如果后缀是 .gif 或者 .GIF,均需要加入 GIF 标识。当然这里只是举例,如果你有自己的判断也可以自己写,判断可以在类外或者类内,如果在类外,那么直接通过 GifIconTransformation(Context context, boolean isGif) 传个 boolean 值进来;如果在类内,那么你得再自行修改。

bitmap 和 paint 设为静态,为的是节约内存。bitmap 取的是中间那个 GIF 白色图标,paint 画的是那个蓝色的长方形背景框。Paint.Style.FILL 是填充满,而不是只画边框。

transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) 中的 toTransform 就是最终的 bitmap。

对于这个方法,在进行相关查阅资料后,需要注意几点:

*对于传入的 toTransform Bitmap,不要去回收它或者把它放入到缓存池。如果实现者返回了一个不同的 Bitmap 实例,Glide 会负责去回收或者复用 toTransform 这个 Bitmap。

*不要去回收作为这个方法返回值的 bitmap。

*如果在这个方法的执行过程中产生了临时的 Bitmap 实例,那么最好把它放入缓存池,或者回收它。

然后我们可以直接就在这个 bitmap 上进行再次绘制并返回给 transform。

绘制过程就不多说了,先画原来的 bitmap ,再画蓝色长方形背景,再画 GIF 图标,具体绘制方法请参考 Canvas 的相关绘制。

当然这里你还可以进行其它操作,比如圆角处理,缩放,灰度等等,这些得根据需要自行编写相关代码。

接下来说说如何使用:

Glide.with(context)
.load(url)
.asBitmap()
.transform(new GifIconTransformation(context, url))
.dontAnimate()
.placeholder(R.drawable.placeholder)
.error(R.drawable.error)
.into(imageview);


当然,如果你要居中处理,那么得这样:

Glide.with(context)
.load(url)
.asBitmap()
.transform(new CenterCrop(context), new GifIconTransformation(context, url))
.dontAnimate()
.placeholder(R.drawable.placeholder)
.error(R.drawable.error)
.into(imageview);


.asBitmap() 必须要有,为了把所有图片都以 bitmap 形式进行处理(用于限制 GIF,此时 GIF 将只会显示第一帧)。其中 CenterCrop(context) 是 glide 提供的类。这里还要讲一点,如果你用了 CenterCrop,那么你的 imageview 就不应该再设置 android:scaleType="centerCrop" ,如果你同时用了两个,那么后面添加的 GIF 标识由于两次居中处理可能会造成显示不完整或看不到的问题。

好了,下面来讲讲坑。。。

关于 CenterCrop,上面的方案只适用于 imageview 宽度高度相对固定的情况下,如果你的图片是用在列表中,并且会根据图片张数不同而变换样式(不同 item 的 imageview 宽度、高度会变换),那么上面的方案就可能会出现问题(因为一开始 glide 拿到的高宽并不是最终的,所以居中就会出现问题,这时候就可能会造成第一次显示出错),当然你可以写个监听,当 imageview 绘制完了再进行图片加载(会造成加载慢的感觉),或者你如果有其它的解决方案也可以分享出来。

当然这里还提供了一个其它的解决方法,那就是通过重写 imageview 来实现这个功能(只限画标识):

【Android】重写 Imageview 实现添加标识(比如右下角添加 GIF 标识)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐