安卓项目实战之Glide 3高手养成(二):Glide强大的图片变换功能

使用Glide时普遍会遇到的一个问题,如何解决?

首先我们尝试使用Glide来加载一张图片,图片URL地址是:https://www.baidu.com/img/bd_logo1.png
这是百度首页logo的一张图片,图片尺寸是540*258像素。
接下来我们编写一个非常简单的布局文件,如下所示:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"> 
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Load Image"
        android:onClick="loadImage"
        /> 
    <ImageView
        android:id="@+id/image_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        /> 
</LinearLayout>

布局文件中只有一个按钮和一个用于显示图片的ImageView。注意,ImageView的宽和高这里设置的都是wrap_content。
然后编写如下的代码来加载图片:

public class MainActivity extends AppCompatActivity { 

    ImageView imageView; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.activity_main); 
        imageView = (ImageView) findViewById(R.id.image_view);
    } 

    public void loadImage(View view) { 
        String url = "https://www.baidu.com/img/bd_logo1.png"; 
        Glide.with(this) .load(url) .into(imageView); 
    }
}

现在运行一下程序并点击加载图片按钮,效果如下图所示:
在这里插入图片描述
图片是正常加载出来了,不过大家有没有发现一个问题。百度这张logo图片的尺寸只有540258像素,但是我的手机的分辨率却是10801920像素,而我们将ImageView的宽高设置的都是wrap_content,那么图片的宽度应该只有手机屏幕宽度的一半而已,但是这里却充满了全屏,这是为什么呢?
答案:Glide的图片变换功能导致的,在开始本篇之前,我们会先分析如何解决这个问题。
稍微对Android有点了解的人应该都知道ImageView有scaleType这个属性,但是可能大多数人却不知道,如果在没有指定scaleType属性的情况下,ImageView默认的scaleType是什么?
经测试我们知道,在没有明确指定的情况下,ImageView默认的scaleType是FIT_CENTER。
通过查看Glide源码我们发现在执行into(ImageView)时有如下的判断逻辑:
在这里插入图片描述
会对ImageView的scaleType进行一个switch判断,如果ImageView的scaleType是CENTER_CROP,则会去调用applyCenterCrop()方法,如果scaleType是FIT_CENTER、FIT_START或FIT_END,则会去调用applyFitCenter()方法。这里的applyCenterCrop()和applyFitCenter()方法其实就是向Glide的加载流程中添加了一个图片变换操作。

那么现在我们就基本清楚了,由于ImageView默认的scaleType是FIT_CENTER,因此会自动添加一个FitCenter的图片变换,而在这个图片变换过程中做了某些操作,导致图片充满了全屏。
解决方案:取消Glide的图片变换
Glide给我们提供了专门的API来添加和取消图片变换,想要解决这个问题只需要使用如下代码即可:

Glide.with(this)
     .load(url)
     .dontTransform()
     .into(imageView);

可以看到,这里调用了一个dontTransform()方法,表示让Glide在加载图片的过程中不进行图片变换,这样刚才调用的applyCenterCrop()、applyFitCenter()就统统无效了。

现在我们重新运行一下代码,效果如下图所示:
在这里插入图片描述
这样图片就只会占据半个屏幕的宽度了,说明我们的代码奏效了。

但是使用dontTransform()方法存在着一个问题,就是调用这个方法之后,所有的图片变换操作就全部失效了,那如果我有一些图片变换操作是必须要执行的该怎么办呢?不用担心,总归是有办法的,这种情况下我们只需要借助override()方法强制将图片尺寸指定成原始大小就可以了,代码如下所示:

Glide.with(this)
     .load(url)
     .override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
     .into(imageView);

通过override()方法将图片的宽和高都指定成Target.SIZE_ORIGINAL,问题同样被解决了。程序的最终运行结果和上图是完全一样的,我就不再重新截图了。

为Glide添加图片变换功能

图片变换的意思就是说,Glide从加载了原始图片到最终展示给用户之前,又进行了一些变换处理,从而能够实现一些更加丰富的图片效果,如图片圆角化、圆形化、模糊化等等。

添加图片变换的用法非常简单,我们只需要调用transform()方法,并将想要执行的图片变换操作作为参数传入transform()方法即可,如下所示:

Glide.with(this)
     .load(url)
     .transform(...)
     .into(imageView);

至于具体要进行什么样的图片变换操作,这个通常都是需要我们自己来写的。不过Glide已经内置了两种图片变换操作,我们可以直接拿来使用,一个是CenterCrop,一个是FitCenter。

但这两种内置的图片变换操作其实都不需要使用transform()方法,Glide为了方便我们使用直接提供了现成的API:

Glide.with(this) .
      load(url) .
      centerCrop() .
      into(imageView); 

Glide.with(this) .
      load(url) .
      fitCenter() .
      into(imageView);

当然,centerCrop()和fitCenter()方法其实也只是对transform()方法进行了一层封装而已,它们背后的源码仍然还是借助transform()方法来实现的,那么这两种内置的图片变换操作到底能实现什么样的效果呢?FitCenter的效果其实刚才我们已经见识过了,就是会将图片按照原始的长宽比充满全屏。那么CenterCrop又是什么样的效果呢?
在这里插入图片描述 在这里插入图片描述
上面的图1为不使用任何变换的效果,图二是使用了CenterCrop的变换效果,可以看到,现在展示的图片是对原图的中心区域进行裁剪后得到的图片。
不得不说,Glide内置的图片变换接口功能十分单一且有限,完全没有办法满足我们平时的开发需求。因此,掌握自定义图片变换功能就显得尤为重要了。

借助第三方库实现丰富的图片变换效果

虽说Glide的图片变换功能框架已经很强大了,使得我们可以轻松地自定义图片变换效果,但是如果每一种图片变换都要我们自己去写还是蛮吃力的。事实上,确实也没有必要完全靠自己去实现各种各样的图片变换效果,因为大多数的图片变换都是比较通用的,各个项目会用到的效果都差不多,我们每一个都自己去重新实现无异于重复造轮子。

也正是因此,网上出现了很多Glide的图片变换开源库,其中做的最出色的应该要数glide-transformations这个库了。它实现了很多通用的图片变换效果,如裁剪变换、颜色变换、模糊变换等等,使得我们可以非常轻松地进行各种各样的图片变换。

glide-transformations的项目主页地址是 https://github.com/wasabeef/glide-transformations

下面我们就来体验一下这个库的强大功能吧。首先需要将这个库引入到我们的项目当中,在app/build.gradle文件当中添加如下依赖:

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

现在如果我想对图片进行模糊化处理,那么就可以使用glide-transformations库中的BlurTransformation这个类,代码如下所示:

Glide.with(this).load(R.drawable.demo)
  .apply(bitmapTransform(new BlurTransformation(25, 3)))
  .into((ImageView) findViewById(R.id.image));

而且我们还可以将多个图片变换效果组合在一起使用,比如同时执行模糊化和圆角化的变换:

MultiTransformation multi = new MultiTransformation(
    new BlurTransformation(25), 
    new RoundedCornersTransformation(128, 0, RoundedCornersTransformation.CornerType.BOTTOM))))
Glide.with(this).load(R.drawable.demo)
  .apply(bitmapTransform(multi))
  .into((ImageView) findViewById(R.id.image));

更多的图片变换效果你可以到它的GitHub项目主页去学习: https://github.com/wasabeef/glide-transformations

猜你喜欢

转载自blog.csdn.net/gpf1320253667/article/details/83388944