Glide图片加载添加蒙层

Glide图片加载添加蒙层

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

图片添加蒙层

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

  • 蒙层添加步骤
  1. 获取原图,在画布上绘制图片
  2. 从缓存或动态生成蒙层图片
  3. 将蒙层图片绘制在画布上
  4. 返回变换后的图片
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;

import androidx.annotation.NonNull;

import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation;
import com.mxbc.mxsa.R;

import java.security.MessageDigest;

/**
 * 自定义图片layer
 */
public class MaskTransformation extends BitmapTransformation {
    private static final int VERSION = 1;
    private static final String ID =
            "com.mxbc.mxsa.base.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.parse("#10000000"), 0);
    }

    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(), ScreenUtils.dp2px(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 MxImageMaskTransformation)) {
            return false;
        }
        MxImageMaskTransformation temp = (MxImageMaskTransformation) o;
        return temp.color == color && temp.radius == radius;
    }

    @Override
    public int hashCode() {
        return ID.hashCode() + color + radius * 10;
    }
}
动态生成图片
  • 要点
  1. 根据设置尺寸、圆角、颜色值,动态创建bitmap
  2. 创建的图片使用弱引用缓存
  3. 优先使用缓存的图片
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;

import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Map;

/**
 * 动态生成图片
 */
public class BitmapUtils {
    /**
     * 缓存动态图片,提升效率
     */
    private static Map<String, WeakReference<Bitmap>> bitmapCache = new HashMap<>();

    /**
     * 动态获取bitmap
     *
     * @param width  图片高度
     * @param height 图片宽度
     * @param radius 图片圆角
     * @param color  图片颜色
     * @return 动态生成图片
     */
    public static Bitmap getBitmap(int width, int height, int radius, int color) {
        String key = getKey(width, height, radius, color);
        Bitmap bitmap = getCacheBitmap(key);
        if (null == bitmap) {
            bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(bitmap);
            Paint paint = new Paint();
            paint.setColor(color);
            paint.setAntiAlias(true);
            paint.setStyle(Paint.Style.FILL_AND_STROKE);
            canvas.drawRoundRect(new RectF(0, 0, width, height), radius, radius, paint);
            bitmapCache.put(key, new WeakReference<>(bitmap));
        }
        return bitmap;
    }

    /**
     * 生成缓存key值
     */
    private static String getKey(int width, int height, int radius, int color) {
        return "Bitmap" + width + height + radius + color;
    }

    /**
     * 获取缓存的图片
     *
     * @param key 图片key
     */
    private static Bitmap getCacheBitmap(String key) {
        if (bitmapCache.containsKey(key)) {
            WeakReference<Bitmap> bitmapWeakReference = bitmapCache.get(key);
            if (null != bitmapWeakReference) {
                Bitmap bitmap = bitmapWeakReference.get();
                if (null != bitmap && !bitmap.isRecycled()) {
                    return bitmap;
                }
            }
        }
        return null;
    }
}
总结

初步想法是使用网上开源的解决方案,但开源方案实现的蒙层效果均不太理想,因此分享出来自己造的轮子,希望给遇到同一问题的开发者提供思路。

文章目录
  1. 1. Glide图片加载添加蒙层
    1. 1.0.1. 图片添加蒙层
    2. 1.0.2. 动态生成图片
    3. 1.0.3. 总结