Android glide之图片新增透明度变换

关于变换

在Glide中,Transformations 可以获取资源并修改它,然后返回被修改后的资源。通常变换操作是用来完成剪裁或对位图应用过滤器,但它也可以用于转换GIF动画,甚至自定义的资源类型。

内置类型

Glide 提供了很多内置的变换,包括:

CenterCrop
FitCenter
CircleCrop

应用

通过 RequestOptions 类可以应用变换:

默认变换

Glide.with(fragment)
.load(url)
.fitCenter()
.into(imageView);
或使用 RequestOptions :

RequestOptions options = new RequestOptions();
options.centerCrop();

Glide.with(fragment)
.load(url)
.apply(options)
.into(imageView);
可以查阅 Options 页来获得更多 RequestOption 的相关信息。

多重变换

默认情况下,每个 transform() 调用,或任何特定转换方法(fitCenter(), centerCrop(), bitmapTransform() etc)的调用都会替换掉之前的变换。

如果你想在单次加载中应用多个变换,请使用 MultiTransformation 类,或其快捷方法 .transforms() 。

Glide.with(fragment)
.load(url)
.transform(new MultiTransformation(new FitCenter(), new YourCustomTransformation())
.into(imageView);
或使用快捷方法:

Glide.with(fragment)
.load(url)
.transform(new FitCenter(), new YourCustomTransformation())
.into(imageView);
请注意,你向 MultiTransformation 的构造器传入变换参数的顺序,决定了这些变换的应用顺序。

定制变换

尽管 Glide 提供了各种各样的内置 Transformation 实现,如果你需要额外的功能,你也可以实现你自己的 Transformation。

BitmapTransformation

如果你只需要变换 Bitmap,最好是从继承 BitmapTransformation 开始。BitmapTransformation 为我们处理了一些基础的东西,例如,如果你的变换返回了一个新修改的 Bitmap ,BitmapTransformation将负责提取和回收原始的 Bitmap。

一个简单的实现看起来可能像这样,在图片基础上新增50%透明度:

public class MaskTransformation extends BitmapTransformation {
    private static final int VERSION = 1;
    private static final String ID =
            "com.utils.MaskTransformation." + VERSION;
    private int color;
    private int radius;
    private Paint paint = new Paint();
    private Rect srcRec = new Rect();
    private Rect toRec = new Rect();

    public MaskTransformation() {
        this(Color.parseColor("#80000000"), 12);
    }

    public MaskTransformation(int color, int radius) {
        this.color = color;
        this.radius = radius;
        paint.setAntiAlias(true);
    }

    @Override
    protected Bitmap transform(@NonNull BitmapPool pool, @NonNull Bitmap toTransform, int outWidth, int outHeight) {
        return maskBitmap(pool, toTransform, outWidth, outHeight);
    }

    private Bitmap maskBitmap(BitmapPool pool, Bitmap source, int outWidth, int outHeight) {
        if (source == null) return null;
        srcRec.right = source.getWidth();
        srcRec.bottom = source.getHeight();
        toRec.right = outWidth;
        toRec.bottom = outHeight;
        Bitmap result = pool.get(outWidth, outHeight, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(result);
        canvas.drawBitmap(source, srcRec, toRec, paint);
        Bitmap bitmap = BitmapUtils.getBitmap(toRec.width(), toRec.height(), DensityUtils.dip2px(AppStoreApplication.getContext(), radius), color);
        canvas.drawBitmap(bitmap, srcRec, toRec, paint);
        return result;
    }

    @Override
    public void updateDiskCacheKey(@NonNull MessageDigest messageDigest) {
        messageDigest.update((ID + color + radius).getBytes(CHARSET));
    }

    @Override
    public boolean equals(Object o) {
        if (!(o instanceof MaskTransformation)) {
            return false;
        }
        MaskTransformation temp = (MaskTransformation) o;
        return temp.color == color && temp.radius == radius;
    }

    @Override
    public int hashCode() {
        return ID.hashCode() + color + radius * 10;
    }
}

尽管你的 Transformation 将几乎确定比这个示例更复杂,但它应该包含了相同的基本元素和复写方法。

必需的方法

请特别注意,对于任何 Transformation 子类,包括 BitmapTransformation,你都有三个方法你 必须 实现它们,以使得磁盘和内存缓存正确地工作:

  1. equals()
  2. hashCode()
  3. updateDiskCacheKey

如果你的 Transformation 没有参数,通常使用一个包含完整包限定名的 static final String 来作为一个 ID,它可以构成 hashCode() 的基础,并可用于更新 updateDiskCacheKey() 传入的 MessageDigest。如果你的 Transformation 需要参数而且它会影响到 Bitmap 被变换的方式,它们也必须被包含到这三个方法中。

     @Override
    public void updateDiskCacheKey(@NonNull MessageDigest messageDigest) {
        messageDigest.update((ID + color + radius).getBytes(CHARSET));
    }

    @Override
    public boolean equals(Object o) {
        if (!(o instanceof MaskTransformation)) {
            return false;
        }
        MaskTransformation temp = (MaskTransformation) o;
        return temp.color == color && temp.radius == radius;
    }

    @Override
    public int hashCode() {
        return ID.hashCode() + color + radius * 10;
    }
不要忘记 equals() / hashCode()!

值得重申的一点是,为了让内存缓存正常地工作你是否必须实现 equals() 和 hashCode() 方法。很不幸,即使你没有复写这两个方法,BitmapTransformation 和 Transformation 也能通过编译,但这并不意味着它们能正常工作。我们正在探索一些方案,以使在 Glide 的未来版本中,使用默认的 equals() 和 hashCode 方法将抛出一个编译时错误。

你可能感兴趣的:(android,glide)