Glide教程9-10

9. 图片预处理(圆角,高斯模糊等)

有时候项目中会有很多特殊的需求,比如说圆角处理,圆形图片,高斯模糊等,Glide提供了方法可以很好的进行处理

1.创建一个类继承BitmapTransformation

需要实现两个方法,其中transform方法里面能拿到bitmap对象,这里就是对图片做处理的地方

public  class CornersTransform extends BitmapTransformation {
        @Override
        protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
            //TODO
        }

        @Override
        public String getId() {
           //TODO
        }
}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

2.使用

通过调用transform方法就能展示处理后的图片

Glide.with(this).load(url).transform(new CornersTransform()).into(iv1);

 
 
  • 1

3.举例(圆角处理)

3.1 自定义Transformation
public  class CornersTransform extends BitmapTransformation {
    private float radius;

    public CornersTransform(Context context) {
        super(context);
        radius = 10;
    }
    public CornersTransform(Context context, float radius) {
        super(context);
        this.radius = radius;
    }
    @Override
    protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
        return cornersCrop(pool, toTransform);
    }
    private Bitmap cornersCrop(BitmapPool pool, Bitmap source) {
        if (source == null) return null;
        Bitmap result = pool.get(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
        if (result == null) {
            result = Bitmap.createBitmap(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);
        RectF rectF = new RectF(0f, 0f, source.getWidth(), source.getHeight());
        canvas.drawRoundRect(rectF, radius, radius, paint);
        return result;
    }
    @Override
    public String getId() {
        return getClass().getName();
    }
}

 
 
  • 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
3.2 使用
Glide.with(this).load(url).transform(new CornersTransform(this,50)).into(iv1);

 
 
  • 1

效果如下:

4.使用多个transform

transform方法是不支持多次调用的,如果你调用了两次,那么第二次的会覆盖了第一次的效果

但是他有一个重载的方法可以传入多个对象,这样传入的变形器都能够生效

Glide.with(this).load(url).transform(new CircleTransform(this),new CornersTransform(this,50)).into(iv1);

 
 
  • 1

5.三方库

如果你觉得自己自定义transform比较困难,或者你想学习别人的图片处理方法,可以在试一试github上的这个三方库

Glide Transformations

https://github.com/wasabeef/glide-transformations

效果(支持圆角,高斯模糊等)



10. 图片的剪裁(ScaleType)

1.基础知识

这里会涉及到Glide的变换处理transform,在之前的文章中已经讲过了,这里就不做介绍了,没有看过的朋友最好去了解一下,不然接下来的分析可能会理解不了

Glide-图片预处理(transform)
http://blog.csdn.net/yulyu/article/details/55261351

2.ImageView默认的ScaleType

讲到图片的剪裁,我们首先要介绍一下ImageView默认的ScaleType设置效果

ImageView的ScaleType一共有8种属性:

  • matrix
  • center
  • centerInside
  • centerCrop
  • fitCenter(默认)
  • fitStart
  • fitEnd
  • fitXY
有些文章说默认是matrix,是不正确的,其实默认是FIT_CENTER

可以通过ImageView的源码看到默认设置

private void initImageView() {
    mMatrix = new Matrix();
    mScaleType = ScaleType.FIT_CENTER;

    if (!sCompatDone) {
        final int targetSdkVersion = mContext.getApplicationInfo().targetSdkVersion;
        sCompatAdjustViewBounds = targetSdkVersion <= Build.VERSION_CODES.JELLY_BEAN_MR1;
        sCompatUseCorrectStreamDensity = targetSdkVersion > Build.VERSION_CODES.M;
        sCompatDrawableVisibilityDispatch = targetSdkVersion < Build.VERSION_CODES.N;
        sCompatDone = true;
    }
}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

2.1属性介绍
(1)matrix

不缩放 ,图片与控件 左上角 对齐,当图片大小超过控件时将被 裁剪

(2)center

不缩放 ,图片与控件 中心点 对齐,当图片大小超过控件时将被 裁剪

(3)centerInside

完整显示图片为目标, 不剪裁 ,当显示不下的时候将缩放,能够显示的情况下不缩放**

(4)centerCrop

填满整个控件为目标,等比缩放,超过控件时将被 裁剪 ( 宽高都要填满 ,所以只要图片宽高比与控件宽高比不同时,一定会被剪裁)

(5)fitCenter(默认)

自适应控件, 不剪裁 ,在不超过控件的前提下,等比 缩放最大 ,居中显示

(6)fitStart

自适应控件, 不剪裁 ,在不超过控件的前提下,等比 缩放最大 ,靠左(上)显示

(7)fitEnd

自适应控件, 不剪裁 ,在不超过控件的前提下,等比 缩放最大 ,靠右(下)显示

(8)fitXY

填满整个控件为目标, 不按比例 拉伸或缩放(可能会变形), 不剪裁


2.2效果图

当你不使用Glide,直接在ImageView的xml的src中设置图片效果如下

图片 336 * 448
控件 300 * 300

效果图

3.Glide配置

Glide有两个方法可以设置图片剪裁的策略

①fitCenter()

②centerCrop()

这两个方法其实都是通过调用transform方法来对图片进行处理


3.1默认策略

当你没有调用上述两个方法,并且也没有调用transform方法的时候,在Glide调用into方法时,会根据你设置的ScaleType来做处理

    if (!isTransformationSet && view.getScaleType() != null) {
        switch (view.getScaleType()) {
            case CENTER_CROP:
                applyCenterCrop();
                break;
            case FIT_CENTER:
            case FIT_START:
            case FIT_END:
                applyFitCenter();
                break;
            //$CASES-OMITTED$
            default:
                // Do nothing.
        }
    }

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

applyCenterCrop其实还是调用的centerCrop

applyFitCenter其实还是调用的applyFitCenter

通过默认的配置加载图片

Glide.with(this).load(url).into(iv1);

 
 
  • 1

效果如下(跟ImageView设置src一样)


3.2 fitCenter

内部是调用transform方法来处理的,处理代码这边只是展示一下,就不做详细的介绍了,有兴趣的朋友可以研究

public static Bitmap fitCenter(Bitmap toFit, BitmapPool pool, int width, int height) {
        if (toFit.getWidth() == width && toFit.getHeight() == height) {
            if (Log.isLoggable(TAG, Log.VERBOSE)) {
                Log.v(TAG, "requested target size matches input, returning input");
            }
            return toFit;
        }
        final float widthPercentage = width / (float) toFit.getWidth();
        final float heightPercentage = height / (float) toFit.getHeight();
        final float minPercentage = Math.min(widthPercentage, heightPercentage);

        // take the floor of the target width/height, not round. If the matrix
        // passed into drawBitmap rounds differently, we want to slightly
        // overdraw, not underdraw, to avoid artifacts from bitmap reuse.
        final int targetWidth = (int) (minPercentage * toFit.getWidth());
        final int targetHeight = (int) (minPercentage * toFit.getHeight());

        if (toFit.getWidth() == targetWidth && toFit.getHeight() == targetHeight) {
            if (Log.isLoggable(TAG, Log.VERBOSE)) {
                Log.v(TAG, "adjusted target size matches input, returning input");
            }
            return toFit;
        }

        Bitmap.Config config = getSafeConfig(toFit);
        Bitmap toReuse = pool.get(targetWidth, targetHeight, config);
        if (toReuse == null) {
            toReuse = Bitmap.createBitmap(targetWidth, targetHeight, config);
        }
        // We don't add or remove alpha, so keep the alpha setting of the Bitmap we were given.
        TransformationUtils.setAlpha(toFit, toReuse);

        if (Log.isLoggable(TAG, Log.VERBOSE)) {
            Log.v(TAG, "request: " + width + "x" + height);
            Log.v(TAG, "toFit:   " + toFit.getWidth() + "x" + toFit.getHeight());
            Log.v(TAG, "toReuse: " + toReuse.getWidth() + "x" + toReuse.getHeight());
            Log.v(TAG, "minPct:   " + minPercentage);
        }

        Canvas canvas = new Canvas(toReuse);
        Matrix matrix = new Matrix();
        matrix.setScale(minPercentage, minPercentage);
        Paint paint = new Paint(PAINT_FLAGS);
        canvas.drawBitmap(toFit, matrix, paint);

        return toReuse;
    }

 
 
  • 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

效果图:

Glide.with(this).load(url).fitCenter().into(iv1);

 
 
  • 1


3.3 centerCrop

跟fitCenter的原理一样,只是具体处理逻辑不一样

public static Bitmap centerCrop(Bitmap recycled, Bitmap toCrop, int width, int height) {
    if (toCrop == null) {
        return null;
    } else if (toCrop.getWidth() == width && toCrop.getHeight() == height) {
        return toCrop;
    }
    // From ImageView/Bitmap.createScaledBitmap.
    final float scale;
    float dx = 0, dy = 0;
    Matrix m = new Matrix();
    if (toCrop.getWidth() * height > width * toCrop.getHeight()) {
        scale = (float) height / (float) toCrop.getHeight();
        dx = (width - toCrop.getWidth() * scale) * 0.5f;
    } else {
        scale = (float) width / (float) toCrop.getWidth();
        dy = (height - toCrop.getHeight() * scale) * 0.5f;
    }

    m.setScale(scale, scale);
    m.postTranslate((int) (dx + 0.5f), (int) (dy + 0.5f));
    final Bitmap result;
    if (recycled != null) {
        result = recycled;
    } else {
        result = Bitmap.createBitmap(width, height, getSafeConfig(toCrop));
    }

    // We don't add or remove alpha, so keep the alpha setting of the Bitmap we were given.
    TransformationUtils.setAlpha(toCrop, result);

    Canvas canvas = new Canvas(result);
    Paint paint = new Paint(PAINT_FLAGS);
    canvas.drawBitmap(toCrop, m, paint);
    return result;
}

 
 
  • 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

效果图(所有的都是与centerCrop效果一样):

Glide.with(this).load(url).centerCrop().into(iv2);

 
 
  • 1

4.统一展示(方便对比)





5.其他

有一点要注意的就是fitCenter和centerCrop方法与transform方法可以共存,但是有时候会互相影响,如果说圆角处理遇到了剪裁,圆角那一部分可能会刚好被剪裁掉了


这一章节涉及到的主要是取图方面的知识,如果是对取图方面要求不高的项目,那么用原生的scaletpye或者是Glide提供的两个方法即可,但是如果是取图规则特别复杂的项目(比如我现在的项目(┬_┬)),那么就需要通过自定义transform了,具体可以参考Glide的两个transform的处理,也可以用github上不错的三方库

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值