• Glide4.0 Transformation大全,罗列搜集所有Transformation,实现图片的变换


    1. 背景

    在使用Glide4.X的时候,经常会使用到图片变换的情况,都是网上搜索一番,Ctrl + C + Ctrl + V,没有系统地去看过这一块东西,网上的资料也很零散,有时候遇到一些较复杂的情况,得搜索好久才能得到自己想要的结果。出现这个痛点后,现准备针对Transformation罗列记录一下。

    本文Glide版本为4.13.2

    implementation 'com.github.bumptech.glide:glide:4.13.2'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.13.2'
    
    • 1
    • 2

    文中的布局是一个固定宽高300*300ImageView

    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <ImageView
            android:id="@+id/image_view"
            android:layout_width="300dp"
            android:layout_height="300dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    
    androidx.constraintlayout.widget.ConstraintLayout>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    正常显示photo1效果如下
    在这里插入图片描述

    2. Transformation是什么

    Transformation(转换器),这个类可以说是 Glide 压缩裁剪图片的核心类,因为该类功能就是依据要求输出的宽高对原始资源进行压缩裁剪之类的转换

    public interface Transformation<T> extends Key {
      
    	/**
    	 * 转换原始资源并返回转换后的资源对象
    	 */
    	Resource<T> transform(@NonNull Context context, @NonNull Resource<T> resource,
    	                        int outWidth, int outHeight);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    3. Glide自带的Transformations

    我们使用Android Studio自带的Hierarchy工具,可以查看到,实现Transformations接口的类总共有这些
    在这里插入图片描述

    Hierarchy工具的具体使用,详见我的另一篇博客 : Android Studio 使用 自带的Hierarchy查看类/方法/调用的层级关系

    3.1 BitmapTransformation

    BitmapTransformation有很多子类,这里是我们关注的重点

    3.1.1 CenterCrop、fitCenter和CenterInside

    其中,Glide中的CenterCropfitCenterCenterInside和ImageView的scale type有对应关系,对照关系如下

    GlideImageView的scaleType
    CenterCropcenterCrop
    fitCenterfitCenter
    CenterInsidecenterInside 和 fitXY

    关于 ImageView scaleType 可以查看这篇文章 Android ImageView 的scaleType 属性图解

    从代码中也可以看出这种对照关系 RequestBuilder#into()

    @NonNull
    public ViewTarget<ImageView, TranscodeType> into(@NonNull ImageView view) {
    	Util.assertMainThread();
    	Preconditions.checkNotNull(view);
    	
    	BaseRequestOptions<?> requestOptions = this;
    	if (!requestOptions.isTransformationSet()
    	  && requestOptions.isTransformationAllowed()
    	  && view.getScaleType() != null) {
    	// Clone in this method so that if we use this RequestBuilder to load into a View and then
    	// into a different target, we don't retain the transformation applied based on the previous
    	// View's scale type.
    	switch (view.getScaleType()) {
    	  case CENTER_CROP:
    	    requestOptions = requestOptions.clone().optionalCenterCrop();
    	    break;
    	  case CENTER_INSIDE:
    	    requestOptions = requestOptions.clone().optionalCenterInside();
    	    break;
    	  case FIT_CENTER:
    	  case FIT_START:
    	  case FIT_END:
    	    requestOptions = requestOptions.clone().optionalFitCenter();
    	    break;
    	  case FIT_XY:
    	    requestOptions = requestOptions.clone().optionalCenterInside();
    	    break;
    	  case CENTER:
    	  case MATRIX:
    	  default:
    	    // Do nothing.
    	}
    }
    
    • 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

    3.1.2 CircleCrop

    这个就是对图片裁剪为圆形

    Glide.with(this)
         .load(R.drawable.photo1)
         .circleCrop()
         .into(imageView)
    
    • 1
    • 2
    • 3
    • 4

    效果如下
    在这里插入图片描述

    3.1.3 Rotate

    这个就是对图片进行旋转操作

    Glide.with(this)
         .load(R.drawable.photo1)
         .transform(Rotate(90))
         .into(imageView)
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    3.1.4 RoundedCorners

    这个是对图片进行圆角操作

    Glide.with(this)
         .load(R.drawable.photo1)
         .transform(RoundedCorners(ConvertUtils.dp2px(30F)))
         .into(imageView)
    
    • 1
    • 2
    • 3
    • 4

    效果如下
    在这里插入图片描述

    3.1.5 GranularRoundedCorners

    这个是当上下左右四个圆角值不一样的时候,对每个圆角的值进行定义

    val radius30 = ConvertUtils.dp2px(30F).toFloat()
    val radius5 = ConvertUtils.dp2px(5F).toFloat()
    Glide.with(this)
        .load(R.drawable.photo1)
        .transform(GranularRoundedCorners(radius30, radius5, radius30, radius5))
        .into(imageView)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    效果如下
    在这里插入图片描述

    3.2 MultiTransformation 多重变换

    默认情况下,每个 transform() 调用,或任何特定转换方法fitCenter(), centerCrop(), bitmapTransform()的调用都会替换掉之前的变换。
    如果想在单次加载中应用多个变换,需要使用使用 MultiTransformation 类。

    Glide.with(this)
         .load(R.drawable.photo1)
         .transform(MultiTransformation(CenterCrop(),Rotate(90)))
         .into(imageView)
    
    • 1
    • 2
    • 3
    • 4

    效果如下
    在这里插入图片描述

    3.3 其他自带的Transformation

    3.3.1. UnitTransformation

    不做任何处理,直接返回

    @NonNull
    @Override
    public Resource<T> transform(
        @NonNull Context context, @NonNull Resource<T> resource, int outWidth, int outHeight) {
      return resource;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    3.3.2 DrawableTransformation

    将Bitmap转化为Drawable,在源码里有用到,我们一般不会去调用。

    3.3.3 BitmapDrawableTransformation

    注解上说已弃用,建议使用DrawableTransformation

    4. Transformation扩展 : glide-transformations

    Github上有一个Glide的Transformation库,glide-transformations,提供了一些额外的Transformation

    需要添加如下依赖

    implementation 'jp.wasabeef:glide-transformations:4.3.0'
    // 如果想使用GPU Filter,需要这个依赖,对应着文中的4.13-4.22部分
    implementation 'jp.co.cyberagent.android:gpuimage:2.1.0'
    
    • 1
    • 2
    • 3

    4.1 Mask

     Glide.with(context)
    	.load(R.drawable.photo1)
    	.apply(overrideOf(266.px, 252.px))
    	.apply(bitmapTransform(MultiTransformation<Bitmap>(CenterCrop(),
    	  MaskTransformation(R.drawable.mask_starfish))))
    	.into(holder.image)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述

    4.2 NinePatchMask

    Glide.with(context)
    	.load(R.drawable.photo1)
    	.apply(overrideOf(300.px, 200.px))
    	.apply(bitmapTransform(MultiTransformation<Bitmap>(CenterCrop(),
    	  MaskTransformation(R.drawable.mask_chat_right))))
    	.into(holder.image)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述

    4.3 RoundedCorners

    Glide.with(context)
    	.load(R.drawable.photo1)
    	.apply(bitmapTransform(RoundedCornersTransformation(120, 0,
    	  RoundedCornersTransformation.CornerType.DIAGONAL_FROM_TOP_LEFT)))
    	.into(holder.image)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述

    4.4 CropTop

    Glide.with(context)
    	.load(R.drawable.photo1)
    	.apply(bitmapTransform(CropTransformation(300.px, 100.px, CropType.TOP)))
    	.into(holder.image)
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    4.5 CropCenter

    Glide.with(context)
    	.load(R.drawable.photo1)
    	.apply(bitmapTransform(CropTransformation(300.px, 100.px, CropType.CENTER)))
    	.into(holder.image)
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    4.6 CropBottom

    Glide.with(context)
    	.load(R.drawable.photo1)
    	.apply(bitmapTransform(CropTransformation(300.px, 100.px, CropType.BOTTOM)))
    	.into(holder.image)
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    4.7 CropSquare

    Glide.with(context)
        .load(R.drawable.photo1)
        .apply(bitmapTransform(CropSquareTransformation()))
        .into(holder.image)
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    4.8 CropCircle

    Glide.with(context)
        .load(R.drawable.photo1)
        .apply(bitmapTransform(CropCircleTransformation()))
        .into(holder.image)
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    4.9 CropCircleWithBorder

    Glide.with(context)
        .load(R.drawable.photo1)
        .apply(bitmapTransform(
          CropCircleWithBorderTransformation(Utils.toDp(4), Color.rgb(0, 145, 86))))
        .into(holder.image)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述

    4.10 Grayscale

    Glide.with(context)
            .load(R.drawable.photo1)
            .apply(bitmapTransform(GrayscaleTransformation()))
            .into(holder.image)
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    4.11 BlurLight

    Glide.with(context)
        .load(R.drawable.photo1)
        .apply(bitmapTransform(BlurTransformation(25)))
        .into(holder.image)
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    4.12 BlurDeep

    Glide.with(context)
        .load(R.drawable.photo1)
        .apply(bitmapTransform(BlurTransformation(25, 8)))
        .into(holder.image)
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    4.13 Toon

    Glide.with(context)
        .load(R.drawable.photo1)
        .apply(bitmapTransform(ToonFilterTransformation()))
        .into(holder.image)
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    4.14 Sepia

    Glide.with(context)
        .load(R.drawable.photo1)
        .apply(bitmapTransform(SepiaFilterTransformation()))
        .into(holder.image)
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    4.15 Contrast

    Glide.with(context)
        .load(R.drawable.check)
        .apply(bitmapTransform(ContrastFilterTransformation(2.0f)))
        .into(holder.image)
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    4.16 Invert

    Glide.with(context)
        .load(R.drawable.photo1)
        .apply(bitmapTransform(ContrastFilterTransformation(2.0f)))
        .into(holder.image)
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    4.17 Pixel

    Glide.with(context)
        .load(R.drawable.photo1)
        .apply(bitmapTransform(PixelationFilterTransformation(20f)))
        .into(holder.image)
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    4.18 Sketch

    Glide.with(context)
        .load(R.drawable.photo1)
        .apply(bitmapTransform(SketchFilterTransformation()))
        .into(holder.image)
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    4.19 Swirl

    Glide.with(context)
        .load(R.drawable.photo1)
        .apply(bitmapTransform(
          SwirlFilterTransformation(0.5f, 1.0f, PointF(0.5f, 0.5f))).dontAnimate())
        .into(holder.image)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述

    4.20 Brightness

    Glide.with(context)
        .load(R.drawable.photo1)
        .apply(bitmapTransform(BrightnessFilterTransformation(0.5f)).dontAnimate())
        .into(holder.image)
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    4.21 Kuawahara

    Glide.with(context)
        .load(R.drawable.photo1)
        .apply(bitmapTransform(KuwaharaFilterTransformation(25)).dontAnimate())
        .into(holder.image)
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    4.22 Vignette

    Glide.with(context)
        .load(R.drawable.photo1)
        .apply(bitmapTransform(VignetteFilterTransformation(PointF(0.5f, 0.5f),
          floatArrayOf(0.0f, 0.0f, 0.0f), 0f, 0.75f)).dontAnimate())
        .into(holder.image)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述

    5. 自定义Transformation

    如果常用的Transformation满足不了我们的需要,也可以自定义Transformation
    如果只需要变换 Bitmap,最好是从继承 BitmapTransformation 开始。BitmapTransformation 为我们处理了一些基础的东西,例如,如果变换返回了一个新修改的 Bitmap ,BitmapTransformation将负责提取和回收原始的 Bitmap。
    比如,我们自己去实现一个旋转图片的Transformation

    class RotateTransformation(private val angle: Float) : BitmapTransformation() {
        override fun updateDiskCacheKey(messageDigest: MessageDigest) {
    
        }
    
        override fun transform(
            pool: BitmapPool,
            toTransform: Bitmap,
            outWidth: Int,
            outHeight: Int
        ): Bitmap {
            val matrix = Matrix()
            matrix.postRotate(angle)
            return Bitmap.createBitmap(
                toTransform,
                0,
                0,
                toTransform.width,
                toTransform.height,
                matrix,
                true
            )
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    进行使用

    Glide.with(this)
    	.load(R.mipmap.photo1)
    	.apply(bitmapTransform(RotateTransformation(90F)))
    	.into(imageView)
    
    • 1
    • 2
    • 3
    • 4

    效果如下
    在这里插入图片描述

    6. 其他

    参考 Glide V4 : 变换
    Glide 的 transformation

  • 相关阅读:
    Windows MySQL8.0免安装版,配置多个安装示例
    LeetCode557. 反转字符串中的单词 III
    基于Spring Boot应用@FunctionalInterface注解
    C++ set 的使用
    目标检测网络系列——YOLO V1
    在你自学计算机的路上,哪些书籍对你的帮助最大?
    【系统架构设计】架构核心知识: 5 系统安全性与保密性设计
    ES7新特性深度解析:提升JavaScript开发效率的利器
    OceanBase荣获OSCAR两项大奖,开源已成主流开发模式
    LeetCode 212. 单词搜索 II -- 字典树+dfs
  • 原文地址:https://blog.csdn.net/EthanCo/article/details/126262446