1. 程式人生 > >Android - 圖片處理之Glide4.0

Android - 圖片處理之Glide4.0

郭大神關於Glide文章的連線,很詳細

Android圖片載入框架最全解析(一),Glide的基本用法

Android圖片載入框架最全解析(二),從原始碼的角度理解Glide的執行流程

Android圖片載入框架最全解析(三),深入探究Glide的快取機制

Android圖片載入框架最全解析(四),玩轉Glide的回撥與監聽

Android圖片載入框架最全解析(五),Glide強大的圖片變換功能

Android圖片載入框架最全解析(六),探究Glide的自定義模組功能

Android圖片載入框架最全解析(七),實現帶進度的Glide圖片載入功能

Android圖片載入框架最全解析(八),帶你全面瞭解Glide 4的用法

Glide官網地址

Android SDK 要求

Min Sdk Version - 使用 Glide 需要 min SDK 版本 API 14 (Ice Cream Sandwich) 或更高。 Compile Sdk Version - Glide 必須使用 API 26 (Oreo) 或更高版本的 SDK 來編譯。 Support Library Version - Glide 使用的支援庫版本為 27

一般這個庫就行

 implementation 'com.android.support:appcompat-v7:27.1.1'

許可權

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

使用

載入佔位圖和錯誤圖

RequestOptions options = new RequestOptions()
        .error(R.drawable.error) //載入失敗顯示的
        .placeholder(R.drawable.loading);//載入中顯示的
Glide.with(this)
     .load(url) //圖片地址
     .apply(options) //RequestOptions 
     .into(imageView); //顯示的控制元件

簡單封裝

public class GlideUtil {
    public static void load(Context context,String url,ImageView imageView,RequestOptions options) {
        Glide.with(context)
             .load(url)
             .apply(options)
             .into(imageView);
    }
}

API介紹

API 介紹
佔位符(Placeholder) 當請求正在執行時被展示的 Drawable
錯誤符(Error) 請求永久性失敗時展示
後備回撥符(Fallback) 在請求的url/model為 null 時展示
override 指定了一個圖片的尺寸,Target.SIZE_ORIGINAL載入圖片的原始尺寸
skipMemoryCache(true) 禁用記憶體快取功能
diskCacheStrategy(DiskCacheStrategy.NONE) 禁用硬碟快取功能,引數列表如下
diskCacheStrategy引數補充
asBitmap() 只允許載入靜態圖片,。如果傳入的是GIF圖,會展示GIF圖的第一幀
asFile() 指定檔案格式
asDrawable() 指定Drawable格式
submit() 使用如下四(3)
transforms 圖片變換,Glide 預設有3個,如下四(4)

diskCacheStrategy引數補充

引數 說明
DiskCacheStrategy.NONE 表示不快取任何內容。
DiskCacheStrategy.DATA 表示只快取原始圖片。
DiskCacheStrategy.RESOURCE 表示只快取轉換過後的圖片。
DiskCacheStrategy.ALL 表示既快取原始圖片,也快取轉換過後的圖片。
DiskCacheStrategy.AUTOMATIC 表示讓Glide根據圖片資源智慧地選擇使用哪一種快取策略(預設選項)。

submit()

通過如下程式碼,可以獲取到,下載好的圖片放在哪,可以看到 都在cache下

new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    File file = Glide.with(MainActivity.this)
                            .asFile()
                            .load(url)
                            .submit()
                            .get();
                    Log.e("Tag", "path-->" + file.getPath());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                }
            }
        }).start();


 E/Tag: path-->/data/user/0/com.allens.glidedemo/cache/image_manager_disk_cache/309df01e6362ddc8939a4e3c549e8276dffb0446a89f2facee371909301fe76a.0

transforms

內建有這3個

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

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

RequestOptions options = new RequestOptions()
        .circleCrop();//圓形

一般我們還會自己去定義,以下是常用的3種轉換

使用起來也很簡單

   RequestOptions options = new RequestOptions()
                .skipMemoryCache(true)
                .diskCacheStrategy(DiskCacheStrategy.NONE);
                //圓形
               .transforms(new CircleTransform(mContext,2, Color.DKGRAY))//外圈寬度,外圈顏色
                //黑白
               .transforms(new BlackWhiteTransformation());
               //高斯模糊 範圍在 0 -- 25 越大模糊程度越高
               .transforms(new BlurTransformation(mContext, 25)); // (0 < r <= 25)
                //可以使用多種
               .transforms(new BlurTransformation(mContext, 25),new CircleTransform(mContext,2, Color.DKGRAY))

(1) 轉成黑白

package com.allens.lib_glide.Transformation;

import android.graphics.Bitmap;
import android.media.ThumbnailUtils;
import android.support.annotation.NonNull;
import android.view.animation.Transformation;

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

import java.security.MessageDigest;

/**
 * 描述:
 * <p> 黑白
 * Created by allens on 2018/1/8.
 */

public class BlackWhiteTransformation extends BitmapTransformation {
    @Override
    protected Bitmap transform(@NonNull BitmapPool pool, @NonNull Bitmap toTransform, int outWidth, int outHeight) {
        return convertToBlackWhite(toTransform);
    }

    @Override
    public void updateDiskCacheKey(MessageDigest messageDigest) {

    }

    private Bitmap convertToBlackWhite(Bitmap bmp) {
        int width = bmp.getWidth(); // 獲取點陣圖的寬
        int height = bmp.getHeight(); // 獲取點陣圖的高
        int[] pixels = new int[width * height]; // 通過點陣圖的大小建立畫素點陣列

        bmp.getPixels(pixels, 0, width, 0, 0, width, height);
        int alpha = 0xFF << 24;
        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {
                int grey = pixels[width * i + j];

                //分離三原色
                int red = ((grey & 0x00FF0000) >> 16);
                int green = ((grey & 0x0000FF00) >> 8);
                int blue = (grey & 0x000000FF);

                //轉化成灰度畫素
                grey = (int) (red * 0.3 + green * 0.59 + blue * 0.11);
                grey = alpha | (grey << 16) | (grey << 8) | grey;
                pixels[width * i + j] = grey;
            }
        }
        //新建圖片
        Bitmap newBmp = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
        //設定圖片資料
        newBmp.setPixels(pixels, 0, width, 0, 0, width, height);

        Bitmap resizeBmp = ThumbnailUtils.extractThumbnail(newBmp, 380, 460);
        return resizeBmp;
    }
}

(2)高斯模糊

package com.allens.lib_glide.Transformation;

import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Build;
import android.renderscript.Allocation;
import android.renderscript.Element;
import android.renderscript.RSRuntimeException;
import android.renderscript.RenderScript;
import android.renderscript.ScriptIntrinsicBlur;
import android.support.annotation.NonNull;

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

import java.security.MessageDigest;

/**
 * 描述: 高斯模糊
 * <p>
 * Created by allens on 2018/1/8.
 */

public class BlurTransformation extends BitmapTransformation {


    private Context context;

    private float blurRadius;

    public BlurTransformation(Context context, float blurRadius) {
        this.context = context;
        this.blurRadius = blurRadius;
    }

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

    @Override
    public void updateDiskCacheKey(MessageDigest messageDigest) {

    }

    /**
     * @param context   上下文物件
     * @param image     需要模糊的圖片
     * @param outWidth  輸入出的寬度
     * @param outHeight 輸出的高度
     * @return 模糊處理後的Bitmap
     */
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
    public Bitmap blurBitmap(Context context, Bitmap image, float blurRadius, int outWidth, int outHeight) {
        // 將縮小後的圖片做為預渲染的圖片
        Bitmap inputBitmap = Bitmap.createScaledBitmap(image, outWidth, outHeight, false);
        // 建立一張渲染後的輸出圖片
        Bitmap outputBitmap = Bitmap.createBitmap(inputBitmap);
        // 建立RenderScript核心物件
        RenderScript rs = RenderScript.create(context);
        // 建立一個模糊效果的RenderScript的工具物件
        ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
        // 由於RenderScript並沒有使用VM來分配記憶體,所以需要使用Allocation類來建立和分配記憶體空間
        // 建立Allocation物件的時候其實記憶體是空的,需要使用copyTo()將資料填充進去
        Allocation tmpIn = Allocation.createFromBitmap(rs, inputBitmap);
        Allocation tmpOut = Allocation.createFromBitmap(rs, outputBitmap);
        // 設定渲染的模糊程度, 25f是最大模糊度
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            blurScript.setRadius(blurRadius);
        }
        // 設定blurScript物件的輸入記憶體
        blurScript.setInput(tmpIn);
        // 將輸出資料儲存到輸出記憶體中
        blurScript.forEach(tmpOut);
        // 將資料填充到Allocation中
        tmpOut.copyTo(outputBitmap);
        return outputBitmap;
    }

}

(3) 圓形

package com.allens.lib_glide.Transformation;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.support.annotation.NonNull;

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

import java.security.MessageDigest;

/**
 * 描述:
 * <p> 圓形
 * Created by allens on 2018/1/8.
 */

public class CircleTransform extends BitmapTransformation {
    private Paint mBorderPaint;
    private float mBorderWidth;

    public CircleTransform(Context context) {
        super(context);
    }

    public CircleTransform(Context context, int borderWidth, int borderColor) {
        super(context);
        mBorderWidth = Resources.getSystem().getDisplayMetrics().density * borderWidth;
        mBorderPaint = new Paint();
        mBorderPaint.setDither(true);
        mBorderPaint.setAntiAlias(true);
        mBorderPaint.setColor(borderColor);
        mBorderPaint.setStyle(Paint.Style.STROKE);
        mBorderPaint.setStrokeWidth(mBorderWidth);
    }

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

    @Override
    public void updateDiskCacheKey(MessageDigest messageDigest) {

    }

    private Bitmap circleCrop(BitmapPool pool, Bitmap source) {
        if (source == null) {
            return null;
        }
        int size = (int) (Math.min(source.getWidth(), source.getHeight()) - (mBorderWidth / 2));
        int x = (source.getWidth() - size) / 2;
        int y = (source.getHeight() - size) / 2;
        Bitmap squared = Bitmap.createBitmap(source, x, y, size, size);
        Bitmap result = pool.get(size, size, Bitmap.Config.ARGB_8888);
        if (result == null) {
            result = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
        }
        Canvas canvas = new Canvas(result);
        Paint paint = new Paint();
        paint.setShader(new BitmapShader(squared, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
        paint.setAntiAlias(true);
        float r = size / 2f;
        canvas.drawCircle(r, r, r, paint);
        if (mBorderPaint != null) {
            float borderRadius = r - mBorderWidth / 2;
            canvas.drawCircle(r, r, borderRadius, mBorderPaint);
        }
        return result;
    }
}

4.0 圓角

package com.starot.spark.transformation;


import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.support.annotation.NonNull;

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

import java.security.MessageDigest;

/**
 * 描述:
 * <p> 圓形
 *
 * @author allens
 * @date 2018/1/8
 */

public class CircleTransform extends BitmapTransformation {
    private Paint mBorderPaint;
    private float mBorderWidth;

    public CircleTransform(Context context) {
        super(context);
    }

    public CircleTransform(Context context, int borderWidth, int borderColor) {
        super(context);
        mBorderWidth = Resources.getSystem().getDisplayMetrics().density * borderWidth;
        mBorderPaint = new Paint();
        mBorderPaint.setDither(true);
        mBorderPaint.setAntiAlias(true);
        mBorderPaint.setColor(borderColor);
        mBorderPaint.setStyle(Paint.Style.STROKE);
        mBorderPaint.setStrokeWidth(mBorderWidth);
    }

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

    @Override
    public void updateDiskCacheKey(MessageDigest messageDigest) {

    }

    private Bitmap circleCrop(BitmapPool pool, Bitmap source) {
        if (source == null) {
            return null;
        }
        int size = (int) (Math.min(source.getWidth(), source.getHeight()) - (mBorderWidth / 2));
        int x = (source.getWidth() - size) / 2;
        int y = (source.getHeight() - size) / 2;
        Bitmap squared = Bitmap.createBitmap(source, x, y, size, size);
        Bitmap result = pool.get(size, size, Bitmap.Config.ARGB_8888);
        if (result == null) {
            result = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
        }
        Canvas canvas = new Canvas(result);
        Paint paint = new Paint();
        paint.setShader(new BitmapShader(squared, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
        paint.setAntiAlias(true);
        float r = size / 2f;
        canvas.drawCircle(r, r, r, paint);
        if (mBorderPaint != null) {
            float borderRadius = r - mBorderWidth / 2;
            canvas.drawCircle(r, r, borderRadius, mBorderPaint);
        }
        return result;
    }
}

5.Generated API

如果4.0用的不爽,就想使用3.0版本的那種鏈式寫法,將Glide 關鍵字改成
GlideApp即可

GlideApp.with(this)
        .load(url)
        .placeholder(R.drawable.loading)
        .error(R.drawable.error)
        .skipMemoryCache(true)
        .diskCacheStrategy(DiskCacheStrategy.NONE)
        .override(Target.SIZE_ORIGINAL)
        .circleCrop()
        .into(imageView);

轉載:https://www.jianshu.com/p/9db8f314b286