Glide图片加载库的使用

Glide是 Google推荐的图片加载库,它可以支持来自url,Android资源,文件,Uri中的图片加载,同时还支持gif图片的加载,以及各种图片显示前的bitmap处理(例如:圆角图片,圆形图片,高斯模糊,旋转,灰度等等),缓存处理,请求优先级处理,动画处理,缩略图处理,图片大小自定义等等.可谓是非常的强大.

1.添加Glide库

需要在build.gradle中加入依赖,目前最新的版本是3.7.0,Glide库地址

 compile 'com.github.bumptech.glide:glide:3.7.0'

2.加载网络图片

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

/**

 * Created by mChenys on 2016/6/6.

 */

public class TestGlideActivity extends Activity {

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_test);

        String url = "http://www.qq745.com/uploads/allimg/141106/1-141106153Q5.png";

        ImageView targetView = (ImageView) findViewById(R.id.iv_target);

        Glide.with(this).

                load(url).

                asBitmap(). //强制处理为bitmap

                into(targetView);//显示到目标View中

    }

}

3.加载资源图片

1

2

3

4

5

6

7

8

9

10

11

12

13

public class TestGlideActivity extends Activity {

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_test);

        int resourceId = R.drawable.test;

        ImageView targetView = (ImageView) findViewById(R.id.iv_target);

        Glide.with(this).

                load(resourceId).

                asBitmap().

                into(targetView);

    }

}

4.加载本地文件图片

1

2

3

4

5

6

7

8

9

10

11

12

13

public class TestGlideActivity extends Activity {

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_test);

        File file = new File(Environment.getExternalStorageDirectory(), "test.jpg");

        ImageView targetView = (ImageView) findViewById(R.id.iv_target);

        Glide.with(this).

                load(file).

                asBitmap().

                into(targetView);

    }

}

5.从Uri中加载

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

/**

 * Created by mChenys on 2016/6/6.

 */

public class TestGlideActivity extends Activity {

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_test);

        Uri uri = Uri.parse("android.resource://" + this.getPackageName() + "/" + R.drawable.test);

        ImageView targetView = (ImageView) findViewById(R.id.iv_target);

        Glide.with(this).

                load(uri).

                asBitmap().

                into(targetView);

    }

}

6.加载gif图片

1

2

3

4

5

6

7

8

9

10

11

12

public class TestGlideActivity extends Activity {

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_test);

        ImageView targetView = (ImageView) findViewById(R.id.iv_target);

        Glide.with(this).

                load(R.drawable.smail).

                asGif().//注意:这里显示的指明了要加载的是gif图片,当然即使不指明,glide也会自己判断.

                into(targetView);

    }

}

效果图:

7.设置默认图片和加载失败时显示的图片

1

2

3

4

5

6

7

8

9

10

11

12

13

14

public class TestGlideActivity extends Activity {

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_test);

        ImageView targetView = (ImageView) findViewById(R.id.iv_target);

        Glide.with(this).

                load(R.drawable.test).

                asBitmap().

                placeholder(R.drawable.bg_loading).//加载中显示的图片

                error(R.drawable.bg_error).//加载失败时显示的图片

                into(targetView);

    }

}

8.淡入显示效果

1

2

3

4

5

6

7

8

9

10

11

12

13

14

public class TestGlideActivity extends Activity {

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_test);

        ImageView targetView = (ImageView) findViewById(R.id.iv_target);

        Glide.with(this).

                load(R.drawable.test).

                placeholder(R.drawable.bg_loading).//加载中显示的图片

                error(R.drawable.bg_error).//加载失败时显示的图片

                crossFade().//淡入显示,注意:如果设置了这个,则必须要去掉asBitmap

                into(targetView);

    }

}

另外,crossFade还可以接收一个参数来设置淡入显示效果的持续时间,crossFade(int duration);
如果你想直接显示图片,而不是淡入显示图片,则可以通过dontAnimate()方法设置.

9.调整图片像素大小

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

public class TestGlideActivity extends Activity {

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_test);

        ImageView targetView = (ImageView) findViewById(R.id.iv_target);

        Glide.with(this).

                load(R.drawable.test).

                placeholder(R.drawable.bg_loading).//加载中显示的图片

                error(R.drawable.bg_error).//加载失败时显示的图片

                crossFade(1000).//淡入显示的时间,注意:如果设置了这个,则必须要去掉asBitmap

                override(80,80).//设置最终显示的图片像素为80*80,注意:这个是像素,而不是控件的宽高

                into(targetView);

    }

}

10.设置CenterCrop,FitCenter

CenterCrop,FitCenter都是对目标图片进行裁剪,了解过ImageView的ScaleType属性就知道,这2种裁剪方式在ImageView上也是有的,分别对应ImageView的ImageView.ScaleType.CENTER_CROP和mageView.ScaleType.FIT_CENTER的.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

public class TestGlideActivity extends Activity {

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_test);

        ImageView targetView = (ImageView) findViewById(R.id.iv_target);

        targetView.setScaleType(ImageView.ScaleType.FIT_CENTER);

        Glide.with(this).

                load(R.drawable.test).

                placeholder(R.drawable.bg_loading).//加载中显示的图片

                error(R.drawable.bg_error).//加载失败时显示的图片

                crossFade(1000).//淡入淡出,注意:如果设置了这个,则必须要去掉asBitmap

                override(80,80).//设置最终显示的图片像素为80*80,注意:这个是像素,而不是控件的宽高

                centerCrop().//中心裁剪,缩放填充至整个ImageView

                into(targetView);

    }

}

11.缓存策略设置

内存缓存设置,通过skipMemoryCache(boolean)来设置是否需要缓存到内存,默认是会缓存到内存的.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

/**

 * Created by mChenys on 2016/6/6.

 */

public class TestGlideActivity extends Activity {

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_test);

        ImageView targetView = (ImageView) findViewById(R.id.iv_target);

        targetView.setScaleType(ImageView.ScaleType.FIT_CENTER);

        Glide.with(this).

                load(R.drawable.test).

                placeholder(R.drawable.bg_loading).//加载中显示的图片

                error(R.drawable.bg_error).//加载失败时显示的图片

                crossFade(1000).//淡入淡出,注意:如果设置了这个,则必须要去掉asBitmap

                override(80,80).//设置最终显示的图片像素为80*80,注意:这个是像素,而不是控件的宽高

                centerCrop().//中心裁剪,缩放填充至整个ImageView

                skipMemoryCache(true).//跳过内存缓存

                into(targetView);

    }

}

磁盘缓存,磁盘缓存通过diskCacheStrategy(DiskCacheStrategy)来设置,DiskCacheStrategy一共有4种模式:

1. DiskCacheStrategy.NONE:什么都不缓存

2. DiskCacheStrategy.SOURCE:仅缓存原图(全分辨率的图片)

3. DiskCacheStrategy.RESULT:仅缓存最终的图片,即修改了尺寸或者转换后的图片

4. DiskCacheStrategy.ALL:缓存所有版本的图片,默认模式

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

public class TestGlideActivity extends Activity {

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_test);

        ImageView targetView = (ImageView) findViewById(R.id.iv_target);

        targetView.setScaleType(ImageView.ScaleType.FIT_CENTER);

        Glide.with(this).

                load(R.drawable.test).

                placeholder(R.drawable.bg_loading).//加载中显示的图片

                error(R.drawable.bg_error).//加载失败时显示的图片

                crossFade(1000).//淡入淡出,注意:如果设置了这个,则必须要去掉asBitmap

                override(8080).//设置最终显示的图片像素为80*80,注意:这个是像素,而不是控件的宽高

                centerCrop().//中心裁剪,缩放填充至整个ImageView

                skipMemoryCache(true).//跳过内存缓存

                diskCacheStrategy(DiskCacheStrategy.RESULT).//保存最终图片

                into(targetView);

    }

}

12.缓存设置

在GlideModule 中,我们可以设置磁盘缓存的位置,磁盘缓存的大小和内存缓存的大小,同时还可以设置图片的显示质量.

要是用GlideModule ,需要创建它的实现类,然后在manifests中申明实现类的全类路径:

1

2

3

<meta-data

          android:name="com.example.mchenys.httputilsdemo.image.glide.module.SimpleGlideModule"

          android:value="GlideModule" />

GlideModule 的实现类,需要实现applyOptions方法:

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

34

35

36

37

38

39

40

41

42

43

/**

 * 所以你知道要创建一个额外的类去定制 Glide。

 * 下一步是要全局的去声明这个类,让 Glide 知道它应该在哪里被加载和使用。

 * Glide 会扫描 AndroidManifest.xml 为 Glide module 的 meta 声明。

 * 因此,你必须在 AndroidManifest.xml 的 <application> 标签内去声明这个SimpleGlideModule。

 * Created by mChenys on 2016/6/10.

 */

public class SimpleGlideModule implements GlideModule {

    public static DiskCache cache;

 

    @Override

    public void applyOptions(Context context, GlideBuilder builder) {

        // 在 Android 中有两个主要的方法对图片进行解码:ARGB8888 和 RGB565。前者为每个像素使用了 4 个字节,

        // 后者仅为每个像素使用了 2 个字节。ARGB8888 的优势是图像质量更高以及能存储一个 alpha 通道。

        // Picasso 使用 ARGB8888,Glide 默认使用低质量的 RGB565。

        // 对于 Glide 使用者来说:你使用 Glide module 方法去改变解码规则。

        builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);

        //设置缓存目录

        File cacheDir = PathUtils.getDiskCacheDir(context, CacheConfig.IMG_DIR);

 

        cache = DiskLruCacheWrapper.get(cacheDir, DiskCache.Factory.DEFAULT_DISK_CACHE_SIZE);// 250 MB

        builder.setDiskCache(new DiskCache.Factory() {

            @Override

            public DiskCache build() {

                return cache;

            }

        });

        //设置memory和Bitmap池的大小

        MemorySizeCalculator calculator = new MemorySizeCalculator(context);

        int defaultMemoryCacheSize = calculator.getMemoryCacheSize();

        int defaultBitmapPoolSize = calculator.getBitmapPoolSize();

 

        int customMemoryCacheSize = (int) (1.2 * defaultMemoryCacheSize);

        int customBitmapPoolSize = (int) (1.2 * defaultBitmapPoolSize);

 

        builder.setMemoryCache(new LruResourceCache(customMemoryCacheSize));

        builder.setBitmapPool(new LruBitmapPool(customBitmapPoolSize));

    }

 

    @Override

    public void registerComponents(Context context, Glide glide) {

    }

}

13.设置图片请求的优先级

Glide 可以用 Priority 枚举来设置图片的加载优先级,这样我们就可以针对那些需要显示的图片设置高的优先级了.

Priority 有4种级别:

· Priority.LOW

· Priority.NORMAL

· Priority.HIGH

· Priority.IMMEDIATE

例如:

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

34

35

36

/**

    * 高优先级加载

    * @param url

    * @param imageView

    * @param listener

    */

   public static void loadImageWithHighPriority(Object url,ImageView imageView, final LoaderListener listener) {

       if (url == null) {

           if (listener != null) {

               listener.onError();

           }

       else {

           Glide.with(imageView.getContext()).

                   load(url).

                   asBitmap().

                   priority(Priority.HIGH).//高优先级

                   dontAnimate().

                   listener(new RequestListener<Object, Bitmap>() {

                       @Override

                       public boolean onException(Exception e, Object model, Target<Bitmap> target, boolean isFirstResource) {

                           if (null != listener) {

                               listener.onError();

                           }

                           return false;

                       }

 

                       @Override

                       public boolean onResourceReady(Bitmap resource, Object model, Target<Bitmap> target, boolean isFromMemoryCache, boolean isFirstResource) {

                           if (null != listener) {

                               listener.onSuccess();

                           }

                           return false;

                       }

                   }).into(imageView);

       }

   }

14.设置加载缩略图

通过设置缩略图,我们可以在显示目标图片之前先展示一个第分辨率或者其他图片,当全分辨率的目标图片在后台加载完成后,
Glide会自动切换显示全像素的目标图片.

设置缩略图有2种方式:
通过thumbnail(float)指定0.0f~1.0f的原始图像大小,例如全像素的大小是500*500,如果设置为thumbnail为0.1f,即目标图片的10%,显示的缩略图大小就是50*50;

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

public class TestGlideActivity extends Activity {

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_test);

        ImageView targetView = (ImageView) findViewById(R.id.iv_target);

 

        Glide.with(this).

                load(R.drawable.test).

                placeholder(R.drawable.bg_loading).//加载中显示的图片

                error(R.drawable.bg_error).//加载失败时显示的图片

                crossFade(1000).//淡入淡出,注意:如果设置了这个,则必须要去掉asBitmap

                override(8080).//设置最终显示的图片像素为80*80,注意:这个是像素,而不是控件的宽高

                centerCrop().//中心裁剪,缩放填充至整个ImageView

                skipMemoryCache(true).//跳过内存缓存

                diskCacheStrategy(DiskCacheStrategy.RESULT).//保存最终图片

                thumbnail(0.1f).//10%的原图大小

                into(targetView);

    }

}

通过thumbnail(DrawableRequestBuilder)方式来指定缩略图,该缩略图可以使用load的所有方式(网络,文件,uri,资源)加载.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

public class TestGlideActivity extends Activity {

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_test);

        ImageView targetView = (ImageView) findViewById(R.id.iv_target);

        //缩略图请求

        DrawableRequestBuilder<String> thumbnailRequest = Glide

                .with(this)

                .load("http://www.qq745.com/uploads/allimg/141106/1-141106153Q5.png");

 

        Glide.with(this).

                load(R.drawable.test).

//                placeholder(R.drawable.bg_loading).//加载中显示的图片

//                error(R.drawable.bg_error).//加载失败时显示的图片

//                crossFade(1000).//淡入淡出,注意:如果设置了这个,则必须要去掉asBitmap

                override(8080).//设置最终显示的图片像素为80*80,注意:这个是像素,而不是控件的宽高

                centerCrop().//中心裁剪,缩放填充至整个ImageView

                skipMemoryCache(true).//跳过内存缓存

                diskCacheStrategy(DiskCacheStrategy.RESULT).//保存最终图片

                thumbnail(thumbnailRequest).//设置缩略图

                into(targetView);

    }

}

15.Transformations Bitmap

在显示目标图片之前,我们可以对目标图片的Bitmap进行相应的处理,例如::圆角图片,圆形图片,高斯模糊,旋转,灰度等等.
只需要实现Transformation接口即可,该接口的transform方法会返回显示图片前的Bitmap对象,在该方法中对
Bitmap的任何处理,都会影响到最终的显示结果.
当然,如果你只是想要对图片做常规的 bitmap 转换,你可以继承抽象类BitmapTransformation,它简化了Transformation接口的实现,这应该能覆盖大部分的应用场景了。

使用的时候,通过transform(Transformation… transformations)来设置.例如:

1

2

3

4

5

6

7

8

9

10

11

12

13

public class TestGlideActivity extends Activity {

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_test);

        ImageView targetView = (ImageView) findViewById(R.id.iv_target);

        Glide.with(this).

                load(R.drawable.test).

                asBitmap().

                transform(new BlurTransformation(this)).//高斯模糊处理

                into(targetView);

    }

}

下面贴出常用的几个Bitmap的转换处理的代码,在github上也有glide-transformations-master库.

圆图处理

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

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

public class CropCircleTransformation implements Transformation<Bitmap> {

 

    private BitmapPool mBitmapPool;

 

    public CropCircleTransformation(Context context) {

        this(Glide.get(context).getBitmapPool());

    }

 

    public CropCircleTransformation(BitmapPool pool) {

        this.mBitmapPool = pool;

    }

 

    @Override

    public Resource<Bitmap> transform(Resource<Bitmap> resource, int outWidth, int outHeight) {

        Bitmap source = resource.get();

        int size = Math.min(source.getWidth(), source.getHeight());

 

        int width = (source.getWidth() - size) / 2;

        int height = (source.getHeight() - size) / 2;

 

        Bitmap bitmap = mBitmapPool.get(size, size, Bitmap.Config.ARGB_8888);

        if (bitmap == null) {

            bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);

        }

 

        Canvas canvas = new Canvas(bitmap);

        Paint paint = new Paint();

        BitmapShader shader =

                new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP);

        if (width != 0 || height != 0) {

            // source isn't square, move viewport to center

            Matrix matrix = new Matrix();

            matrix.setTranslate(-width, -height);

            shader.setLocalMatrix(matrix);

        }

        paint.setShader(shader);

        paint.setAntiAlias(true);

 

        float r = size / 2f;

        canvas.drawCircle(r, r, r, paint);

 

        return BitmapResource.obtain(bitmap, mBitmapPool);

    }

 

    @Override public String getId() {

        return "CropCircleTransformation()";

    }

}

圆角处理

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

34

35

36

37

38

39

40

41

42

43

public class RoundedCornersTransformation implements Transformation<Bitmap> {

 

    private BitmapPool mBitmapPool;

 

    private int radius;

    private int margin;

 

    public RoundedCornersTransformation(Context context, int radius, int margin) {

        this(Glide.get(context).getBitmapPool(), radius, margin);

    }

 

    public RoundedCornersTransformation(BitmapPool pool, int radius, int margin) {

        mBitmapPool = pool;

        this.radius = radius;

        this.margin = margin;

    }

 

    @Override

    public Resource<Bitmap> transform(Resource<Bitmap> resource, int outWidth, int outHeight) {

        Bitmap source = resource.get();

 

        int width = source.getWidth();

        int height = source.getHeight();

 

        Bitmap bitmap = mBitmapPool.get(width, height, Bitmap.Config.ARGB_8888);

        if (bitmap == null) {

            bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);

        }

 

        Canvas canvas = new Canvas(bitmap);

        Paint paint = new Paint();

        paint.setAntiAlias(true);

        paint.setShader(new BitmapShader(source, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));

        canvas.drawRoundRect(new RectF(margin, margin, width - margin, height - margin), radius, radius,

                paint);

 

        return BitmapResource.obtain(bitmap, mBitmapPool);

    }

 

    @Override public String getId() {

        return "RoundedTransformation(radius=" + radius + ", margin=" + margin + ")";

    }

}

灰度处理

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

34

35

36

37

38

39

40

public class GrayscaleTransformation implements Transformation<Bitmap> {

 

    private BitmapPool mBitmapPool;

 

    public GrayscaleTransformation(Context context) {

        this(Glide.get(context).getBitmapPool());

    }

 

    public GrayscaleTransformation(BitmapPool pool) {

        mBitmapPool = pool;

    }

 

    @Override

    public Resource<Bitmap> transform(Resource<Bitmap> resource, int outWidth, int outHeight) {

        Bitmap source = resource.get();

 

        int width = source.getWidth();

        int height = source.getHeight();

 

        Bitmap.Config config =

                source.getConfig() != null ? source.getConfig() : Bitmap.Config.ARGB_8888;

        Bitmap bitmap = mBitmapPool.get(width, height, config);

        if (bitmap == null) {

            bitmap = Bitmap.createBitmap(width, height, config);

        }

 

        Canvas canvas = new Canvas(bitmap);

        ColorMatrix saturation = new ColorMatrix();

        saturation.setSaturation(0f);

        Paint paint = new Paint();

        paint.setColorFilter(new ColorMatrixColorFilter(saturation));

        canvas.drawBitmap(source, 00, paint);

 

        return BitmapResource.obtain(bitmap, mBitmapPool);

    }

 

    @Override public String getId() {

        return "GrayscaleTransformation()";

    }

}

旋转处理

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

public class RotateTransformation extends BitmapTransformation {

 

    private float rotateRotationAngle = 0f;

 

    public RotateTransformation(Context context, float rotateRotationAngle) {

        super(context);

 

        this.rotateRotationAngle = rotateRotationAngle;

    }

 

    @Override

    protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {

        Matrix matrix = new Matrix();

 

        matrix.postRotate(rotateRotationAngle);

 

        return Bitmap.createBitmap(toTransform, 00, toTransform.getWidth(), toTransform.getHeight(), matrix, true);

    }

 

    @Override

    public String getId() {

        return "rotate" + rotateRotationAngle;

    }

}

高斯模糊处理

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

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

public class BlurTransformation implements Transformation<Bitmap> {

 

    private static int MAX_RADIUS = 25;

    private static int DEFAULT_DOWN_SAMPLING = 1;

 

    private Context mContext;

    private BitmapPool mBitmapPool;

 

    private int mRadius;

    private int mSampling;

 

    public BlurTransformation(Context context) {

        this(context, Glide.get(context).getBitmapPool(), MAX_RADIUS, DEFAULT_DOWN_SAMPLING);

    }

 

    public BlurTransformation(Context context, BitmapPool pool) {

        this(context, pool, MAX_RADIUS, DEFAULT_DOWN_SAMPLING);

    }

 

    public BlurTransformation(Context context, BitmapPool pool, int radius) {

        this(context, pool, radius, DEFAULT_DOWN_SAMPLING);

    }

 

    public BlurTransformation(Context context, int radius) {

        this(context, Glide.get(context).getBitmapPool(), radius, DEFAULT_DOWN_SAMPLING);

    }

 

    public BlurTransformation(Context context, BitmapPool pool, int radius, int sampling) {

        mContext = context;

        mBitmapPool = pool;

        mRadius = radius;

        mSampling = sampling;

    }

 

    public BlurTransformation(Context context, int radius, int sampling) {

        mContext = context;

        mBitmapPool = Glide.get(context).getBitmapPool();

        mRadius = radius;

        mSampling = sampling;

    }

 

    @Override

    public Resource<Bitmap> transform(Resource<Bitmap> resource, int outWidth, int outHeight) {

        Bitmap source = resource.get();

 

        int width = source.getWidth();

        int height = source.getHeight();

        int scaledWidth = width / mSampling;

        int scaledHeight = height / mSampling;

 

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

        if (bitmap == null) {

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

        }

 

        Canvas canvas = new Canvas(bitmap);

        canvas.scale(1 / (float) mSampling, 1 / (float) mSampling);

        Paint paint = new Paint();

        paint.setFlags(Paint.FILTER_BITMAP_FLAG);

        canvas.drawBitmap(source, 00, paint);

 

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {

            try {

                bitmap = RSBlur.blur(mContext, bitmap, mRadius);

            catch (RSRuntimeException e) {

                bitmap = FastBlur.blur(bitmap, mRadius, true);

            }

        else {

            bitmap = FastBlur.blur(bitmap, mRadius, true);

        }

 

        return BitmapResource.obtain(bitmap, mBitmapPool);

    }

 

    @Override public String getId() {

        return "BlurTransformation(radius=" + mRadius + ", sampling=" + mSampling + ")";

    }

}

网上提供的FastBlur,可兼容低版本的高斯模糊处理

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

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

public class FastBlur {

 

    public static Bitmap blur(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, 00, 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, 00, w, h);

 

        return (bitmap);

    }

}

RenderScript处理高斯模糊

android4.3之后可使用,需要在build.gradle中配置:

defaultConfig {

//BlurTransformation
renderscriptTargetApi 23
renderscriptSupportModeEnabled true
}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

public class RSBlur {

 

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)

    public static Bitmap blur(Context context, Bitmap blurredBitmap, int radius) throws RSRuntimeException {

        try {

            RenderScript rs = RenderScript.create(context);

            Allocation input = Allocation.createFromBitmap(rs, blurredBitmap, Allocation.MipmapControl.MIPMAP_NONE,

                    Allocation.USAGE_SCRIPT);

            Allocation output = Allocation.createTyped(rs, input.getType());

            ScriptIntrinsicBlur blur = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));

 

            blur.setInput(input);

            blur.setRadius(radius);

            blur.forEach(output);

            output.copyTo(blurredBitmap);

            rs.destroy();

        catch (RSRuntimeException e) {

            blurredBitmap = FastBlur.blur(blurredBitmap, radius, true);

        }

        return blurredBitmap;

    }

}

16.动画处理

通过animate()方法可以设置xml文件定义的4种补间动画(alpha、scale、translate、rotate)
例如:

res\anim\left_in.xml

1

2

3

4

5

6

7

8

9

10

11

<?xml version="1.0" encoding="utf-8"?>

<set xmlns:android="http://schemas.android.com/apk/res/android">

    <translate

        android:duration="@android:integer/config_mediumAnimTime"

        android:fromXDelta="-50%p"

        android:toXDelta="0"/>

    <alpha

        android:duration="@android:integer/config_mediumAnimTime"

        android:fromAlpha="0.0"

        android:toAlpha="1.0"/>

</set>

使用方式:

1

2

3

4

5

6

7

8

9

10

11

12

13

public class TestGlideActivity extends Activity {

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_test);

        ImageView targetView = (ImageView) findViewById(R.id.iv_target);

        Glide.with(this).

                load(R.drawable.test).

                asBitmap().

                animate(R.anim.left_in).//加载xml文件定义的动画

                into(targetView);

    }

}

处理此外,还可以通过animate指定属性动画:

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

public class TestGlideActivity extends Activity {

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_test);

        ImageView targetView = (ImageView) findViewById(R.id.iv_target);

 

        ViewPropertyAnimation.Animator animationObject = new ViewPropertyAnimation.Animator() {

            @Override

            public void animate(View view) {

                //设置属性动画

                ObjectAnimator moveIn = ObjectAnimator.ofFloat(view, "translationX", -500f, 0f);

                ObjectAnimator rotate = ObjectAnimator.ofFloat(view, "rotation", 0f, 360f);

                ObjectAnimator fadeInOut = ObjectAnimator.ofFloat(view, "alpha", 1f, 0f, 1f);

                ObjectAnimator moveTop = ObjectAnimator.ofFloat(view, "translationY", 0f, -2000, 0f);

                AnimatorSet animSet = new AnimatorSet();

                //先左进,然后旋转伴随淡入效果,最后移动向上

                animSet.play(rotate).with(fadeInOut).after(moveIn).before(moveTop);

                animSet.setDuration(5000);

                animSet.start();

            }

        };

        Glide.with(this).

                load(R.drawable.test).

                asBitmap().

                animate(animationObject).//加载属性动画

                into(targetView);

    }

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android图片框架Glide-3.7.0(最新,很强大),超好用的图片框架(包含jar和源码) Glide 是一个高效、开源、 Android设备上的媒体管理框架,它遵循BSD、MIT以及Apache 2.0协议发布。Glide具有获取、解码和展示视频剧照、图片、动画等功能,它还有灵活的API,这些API使开发者能够将Glide应用在几乎任何网络协议栈里。创建Glide的主要目的有两个,一个是实现平滑的图片列表滚动效果,另一个是支持远程图片的获取、大小调整和展示。近日,Glide 3.0发布,现已提供 jar包下载 ,同时还支持使用Gradle以及Maven进行构建。该版本包括很多值得关注的新功能,如支持Gif 动画和视频剧照解码、智能的暂停和重新开始请求、支持缩略图等,具体新增功能如下如下: GIF 动画的解码 :通过调用Glide.with(context).load(“图片路径“)方法,GIF动画图片可以自动显示为动画效果。如果想有更多的控制,还可以使用Glide.with(context).load(“图片路径“).asBitmap()方法加载静态图片使用Glide.with(context).load(“图片路径“).asGif()方法加载动画图片 本地视频剧照的解码: 通过调用Glide.with(context).load(“图片路径“)方法,Glide能够支持Android设备中的所有视频剧照的加载和展示 缩略图的支持: 为了减少在同一个view组件里同时加载多张图片的时间,可以调用Glide.with(context).load(“图片路径“).thumbnail(“缩略比例“).into(“view组件“)方法加载一个缩略图,还可以控制thumbnail()中的参数的大小,以控制显示不同比例大小的缩略图 Activity 生命周期的集成: 当Activity暂停和重启时,Glide能够做到智能的暂停和重新开始请求,并且当Android设备的连接状态变化时,所有失败的请求能够自动重新请求 转码的支持: Glide的toBytes() 和transcode() 两个方法可以用来获取、解码和变换背景图片,并且transcode() 方法还能够改变图片的样式 动画的支持: 新增支持图片的淡入淡出动画效果(调用crossFade()方法)和查看动画的属性的功能 OkHttp 和Volley 的支持: 默认选择HttpUrlConnection作为网络协议栈,还可以选择OkHttp和Volley作为网络协议栈 其他功能: 如在图片加载过程中,使用Drawables对象作为占位符、图片请求的优化、图片的宽度和高度可重新设定、缩略图和原图的缓存等功能
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值