Glide4.0+使用

前言

都2020年了,还讲Glide的使用确实很过时,而且网上文章和官方文档一大堆,不过,在使用中往往也只用到那几句话,但是遇到的实际问题确实很多。想小记一下,怕自己忘记了。

使用

导包

  api 'com.github.bumptech.glide:glide:4.9.0'
    api 'com.github.bumptech.glide:disklrucache:4.9.0'
    api 'com.github.bumptech.glide:annotations:4.9.0'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.6.1'
    api 'com.github.bumptech.glide:gifdecoder:4.9.0'

一般项目都会集成okhttp的,如果没有,需要加上以下库:

   api 'com.github.bumptech.glide:okhttp3-integration:4.9.0'

和网络访问权限:

   <uses-permission android:name="android.permission.INTERNET" />

初始化

由于最新4.0+版本引入了注解器,需要注解初始化,生产build文件。需要在包目录下添加如下代码:

package com.hujin.wan;


import com.bumptech.glide.annotation.GlideModule;
import com.bumptech.glide.module.AppGlideModule;

@GlideModule
public class MyAppGlideModule extends AppGlideModule {
}

重新编译后(如遇到androidx适配问题,可参考后面),会产生新的文件:
在这里插入图片描述

具体使用

加载
资源文件加载
   		int resId = R.mipmap.ic_launcher;
        GlideApp.with(context)
                .load(resId)
                .into(imageView);
网络加载
   String url = "https://www.baidu.com/img/flexible/logo/pc/result@2.png";
        GlideApp.with(context)
                .load(url)
                .into(imageView);             
文件加载
      File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "test.jpg");
        GlideApp.with(context)
                .load(file)
                .into(imageView);
加载asset下图片

asset只是Uri的一种,可支持各类型Uri

  Uri parse = Uri.parse("file:///android_asset/<assetName>");
        GlideApp.with(context)
                .load(parse)
                .into(imageView);
加载bitmap
  	    int res = R.mipmap.ic_launcher;
        Bitmap bitmap = BitmapUtil.resourcesToBitmap(context, res);
        GlideApp.with(context)
                .load(bitmap)
                .into(imageView);

上述代码的工具方法:

 public static Bitmap resourcesToBitmap(Context context, int resId) {
        Bitmap bitmap = null;
        try {
            //将资源文件转化为bitmap
            bitmap = BitmapFactory.decodeResource(context.getResources(), resId, null);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return bitmap;
    }
占位图
  		int resID = R.mipmap.ic_launcher;
        Drawable placeholderDrawable = imageView.getDrawable();
        int resFall= R.mipmap.icon_fall;
        int resError = R.mipmap.icon_error;
        GlideApp.with(context)
                .load(resID)
                //占位图
                .placeholder(placeholderDrawable)
                //失败占位
                .fallback(resFall)
                //错误占位
                .error(resError)
                .into(imageView);
动画效果
淡入淡出

4.0+之后舍弃了crossFade(),改为DrawableCrossFadeFactory工厂类去创建淡入淡出动画。可设置动画时间,和是否开启交叉效果。

 DrawableCrossFadeFactory.Builder builder = new DrawableCrossFadeFactory.Builder(3000);
                DrawableCrossFadeFactory build = builder.setCrossFadeEnabled(false).build();
                int resId = R.mipmap.icon_car;
                GlideApp.with(context)
                        .load(resId)
                        .placeholder(R.mipmap.ic_launcher)
                        .transition(DrawableTransitionOptions.withCrossFade(build))
                        .into(imageView);
关闭动画

dontAnimate()方法慎用,会让gif动图停留在第一帧。

         int resId = R.mipmap.icon_car;
        GlideApp.with(context)
                .load(resId)
                //取消动画
                .dontAnimate()
                //取消转换动画
                .dontTransform()
                .placeholder(R.mipmap.ic_launcher)
                .into(imageView);
图片裁剪与变换

先看下控件imageview自带的ScaleType属性,其fitCenter为图片的默认属性:

matrix不缩放 ,图片与控件 左上角 对齐,当图片大小超过控件时将被 裁剪
center不缩放 ,图片与控件 中心点 对齐,当图片大小超过控件时将被 裁剪
centerInside以完整显示图片为目标, 不剪裁 ,当显示不下的时候将缩放,能够显示的情况下不缩放
centerCrop以填满整个控件为目标,等比缩放,超过控件时将被 裁剪 ( 宽高都要填满 ,所以只要图片宽高比与控件宽高比不同时,一定会被剪裁)
fitCenter以完整显示图片为目标, 不剪裁 ,当显示不下的时候将缩放,能够显示的情况下不缩放
fitStart自适应控件, 不剪裁 ,在不超过控件的前提下,等比 缩放 到 最大 ,靠左(上)显示
fitEnd自适应控件, 不剪裁 ,在不超过控件的前提下,等比 缩放 到 最大 ,靠右(下)显示
fitXY以填满整个控件为目标, 不按比例 拉伸或缩放(可能会变形), 不剪裁
fitCenter

参考如上裁剪描述:

  int resId = R.mipmap.icon_car;
        GlideApp.with(context)
                .load(resId)
                .fitCenter()
                .into(imageView);
circleCrop圆形剪裁
 int resId = R.mipmap.icon_car;
        GlideApp.with(context)
                .load(resId)
                .circleCrop()
                .into(imageView);

在这里插入图片描述

centerInside

参考如上裁剪描述:

    int resId = R.mipmap.icon_car;
        GlideApp.with(context)
                .load(resId)
                .centerInside()
                .into(imageView);

完整显示图片,但是未填充满。
在这里插入图片描述

centerCrop

参考如上裁剪描述:

   int resId = R.mipmap.icon_car;
        GlideApp.with(context)
                .load(resId)
                .centerCrop()
                .into(imageView);

控件完全填充,在等比拉伸情况下,高度出现剪裁。
在这里插入图片描述

自定义变换
圆角变换

经常会遇到设置图片的圆角或者更过分的、只设置左上圆角,或者上下左右圆角个不一样。而glide自带的只能实现纯圆形的变换,所以需要自定义圆角变换。
glide提交了BitmapTransformation入口来实现自定义。这里提供一份功能比较全的圆角变换:
例子:这里设置图片宽高为300:200dp便于展示效果

RequestOptions requestOptions = new RequestOptions();
        requestOptions.optionalTransform(new GlideRoundedCornersTransform(12f,30f,15f,40f));
        int resId = R.mipmap.icon_car;
        GlideApp.with(context)
                .load(resId)
                .apply(requestOptions)
                .into(imageView);

效果:
在这里插入图片描述
GlideRoundedCornersTransform代码如下:

package com.hujin.wan.util;

import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;

import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.load.resource.bitmap.CenterCrop;
import com.hujin.wan.BuildConfig;
import com.hujin.wan.DisplayUtils;

import java.security.MessageDigest;

/**
 * @author apppp
 */
public class GlideRoundedCornersTransform extends CenterCrop {
    private float mRadius;
    private CornerType mCornerType;
    private static final int VERSION = 1;
    private static final String ID = BuildConfig.APPLICATION_ID+"GlideRoundedCornersTransform." + VERSION;
    private static final byte[] ID_BYTES = ID.getBytes(CHARSET);
    private int[] radiusAll = new int[4];

    public enum CornerType {
        /**
         * 四个角
         */
        ALL,
        TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT,
        TOP, BOTTOM, LEFT, RIGHT,
        TOP_LEFT_BOTTOM_RIGHT,
        TOP_RIGHT_BOTTOM_LEFT,
        TOP_LEFT_TOP_RIGHT_BOTTOM_RIGHT,
        TOP_RIGHT_BOTTOM_RIGHT_BOTTOM_LEFT,
    }

    public GlideRoundedCornersTransform(float radius, CornerType cornerType) {
        super();
        //dp ->px
        int dp2px = DisplayUtils.dp2px(radius);
        mRadius = dp2px;
        radiusAll[0] =  dp2px;
        radiusAll[1] =  dp2px;
        radiusAll[2] =  dp2px;
        radiusAll[3] =  dp2px;
        mCornerType = cornerType;
    }

    /**
     * 分别指定 四个圆角半径 所以这里cornerType为ALL
     * @param tl 左上
     * @param tr 右上
     * @param br 右下
     * @param bl 左下
     */
    public GlideRoundedCornersTransform(float tl,float tr,float br, float bl) {
        super();
        //dp ->px
        radiusAll[0] =  DisplayUtils.dp2px(tl);
        radiusAll[1] =  DisplayUtils.dp2px(tr);
        radiusAll[2] =  DisplayUtils.dp2px(br);
        radiusAll[3] =  DisplayUtils.dp2px(bl);
        mCornerType = CornerType.ALL;
    }

    @Override
    protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
        Bitmap transform = super.transform(pool, toTransform, outWidth, outHeight);
        return roundCrop(pool, transform);
    }

    private Bitmap roundCrop(BitmapPool pool, Bitmap source) {
        if (source == null) {
            return null;
        }
        int width = source.getWidth();
        int height = source.getHeight();
        Bitmap result = pool.get(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(result);
        Paint paint = new Paint();
        paint.setShader(new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader
                .TileMode.CLAMP));
        paint.setAntiAlias(true);

        Path path = new Path();
        drawRoundRect(canvas, paint, path, width, height);

        return result;
    }

    private void drawRoundRect(Canvas canvas, Paint paint, Path path, int width, int height) {
         float[] rids ;
        switch (mCornerType) {
            case ALL:
                rids = new float[]{radiusAll[0],radiusAll[0],radiusAll[1],radiusAll[1],radiusAll[2],radiusAll[2],radiusAll[3],radiusAll[3]};
                drawPath(rids,canvas, paint, path, width, height);
                break;
            case TOP_LEFT:
                rids = new float[]{mRadius,mRadius,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f};
                drawPath(rids,canvas, paint, path, width, height);
                break;
            case TOP_RIGHT:
                rids  = new float[]{0.0f,0.0f,mRadius,mRadius,0.0f,0.0f,0.0f,0.0f};
                drawPath(rids,canvas, paint, path, width, height);
                break;
            case BOTTOM_RIGHT:
                rids  = new float[]{0.0f,0.0f,0.0f,0.0f,mRadius,mRadius,0.0f,0.0f};
                drawPath(rids,canvas,  paint, path, width, height);
                break;
            case BOTTOM_LEFT:
                rids  = new float[]{0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,mRadius,mRadius};
                drawPath(rids,canvas,  paint, path, width, height);
                break;
            case TOP:
                rids = new float[]{mRadius,mRadius,mRadius,mRadius,0.0f,0.0f,0.0f,0.0f};
                drawPath(rids,canvas,  paint,  path,width, height);
                break;
            case BOTTOM:
                rids  = new float[]{0.0f,0.0f,0.0f,0.0f,mRadius,mRadius,mRadius,mRadius};
                drawPath(rids,canvas,  paint, path, width, height);
                break;
            case LEFT:
                rids = new float[]{mRadius,mRadius,0.0f,0.0f,0.0f,0.0f,mRadius,mRadius};
                drawPath(rids,canvas,  paint, path, width, height);
                break;
            case RIGHT:
                rids  = new float[]{0.0f,0.0f,mRadius,mRadius,mRadius,mRadius,0.0f,0.0f};
                drawPath(rids,canvas,  paint, path, width, height);
                break;
            case TOP_LEFT_BOTTOM_RIGHT:
                rids  = new float[]{mRadius,mRadius,0.0f,0.0f,mRadius,mRadius,0.0f,0.0f};
                drawPath(rids,canvas,  paint, path, width, height);
                break;
            case TOP_RIGHT_BOTTOM_LEFT:
                rids  = new float[]{0.0f,0.0f,mRadius,mRadius,0.0f,0.0f,mRadius,mRadius};
                drawPath(rids,canvas,  paint, path, width, height);
                break;
            case TOP_LEFT_TOP_RIGHT_BOTTOM_RIGHT:
                rids  = new float[]{mRadius,mRadius,mRadius,mRadius,mRadius,mRadius,0.0f,0.0f};
                drawPath(rids,canvas,  paint, path, width, height);
                break;
            case TOP_RIGHT_BOTTOM_RIGHT_BOTTOM_LEFT:
                rids  = new float[]{0.0f,0.0f,mRadius,mRadius,mRadius,mRadius,mRadius,mRadius};
                drawPath(rids,canvas,  paint,  path,width, height);
                break;
            default:
                throw new RuntimeException("RoundedCorners type not belong to CornerType");
        }
    }


    /**@param rids 圆角的半径,依次为左上角xy半径,右上角,右下角,左下角*/
    private void drawPath(float[] rids,Canvas canvas,Paint paint,Path path, int width, int height) {
        path.addRoundRect(new RectF(0, 0, width, height), rids, Path.Direction.CW);
        canvas.drawPath(path,paint);
    }


    @Override
    public boolean equals(Object o) {
        return o instanceof GlideRoundedCornersTransform;
    }


    @Override
    public int hashCode() {
        return ID.hashCode();
    }


    @Override
    public void updateDiskCacheKey(MessageDigest messageDigest) {
        messageDigest.update(ID_BYTES);
    }
}

黑白变换
RequestOptions requestOptions = new RequestOptions();
        requestOptions.optionalTransform(new BlackWhiteTransformation());
        int resId = R.mipmap.icon_car;
        GlideApp.with(context)
                .load(resId)
                .apply(requestOptions)
                .into(imageView);

效果:
在这里插入图片描述
BlackWhiteTransformation代码如下

public class BlackWhiteTransformation extends BitmapTransformation {
    private static final int VERSION = BuildConfig.VERSION_CODE;
    private static final String ID = BuildConfig.APPLICATION_ID + "BlackWhiteTransformation." + VERSION;
    private static final byte[] ID_BYTES = ID.getBytes(CHARSET);

    @Override
    protected Bitmap transform(@NonNull BitmapPool pool, @NonNull Bitmap toTransform, int outWidth, int outHeight) {
        int width = toTransform.getWidth();
        int height = toTransform.getHeight();

        Bitmap.Config config =
                toTransform.getConfig() != null ? toTransform.getConfig() : Bitmap.Config.ARGB_8888;
        Bitmap bitmap = pool.get(width, height, config);

        setCanvasBitmapDensity(toTransform, bitmap);

        Canvas canvas = new Canvas(bitmap);
        ColorMatrix saturation = new ColorMatrix();
        saturation.setSaturation(0f);
        Paint paint = new Paint();
        paint.setColorFilter(new ColorMatrixColorFilter(saturation));
        canvas.drawBitmap(toTransform, 0, 0, paint);

        return bitmap;
    }

    @Override
    public void updateDiskCacheKey(MessageDigest messageDigest) {
        messageDigest.update(ID_BYTES);
    }



    @Override
    public boolean equals(Object o) {
        return o instanceof GlideRoundedCornersTransform;
    }


    @Override
    public int hashCode() {
        return ID.hashCode();
    }

    private void setCanvasBitmapDensity(@NonNull Bitmap toTransform, @NonNull Bitmap canvasBitmap) {
        canvasBitmap.setDensity(toTransform.getDensity());
    }
}
高斯模糊
  RequestOptions requestOptions = new RequestOptions();
        requestOptions.optionalTransform(new BlurTransformation(context));
        int resId = R.mipmap.icon_car;
        GlideApp.with(context)
                .load(resId)
                .apply(requestOptions)
                .into(imageView);

效果:
在这里插入图片描述
BlurTransformation代码如下:

public class BlurTransformation extends BitmapTransformation {

    private static final int VERSION = 1;
    private static final String ID = BuildConfig.APPLICATION_ID + "BlurTransformation." + VERSION;

    private static final int MAX_RADIUS = 25;
    private static final int DEFAULT_DOWN_SAMPLING = 1;

    private final int radius;
    private final int sampling;
    private Context mContext;

    public BlurTransformation(Context context) {
        this(MAX_RADIUS, DEFAULT_DOWN_SAMPLING, context);
    }

    public BlurTransformation(int radius, int sampling, Context context) {
        this.mContext = context.getApplicationContext();
        this.radius = radius;
        this.sampling = sampling;
    }

    void setCanvasBitmapDensity(@NonNull Bitmap toTransform, @NonNull Bitmap canvasBitmap) {
        canvasBitmap.setDensity(toTransform.getDensity());
    }

    @Override
    protected Bitmap transform(@NonNull BitmapPool pool, @NonNull Bitmap toTransform, int outWidth, int outHeight) {
        int width = toTransform.getWidth();
        int height = toTransform.getHeight();
        int scaledWidth = width / sampling;
        int scaledHeight = height / sampling;

        Bitmap bitmap = pool.get(scaledWidth, scaledHeight, Bitmap.Config.ARGB_8888);

        setCanvasBitmapDensity(toTransform, bitmap);

        Canvas canvas = new Canvas(bitmap);
        canvas.scale(1 / (float) sampling, 1 / (float) sampling);
        Paint paint = new Paint();
        paint.setFlags(Paint.FILTER_BITMAP_FLAG);
        canvas.drawBitmap(toTransform, 0, 0, paint);

        try {
            bitmap = blur(mContext, bitmap, radius);
        } catch (RSRuntimeException e) {
            bitmap = fastBlur(bitmap, radius, true);
        }
        return bitmap;
    }


    @Override
    public String toString() {
        return "BlurTransformation(radius=" + radius + ", sampling=" + sampling + ")";
    }

    @Override
    public boolean equals(Object o) {
        return o instanceof BlurTransformation &&
                ((BlurTransformation) o).radius == radius &&
                ((BlurTransformation) o).sampling == sampling;
    }

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

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

    public Bitmap blur(Context context, Bitmap bitmap, int radius) throws RSRuntimeException {
        RenderScript rs = null;
        Allocation input = null;
        Allocation output = null;
        ScriptIntrinsicBlur blur = null;
        try {
            rs = RenderScript.create(context);
            rs.setMessageHandler(new RenderScript.RSMessageHandler());
            input = Allocation.createFromBitmap(rs, bitmap, Allocation.MipmapControl.MIPMAP_NONE,
                    Allocation.USAGE_SCRIPT);
            output = Allocation.createTyped(rs, input.getType());
            blur = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));

            blur.setInput(input);
            blur.setRadius(radius);
            blur.forEach(output);
            output.copyTo(bitmap);
        } finally {
            if (rs != null) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    RenderScript.releaseAllContexts();
                } else {
                    rs.destroy();
                }
            }
            if (input != null) {
                input.destroy();
            }
            if (output != null) {
                output.destroy();
            }
            if (blur != null) {
                blur.destroy();
            }
        }

        return bitmap;
    }

    private Bitmap fastBlur(Bitmap sentBitmap, int radius, boolean canReuseInBitmap) {
        Bitmap bitmap;
        if (canReuseInBitmap) {
            bitmap = sentBitmap;
        } else {
            bitmap = sentBitmap.copy(sentBitmap.getConfig(), true);
        }

        if (radius < 1) {
            return (null);
        }

        int w = bitmap.getWidth();
        int h = bitmap.getHeight();

        int[] pix = new int[w * h];
        bitmap.getPixels(pix, 0, w, 0, 0, w, h);

        int wm = w - 1;
        int hm = h - 1;
        int wh = w * h;
        int div = radius + radius + 1;

        int[] r = new int[wh];
        int[] g = new int[wh];
        int[] b = new int[wh];
        int rsum, gsum, bsum, x, y, i, p, yp, yi, yw;
        int[] vmin = new int[Math.max(w, h)];

        int divsum = (div + 1) >> 1;
        divsum *= divsum;
        int[] dv = new int[256 * divsum];
        for (i = 0; i < 256 * divsum; i++) {
            dv[i] = (i / divsum);
        }

        yw = yi = 0;

        int[][] stack = new int[div][3];
        int stackpointer;
        int stackstart;
        int[] sir;
        int rbs;
        int r1 = radius + 1;
        int routsum, goutsum, boutsum;
        int rinsum, ginsum, binsum;

        for (y = 0; y < h; y++) {
            rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
            for (i = -radius; i <= radius; i++) {
                p = pix[yi + Math.min(wm, Math.max(i, 0))];
                sir = stack[i + radius];
                sir[0] = (p & 0xff0000) >> 16;
                sir[1] = (p & 0x00ff00) >> 8;
                sir[2] = (p & 0x0000ff);
                rbs = r1 - Math.abs(i);
                rsum += sir[0] * rbs;
                gsum += sir[1] * rbs;
                bsum += sir[2] * rbs;
                if (i > 0) {
                    rinsum += sir[0];
                    ginsum += sir[1];
                    binsum += sir[2];
                } else {
                    routsum += sir[0];
                    goutsum += sir[1];
                    boutsum += sir[2];
                }
            }
            stackpointer = radius;

            for (x = 0; x < w; x++) {

                r[yi] = dv[rsum];
                g[yi] = dv[gsum];
                b[yi] = dv[bsum];

                rsum -= routsum;
                gsum -= goutsum;
                bsum -= boutsum;

                stackstart = stackpointer - radius + div;
                sir = stack[stackstart % div];

                routsum -= sir[0];
                goutsum -= sir[1];
                boutsum -= sir[2];

                if (y == 0) {
                    vmin[x] = Math.min(x + radius + 1, wm);
                }
                p = pix[yw + vmin[x]];

                sir[0] = (p & 0xff0000) >> 16;
                sir[1] = (p & 0x00ff00) >> 8;
                sir[2] = (p & 0x0000ff);

                rinsum += sir[0];
                ginsum += sir[1];
                binsum += sir[2];

                rsum += rinsum;
                gsum += ginsum;
                bsum += binsum;

                stackpointer = (stackpointer + 1) % div;
                sir = stack[(stackpointer) % div];

                routsum += sir[0];
                goutsum += sir[1];
                boutsum += sir[2];

                rinsum -= sir[0];
                ginsum -= sir[1];
                binsum -= sir[2];

                yi++;
            }
            yw += w;
        }
        for (x = 0; x < w; x++) {
            rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
            yp = -radius * w;
            for (i = -radius; i <= radius; i++) {
                yi = Math.max(0, yp) + x;

                sir = stack[i + radius];

                sir[0] = r[yi];
                sir[1] = g[yi];
                sir[2] = b[yi];

                rbs = r1 - Math.abs(i);

                rsum += r[yi] * rbs;
                gsum += g[yi] * rbs;
                bsum += b[yi] * rbs;

                if (i > 0) {
                    rinsum += sir[0];
                    ginsum += sir[1];
                    binsum += sir[2];
                } else {
                    routsum += sir[0];
                    goutsum += sir[1];
                    boutsum += sir[2];
                }

                if (i < hm) {
                    yp += w;
                }
            }
            yi = x;
            stackpointer = radius;
            for (y = 0; y < h; y++) {
                // Preserve alpha channel: ( 0xff000000 & pix[yi] )
                pix[yi] = (0xff000000 & pix[yi]) | (dv[rsum] << 16) | (dv[gsum] << 8) | dv[bsum];

                rsum -= routsum;
                gsum -= goutsum;
                bsum -= boutsum;

                stackstart = stackpointer - radius + div;
                sir = stack[stackstart % div];

                routsum -= sir[0];
                goutsum -= sir[1];
                boutsum -= sir[2];

                if (x == 0) {
                    vmin[y] = Math.min(y + r1, hm) * w;
                }
                p = x + vmin[y];

                sir[0] = r[p];
                sir[1] = g[p];
                sir[2] = b[p];

                rinsum += sir[0];
                ginsum += sir[1];
                binsum += sir[2];

                rsum += rinsum;
                gsum += ginsum;
                bsum += binsum;

                stackpointer = (stackpointer + 1) % div;
                sir = stack[stackpointer];

                routsum += sir[0];
                goutsum += sir[1];
                boutsum += sir[2];

                rinsum -= sir[0];
                ginsum -= sir[1];
                binsum -= sir[2];

                yi += w;
            }
        }

        bitmap.setPixels(pix, 0, w, 0, 0, w, h);

        return (bitmap);

    }
}
组合变换

glide也支持组合变换效果,现在将上面三种组合起来实现黑白、圆角、高斯模糊组合效果。


        int resId = R.mipmap.icon_car;
        GlideApp.with(context)
                .load(resId)
                .transform(new BlurTransformation(context), 
                        new BlackWhiteTransformation(),
                        new GlideRoundedCornersTransform(25.0f, GlideRoundedCornersTransform.CornerType.ALL))
                .into(imageView);

效果:
在这里插入图片描述

播放gif

不做任何处理,是默认支持gif的,但是有的gif会在某些手机上播放速率会有问题。后面会给出处理方案。

   int resId = R.mipmap.icon_gif;
        GlideApp.with(context)
                .asGif()
                //.dontAnimate()
                .load(resId)
                .into(imageView);

对于gif图片,asGif加不加没啥影响。但是如果调用dontAnimate会导致gif加载空白或者停留在第一帧。

请求优先级

glide支持图片加载的优先级,但是这个不一定是稳定的。

  String url = "https://www.baidu.com/img/flexible/logo/pc/result@2.png";
        GlideApp.with(context)
                .load(url)
                .priority(Priority.LOW)
                .into(imageView);

支持的优先级:

public enum Priority {
  IMMEDIATE,
  HIGH,
  NORMAL,
  LOW,
}
缩略图

模式一:接受一个float类型参数,表示展示 原尺寸乘以该系数 后得到的缩略图。

  String url = "https://www.baidu.com/img/flexible/logo/pc/result@2.png";
        GlideApp.with(context)
                .load(url)
                .thumbnail(0.1f)
                .into(imageView);

模式二:缩略请求,对于大图用用就行

    String urlThumb = "https://www.baidu.com/img/flexible/logo/pc/result@2.png";
        String url = "https://www.baidu.com/img/flexible/logo/pc/result@2.png";
        RequestBuilder<Drawable> drawableRequestBuilder = Glide.with(context).load(urlThumb);
        GlideApp.with(context)
                .load(url)
                .thumbnail(drawableRequestBuilder)
                .into(imageView);
缓存基础
内存缓存
        int resId = R.mipmap.icon_car;
        GlideApp.with(context)
                .load(resId)
                .skipMemoryCache(true)
                .into(imageView);

使用skipMemoryCache(true)后,会告诉glide跳过该图片的缓存,并且加载后不会把该图片的缓存在内存里。但是还是会存储到磁盘缓存。

磁盘缓存
 int resId = R.mipmap.icon_car;
        GlideApp.with(context)
                .load(resId)
                .diskCacheStrategy(DiskCacheStrategy.NONE)
                .into(imageView);

设置diskCacheStrategy方法会设置磁盘缓存策略:

  • DiskCacheStrategy.NONE 不缓存
  • DiskCacheStrategy.SOURCE 只缓存全尺寸图
  • DiskCacheStrategy.RESULT 只缓存最终降低分辨后用到的图片
  • DiskCacheStrategy.ALL SOURCE和RESULT策略都执行
回调

目前支持的回调类型:Bitmap Drawable GifDrawable File
然后还支持自定义类型,调用as方法

  int resId = R.mipmap.icon_car;
        GlideApp.with(context)
                .asBitmap()
                .load(resId)
                .addListener(new RequestListener<Bitmap>() {
                    @Override
                    public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Bitmap> target, boolean isFirstResource) {
                        return false;
                    }

                    @Override
                    public boolean onResourceReady(Bitmap resource, Object model, Target<Bitmap> target, DataSource dataSource, boolean isFirstResource) {
                        return false;
                    }
                })
                .into(imageView);

        GlideApp.with(context)
                .asDrawable()
                .load(resId)
                .listener(new RequestListener<Drawable>() {
                    @Override
                    public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
                        return false;
                    }

                    @Override
                    public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
                        return false;
                    }
                })
                .into(imageView);

        GlideApp.with(context)
                .asFile()
                .load(resId)
                .listener(new RequestListener<File>() {
                    @Override
                    public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<File> target, boolean isFirstResource) {
                        return false;
                    }

                    @Override
                    public boolean onResourceReady(File resource, Object model, Target<File> target, DataSource dataSource, boolean isFirstResource) {
                        return false;
                    }
                })
                .into(imageView);


        GlideApp.with(context)
                .asGif()
                .load(resId)
                .listener(new RequestListener<GifDrawable>() {
                    @Override
                    public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<GifDrawable> target, boolean isFirstResource) {
                        return false;
                    }

                    @Override
                    public boolean onResourceReady(GifDrawable resource, Object model, Target<GifDrawable> target, DataSource dataSource, boolean isFirstResource) {
                        return false;
                    }
                })
                .into(imageView);


        GlideApp.with(context)
                .as(String.class)
                .load(resId)
                .listener(new RequestListener<String>() {
                    @Override
                    public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<String> target, boolean isFirstResource) {
                        return false;
                    }

                    @Override
                    public boolean onResourceReady(String resource, Object model, Target<String> target, DataSource dataSource, boolean isFirstResource) {
                        return false;
                    }
                })
                .into(imageView);

结语

一般开发的用法,应该都包含了。一些遇到的问题会新开一篇记录以下。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Glide 是一个 Android 平台上的图片加载库,用于加载本地或网络上的图片。使用 Glide 可以方便地加载图片、GIF 图片、缩略图等,而且还支持图片缓存,可以提高图片加载速度。 以下是 Glide 的基本使用方法: 1. 添加依赖 在项目的 build.gradle 文件中添加以下依赖: ``` dependencies { implementation 'com.github.bumptech.glide:glide:4.12.0' annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0' } ``` 2. 加载图片 在代码中使用 Glide 加载图片: ``` Glide.with(context) .load("图片 URL 或本地图片路径") .into(imageView); ``` 其中,context 为上下文对象,imageView 为显示图片的 ImageView 控件。 3. 加载 GIF 图片 加载 GIF 图片同样很简单,只需要将图片的 URL 或本地路径传入 load() 方法即可: ``` Glide.with(context) .asGif() .load("GIF 图片 URL 或本地路径") .into(imageView); ``` 4. 加载缩略图 可以使用 Glide 加载缩略图,这样可以提高图片加载速度。以下是加载缩略图的示例代码: ``` Glide.with(context) .load("图片 URL 或本地图片路径") .thumbnail(0.2f) // 加载原图的 20% 作为缩略图 .into(imageView); ``` 5. 图片缓存 Glide 默认会对加载的图片进行缓存,可以使用以下代码设置缓存策略: ``` Glide.with(context) .load("图片 URL 或本地图片路径") .diskCacheStrategy(DiskCacheStrategy.NONE) // 禁用磁盘缓存 .skipMemoryCache(true) // 禁用内存缓存 .into(imageView); ``` 以上就是 Glide 的基本使用方法,可以根据实际需求进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值