Glide入门教程——13.自定义变换

Glide — 自定义变换

原文:Custom Transformation
作者:Norman Peitek
翻译:Dexter0218

前面的12篇文章中,你已经学会了所有的基础请求去实现Glide的标准功能。从这篇文章开始,我们将要深入研究一些高级话题。这篇文章进一步研究变换(Transformations)。

Glide 系列概览

  1. 入门简介
  2. 高级加载
  3. 适配器(ListView, GridView)
  4. 占位图& 淡入淡出动画
  5. 图片大小 & 缩放
  6. 播放GIF & 视频
  7. 缓存基础
  8. 请求优先级
  9. 缩略图
  10. 回调:定制view中使用SimpleTarget和ViewTarget
  11. 通知栏和桌面小控件的图片加载
  12. 异常: 调试和报错处理
  13. 自定义变换
  14. 用animate()定制动画
  15. 整合网络协议栈
  16. 用Modules定制Glide
  17. Glide Module 案例: 接受自签名HTTPS证书
  18. Glide Module 案例: 自定义缓存
  19. Glide Module 案例: 通过加载自定义大小图片优化
  20. 动态使用 Model Loaders
  21. 如何旋转图片
  22. 系列综述

变换

在图片显示出之前可以对图片进行变换处理。例如,如果你的app需要显示一张灰度图,但只能获取到一个原始全色彩的版本,你可以使用一个变换去将图片从有明艳色彩的版本转换成惨淡的黑白版。不要误会我们,变换不仅限于颜色。你可以改变图片的很多属性:大小、边框、色彩、像素点,等等!在之前介绍用Glide调整图片大小时,已经介绍了自带的两个变换fitCentercenterCrop。这两个方案都有一个显著的特征,他们有他们自己的Glide转换方法,所以,这篇文章不再介绍了。

实现你自己的变换

为了实现你自己自定义的变换,你需要创建一个新的类去实现变换接口。这个方法需要实现的内容还是相当复杂的,你需要深入探索Glide的内部结构才能让其工作好。如果你只是想要常规的图片(不包括Gif和视频)变换,我们建议只要处理抽象的BitmapTransformation类。它简化了相当多的实现,能覆盖95%的使用范围。

所以,让我们先看一下BitmapTransformation实现的一个例子。如果你有规律地看我们的文章,你知道我们最喜欢的变换是用Renderscript去模糊图片。我们可以用之前用过的代码去实现一个Glide变换。我们的框架必须继承BitmapTransformation类:

public class BlurTransformation extends BitmapTransformation {

    public BlurTransformation(Context context) {
        super( context );
    }

    @Override
    protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
        return null; // todo
    }

    @Override
    public String getId() {
        return null; // todo
    }
}

现在,我们用前面文章的代码,借助Renderscript来实现图片的模糊处理。

public class BlurTransformation extends BitmapTransformation {

    private RenderScript rs;

    public BlurTransformation(Context context) {
        super( context );

        rs = RenderScript.create( context );
    }

    @Override
    protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
        Bitmap blurredBitmap = toTransform.copy( Bitmap.Config.ARGB_8888, true );

        // Allocate memory for Renderscript to work with
        Allocation input = Allocation.createFromBitmap(
            rs, 
            blurredBitmap, 
            Allocation.MipmapControl.MIPMAP_FULL, 
            Allocation.USAGE_SHARED
        );
        Allocation output = Allocation.createTyped(rs, input.getType());

        // Load up an instance of the specific script that we want to use.
        ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
        script.setInput(input);

        // Set the blur radius
        script.setRadius(10);

        // Start the ScriptIntrinisicBlur
        script.forEach(output);

        // Copy the output to the blurred bitmap
        output.copyTo(blurredBitmap);

        toTransform.recycle();

        return blurredBitmap;
    }

    @Override
    public String getId() {
        return "blur";
    }
}

再次提醒,如果你对transform()里的代码困惑,建议看看之前的文章。getId()方法为这个变换描述了一个独有的识别。Glide使用那个关键字作为缓存系统的一部分。防止出现异常问题,确保其唯一。

下一节,我们要学习如何应用我们创建的变换方法。

应用一个简单的变换

Glide has two ways of applying a transformation. The first is to pass an instance of your class as a parameter to .transform(). You can apply any transformation there, no matter if it's for an image or Gif. The other option is to use .bitmapTransform(), which only accepts transformations for bitmaps. Since our implementation above is designed for bitmaps, we could use either one:

Glide有两个不同的方式进行变换。第一个是传递一个你的类的实例作为.transform()的参数。不管是图片还是gif,都可以进行变换。另一个则是使用.bitmapTransform(),它只接受bitmap的变换。由于我们的实现都是基于bitmap,我们可以使用第一个:

Glide  
    .with( context )
    .load( eatFoodyImages[0] )
    .transform( new BlurTransformation( context ) )
    //.bitmapTransform( new BlurTransformation( context ) ) // this would work too!
    .into( imageView1 );

这足够让Glide从网络下载的图片自动实现模糊算法。非常有用!

实现多重变换

通常,Glide的流接口(fluent interface)允许方法被连接在一起,然而变换并不是这样的。确保你只调用.transform()或者.bitmapTransform()一次,不然,之前的设置将会被覆盖!然而,你可以通过传递多个转换对象当作参数到.transform()(或者.bitmapTransform())中来进行多重变换:

Glide  
    .with( context )
    .load( eatFoodyImages[1] )
    .transform( new GreyscaleTransformation( context ), new BlurTransformation( context ) )
    .into( imageView2 );

在这段代码中,我们先对图片进行了灰度变换,然后模糊处理。Glide会为你自动进行两个转换。牛逼吧!

提示:当你使用变换的时候,你不能使用.centerCrop()或者.fitCenter()

Glide的变换集合

如果你已经对你的app里要用什么变换有了想法,在花点时间看看下面的库吧:Glide-transformations。它提供了许多变换的集合。值得去看一下你的idea是否已经被实现了。

这个库有2个不同版本。扩展库包括更多的变换,并且是用手机的GPU进行计算。需要一个额外的依赖,所以这两个版本的设置还有点不一样。你应当看看支持的变换的列表,再决定你需要用哪个版本。

Glide变换的设置

设置是很简单的!对于基本版,你可以在你的build.gradle里加一行:

dependencies {  
    compile 'jp.wasabeef:glide-transformations:2.0.0'
}

如果你想要使用GPU变换:

repositories {  
    jcenter()
    mavenCentral()
}

dependencies {  
    compile 'jp.wasabeef:glide-transformations:2.0.0'
    compile 'jp.co.cyberagent.android.gpuimage:gpuimage-library:1.3.0'
}

Glide变换的使用

在你同步了Android Studio的builde.gradle文件后,你已经可以进行使用变换集合了。使用方式与使用自定义变换一样。假如我们要用glide变换集合去模糊图片:

Glide  
    .with( context )
    .load( eatFoodyImages[2] )
    .bitmapTransform( new jp.wasabeef.glide.transformations.BlurTransformation( context, 25 ) )
    .into( imageView3 );

你也可以像上面一样应用一组变换。一个单独的变换或者一组变换,.bitmapTransform()都可以接受!

展望

这边文章中,你已经学会了Glide的一个非常有用的工具:变换。你已经知道如何实现并应用预定义的变换,我们希望这提供给你应用到app里所有需要的帮助!如果你有问题,在评论区提出!

这篇文件讲解了一个非常定制化的特征,后面的文章将介绍另一个:自定义动画。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容