文章目录

  • 前言
  • 基于glide-transformations项目中的圆角矩形方案修改
  • 方案2
  • 其它问题
  • 参考


前言

Glide中的 Transformation,多次设置,后面的会覆盖前面的。
如果 ImageView的 scaleType = “centerCrop”,会在 into()方法前自动加上 centerCrop(),即会调用 CenterCrop#transform()

public class CenterCrop extends BitmapTransformation {  private static final String ID = "com.bumptech.glide.load.resource.bitmap.CenterCrop";  private static final byte[] ID_BYTES = ID.getBytes(CHARSET);  @Override  protected Bitmap transform(      @NonNull BitmapPool pool, @NonNull Bitmap toTransform, int outWidth, int outHeight) {    return TransformationUtils.centerCrop(pool, toTransform, outWidth, outHeight);  }  @Override  public boolean equals(Object o) {    return o instanceof CenterCrop;  }  @Override  public int hashCode() {    return ID.hashCode();  }  @Override  public void updateDiskCacheKey(@NonNull MessageDigest messageDigest) {    messageDigest.update(ID_BYTES);  }}

要同时有centerCrop效果与圆角效果,就基于这个类修改就行,即基于 TransformationUtils.centerCrop(pool, toTransform, outWidth, outHeight); 这段代码返回的Bitmap对象作处理。


基于glide-transformations项目中的圆角矩形方案修改

支持dp单位,float精度

/** * Copyright (C) 2018 Wasabeef * 

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *

* http://www.apache.org/licenses/LICENSE-2.0 *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */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.graphics.PaintFlagsDrawFilter;import android.graphics.RectF;import android.graphics.Shader;import android.support.annotation.NonNull;import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;import com.bumptech.glide.load.resource.bitmap.TransformationUtils;import java.security.MessageDigest;import jp.wasabeef.glide.transformations.BitmapTransformation;/** * desc : * author : stone * email : aa86799@163.com * time : 2019/6/12 ‏‎9:42 */public class RoundedCornersTransformation2 extends BitmapTransformation { private static final int VERSION = 1; private static final String ID = "jp.wasabeef.glide.transformations.RoundedCornersTransformation." + VERSION; public enum CornerType { ALL, TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT, TOP, BOTTOM, LEFT, RIGHT, OTHER_TOP_LEFT, OTHER_TOP_RIGHT, OTHER_BOTTOM_LEFT, OTHER_BOTTOM_RIGHT, DIAGONAL_FROM_TOP_LEFT, DIAGONAL_FROM_TOP_RIGHT } public enum ScaleType { FIT_CENTER, CENTER_CROP, CENTER_INSIDE } private float radius; private float diameter; private float margin; private CornerType cornerType; private ScaleType scaleType; public RoundedCornersTransformation2(int dpRadius, int marginDp) { this(dpRadius, marginDp, CornerType.ALL, ScaleType.FIT_CENTER); } public RoundedCornersTransformation2(int dpRadius, int marginDp, CornerType cornerType, ScaleType scaleType) { this.radius = Resources.getSystem().getDisplayMetrics().density * dpRadius; this.diameter = this.radius * 2; this.margin = Resources.getSystem().getDisplayMetrics().density * marginDp; this.cornerType = cornerType; this.scaleType = scaleType; } @Override protected Bitmap transform(@NonNull Context context, @NonNull BitmapPool pool, @NonNull Bitmap toTransform, int outWidth, int outHeight) { Bitmap bitmap; switch (scaleType) { case CENTER_CROP: bitmap = TransformationUtils.centerCrop(pool, toTransform, outWidth, outHeight); break; case CENTER_INSIDE: bitmap = TransformationUtils.centerInside(pool, toTransform, outWidth, outHeight); break; case FIT_CENTER: default: bitmap = TransformationUtils.fitCenter(pool, toTransform, outWidth, outHeight); break; } return roundCrop(pool, bitmap); } private Bitmap roundCrop(BitmapPool pool, Bitmap source) { if (source == null) return null; Bitmap result = pool.get(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888); result.setHasAlpha(true); Canvas canvas = new Canvas(result); canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG)); Paint paint = new Paint(); paint.setAntiAlias(true); paint.setShader(new BitmapShader(source, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP)); drawRoundRect(canvas, paint, source.getWidth(), source.getHeight()); return result; } private void drawRoundRect(Canvas canvas, Paint paint, float width, float height) { float right = width - margin; float bottom = height - margin; switch (cornerType) { case ALL: canvas.drawRoundRect(new RectF(margin, margin, right, bottom), radius, radius, paint); break; case TOP_LEFT: drawTopLeftRoundRect(canvas, paint, right, bottom); break; case TOP_RIGHT: drawTopRightRoundRect(canvas, paint, right, bottom); break; case BOTTOM_LEFT: drawBottomLeftRoundRect(canvas, paint, right, bottom); break; case BOTTOM_RIGHT: drawBottomRightRoundRect(canvas, paint, right, bottom); break; case TOP: drawTopRoundRect(canvas, paint, right, bottom); break; case BOTTOM: drawBottomRoundRect(canvas, paint, right, bottom); break; case LEFT: drawLeftRoundRect(canvas, paint, right, bottom); break; case RIGHT: drawRightRoundRect(canvas, paint, right, bottom); break; case OTHER_TOP_LEFT: drawOtherTopLeftRoundRect(canvas, paint, right, bottom); break; case OTHER_TOP_RIGHT: drawOtherTopRightRoundRect(canvas, paint, right, bottom); break; case OTHER_BOTTOM_LEFT: drawOtherBottomLeftRoundRect(canvas, paint, right, bottom); break; case OTHER_BOTTOM_RIGHT: drawOtherBottomRightRoundRect(canvas, paint, right, bottom); break; case DIAGONAL_FROM_TOP_LEFT: drawDiagonalFromTopLeftRoundRect(canvas, paint, right, bottom); break; case DIAGONAL_FROM_TOP_RIGHT: drawDiagonalFromTopRightRoundRect(canvas, paint, right, bottom); break; default: canvas.drawRoundRect(new RectF(margin, margin, right, bottom), radius, radius, paint); break; } } private void drawTopLeftRoundRect(Canvas canvas, Paint paint, float right, float bottom) { canvas.drawRoundRect(new RectF(margin, margin, margin + diameter, margin + diameter), radius, radius, paint); canvas.drawRect(new RectF(margin, margin + radius, margin + radius, bottom), paint); canvas.drawRect(new RectF(margin + radius, margin, right, bottom), paint); } private void drawTopRightRoundRect(Canvas canvas, Paint paint, float right, float bottom) { canvas.drawRoundRect(new RectF(right - diameter, margin, right, margin + diameter), radius, radius, paint); canvas.drawRect(new RectF(margin, margin, right - radius, bottom), paint); canvas.drawRect(new RectF(right - radius, margin + radius, right, bottom), paint); } private void drawBottomLeftRoundRect(Canvas canvas, Paint paint, float right, float bottom) { canvas.drawRoundRect(new RectF(margin, bottom - diameter, margin + diameter, bottom), radius, radius, paint); canvas.drawRect(new RectF(margin, margin, margin + diameter, bottom - radius), paint); canvas.drawRect(new RectF(margin + radius, margin, right, bottom), paint); } private void drawBottomRightRoundRect(Canvas canvas, Paint paint, float right, float bottom) { canvas.drawRoundRect(new RectF(right - diameter, bottom - diameter, right, bottom), radius, radius, paint); canvas.drawRect(new RectF(margin, margin, right - radius, bottom), paint); canvas.drawRect(new RectF(right - radius, margin, right, bottom - radius), paint); } private void drawTopRoundRect(Canvas canvas, Paint paint, float right, float bottom) { canvas.drawRoundRect(new RectF(margin, margin, right, margin + diameter), radius, radius, paint); canvas.drawRect(new RectF(margin, margin + radius, right, bottom), paint); } private void drawBottomRoundRect(Canvas canvas, Paint paint, float right, float bottom) { canvas.drawRoundRect(new RectF(margin, bottom - diameter, right, bottom), radius, radius, paint); canvas.drawRect(new RectF(margin, margin, right, bottom - radius), paint); } private void drawLeftRoundRect(Canvas canvas, Paint paint, float right, float bottom) { canvas.drawRoundRect(new RectF(margin, margin, margin + diameter, bottom), radius, radius, paint); canvas.drawRect(new RectF(margin + radius, margin, right, bottom), paint); } private void drawRightRoundRect(Canvas canvas, Paint paint, float right, float bottom) { canvas.drawRoundRect(new RectF(right - diameter, margin, right, bottom), radius, radius, paint); canvas.drawRect(new RectF(margin, margin, right - radius, bottom), paint); } private void drawOtherTopLeftRoundRect(Canvas canvas, Paint paint, float right, float bottom) { canvas.drawRoundRect(new RectF(margin, bottom - diameter, right, bottom), radius, radius, paint); canvas.drawRoundRect(new RectF(right - diameter, margin, right, bottom), radius, radius, paint); canvas.drawRect(new RectF(margin, margin, right - radius, bottom - radius), paint); } private void drawOtherTopRightRoundRect(Canvas canvas, Paint paint, float right, float bottom) { canvas.drawRoundRect(new RectF(margin, margin, margin + diameter, bottom), radius, radius, paint); canvas.drawRoundRect(new RectF(margin, bottom - diameter, right, bottom), radius, radius, paint); canvas.drawRect(new RectF(margin + radius, margin, right, bottom - radius), paint); } private void drawOtherBottomLeftRoundRect(Canvas canvas, Paint paint, float right, float bottom) { canvas.drawRoundRect(new RectF(margin, margin, right, margin + diameter), radius, radius, paint); canvas.drawRoundRect(new RectF(right - diameter, margin, right, bottom), radius, radius, paint); canvas.drawRect(new RectF(margin, margin + radius, right - radius, bottom), paint); } private void drawOtherBottomRightRoundRect(Canvas canvas, Paint paint, float right, float bottom) { canvas.drawRoundRect(new RectF(margin, margin, right, margin + diameter), radius, radius, paint); canvas.drawRoundRect(new RectF(margin, margin, margin + diameter, bottom), radius, radius, paint); canvas.drawRect(new RectF(margin + radius, margin + radius, right, bottom), paint); } private void drawDiagonalFromTopLeftRoundRect(Canvas canvas, Paint paint, float right, float bottom) { canvas.drawRoundRect(new RectF(margin, margin, margin + diameter, margin + diameter), radius, radius, paint); canvas.drawRoundRect(new RectF(right - diameter, bottom - diameter, right, bottom), radius, radius, paint); canvas.drawRect(new RectF(margin, margin + radius, right - diameter, bottom), paint); canvas.drawRect(new RectF(margin + diameter, margin, right, bottom - radius), paint); } private void drawDiagonalFromTopRightRoundRect(Canvas canvas, Paint paint, float right, float bottom) { canvas.drawRoundRect(new RectF(right - diameter, margin, right, margin + diameter), radius, radius, paint); canvas.drawRoundRect(new RectF(margin, bottom - diameter, margin + diameter, bottom), radius, radius, paint); canvas.drawRect(new RectF(margin, margin, right - radius, bottom - radius), paint); canvas.drawRect(new RectF(margin + radius, margin + radius, right, bottom), paint); } @NonNull @Override public String toString() { return "RoundedTransformation(radius=" + radius + ", margin=" + margin + ", diameter=" + diameter + ", cornerType=" + cornerType.name() + ")"; } @Override public boolean equals(Object o) { return o instanceof RoundedCornersTransformation2 && ((RoundedCornersTransformation2) o).radius == radius && ((RoundedCornersTransformation2) o).diameter == diameter && ((RoundedCornersTransformation2) o).margin == margin && ((RoundedCornersTransformation2) o).cornerType == cornerType; } @Override public int hashCode() { return (int) (ID.hashCode() + radius * 10000 + diameter * 1000 + margin * 100 + cornerType.ordinal() * 10); } @Override public void updateDiskCacheKey(@NonNull MessageDigest messageDigest) { messageDigest.update((ID + radius + diameter + margin + cornerType).getBytes(CHARSET)); }}

调用方式

Glide.with(...)....transform(new RoundedCornersTransformation2(dpRadius, margin, cornerType, scaleType)).into(...);

这里继承的是 glide-transformations项目中的 BitmapTransformation,而不是glide中的。继承glide中的也是可以的。


方案2

上面绘制圆角时,分了很多type,不同type分别绘制。代码量很长。
参考了一个文章,改成如下:

public class RoundedCornersTransformation extends BitmapTransformation {    private static final int VERSION = 1;    //这个ID值 随意    private static final String ID = "jp.wasabeef.glide.transformations.RoundedCornersTransformation." + VERSION;    public static final int CORNER_NONE = 0;    public static final int CORNER_TOP_LEFT = 1;    public static final int CORNER_TOP_RIGHT = 1 << 1;    public static final int CORNER_BOTTOM_LEFT = 1 << 2;    public static final int CORNER_BOTTOM_RIGHT = 1 << 3;    public static final int CORNER_ALL = CORNER_TOP_LEFT | CORNER_TOP_RIGHT | CORNER_BOTTOM_LEFT | CORNER_BOTTOM_RIGHT;    public static final int CORNER_TOP = CORNER_TOP_LEFT | CORNER_TOP_RIGHT;    public static final int CORNER_BOTTOM = CORNER_BOTTOM_LEFT | CORNER_BOTTOM_RIGHT;    public static final int CORNER_LEFT = CORNER_TOP_LEFT | CORNER_BOTTOM_LEFT;    public static final int CORNER_RIGHT = CORNER_TOP_RIGHT | CORNER_BOTTOM_RIGHT;    public static final int FIT_CENTER = 1;    public static final int CENTER_CROP = 2;    public static final int CENTER_INSIDE = 3;    @IntDef({FIT_CENTER, CENTER_CROP, CENTER_INSIDE})    public @interface ScaleType {}    private float radius;    private float diameter;    private float margin;    private int cornerType;    private @ScaleType int scaleType;    public RoundedCornersTransformation(int dpRadius, int marginDp) {        this(dpRadius, marginDp, CORNER_ALL, FIT_CENTER);    }    public RoundedCornersTransformation(int dpRadius, int marginDp, int cornerType, @ScaleType int scaleType) {        this.radius = Resources.getSystem().getDisplayMetrics().density * dpRadius;        this.diameter = this.radius * 2;        this.margin = Resources.getSystem().getDisplayMetrics().density * marginDp;        this.cornerType = cornerType;        this.scaleType = scaleType;    }        @Override    protected Bitmap transform(@NonNull BitmapPool pool, @NonNull Bitmap toTransform, int outWidth, int outHeight) {        Bitmap bitmap;        switch (scaleType) {            case CENTER_CROP:                bitmap = TransformationUtils.centerCrop(pool, toTransform, outWidth, outHeight);                break;            case CENTER_INSIDE:                bitmap = TransformationUtils.centerInside(pool, toTransform, outWidth, outHeight);                break;            case FIT_CENTER:            default:                bitmap = TransformationUtils.fitCenter(pool, toTransform, outWidth, outHeight);                break;        }        return roundCrop(pool, bitmap);    }    private Bitmap roundCrop(BitmapPool pool, Bitmap source) {        if (source == null) return null;        Bitmap result = pool.get(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);        result.setHasAlpha(true);        Canvas canvas = new Canvas(result);        canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG));        Paint paint = new Paint();        paint.setAntiAlias(true);        paint.setShader(new BitmapShader(source, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));        drawRoundRect(canvas, paint, source.getWidth(), source.getHeight());        return result;    }    private void drawRoundRect(Canvas canvas, Paint paint, float width, float height) {        float right = width - margin;        float bottom = height - margin;        canvas.drawRoundRect(new RectF(margin, margin, right, bottom), radius, radius, paint);        //把不需要的圆角去掉        int notRoundedCorners = cornerType ^ CORNER_ALL;        if ((notRoundedCorners & CORNER_TOP_LEFT) != 0) {            clipTopLeft(canvas, paint, radius);        }        if ((notRoundedCorners & CORNER_TOP_RIGHT) != 0) {            clipTopRight(canvas, paint, radius, right);        }        if ((notRoundedCorners & CORNER_BOTTOM_LEFT) != 0) {            clipBottomLeft(canvas, paint, radius, bottom);        }        if ((notRoundedCorners & CORNER_BOTTOM_RIGHT) != 0) {            clipBottomRight(canvas, paint, radius, right, bottom);        }    }    private static void clipTopLeft(final Canvas canvas, final Paint paint, float offset) {        final RectF block = new RectF(0, 0, offset, offset);        canvas.drawRect(block, paint);    }    private static void clipTopRight(final Canvas canvas, final Paint paint, float offset, float width) {        final RectF block = new RectF(width - offset, 0, width, offset);        canvas.drawRect(block, paint);    }    private static void clipBottomLeft(final Canvas canvas, final Paint paint, float offset, float height) {        final RectF block = new RectF(0, height - offset, offset, height);        canvas.drawRect(block, paint);    }    private static void clipBottomRight(final Canvas canvas, final Paint paint, float offset, float width, float height) {        final RectF block = new RectF(width - offset, height - offset, width, height);        canvas.drawRect(block, paint);    }    @NonNull    @Override    public String toString() {        return "RoundedTransformation(radius=" + radius + ", margin=" + margin + ", diameter="                + diameter + ", cornerType=" + cornerType + ")";    }    @Override    public boolean equals(Object o) {        return o instanceof RoundedCornersTransformation &&                ((RoundedCornersTransformation) o).radius == radius &&                ((RoundedCornersTransformation) o).diameter == diameter &&                ((RoundedCornersTransformation) o).margin == margin &&                ((RoundedCornersTransformation) o).cornerType == cornerType;    }    @Override    public int hashCode() {        return (int) (ID.hashCode() + radius * 10000 + diameter * 1000 + margin * 100 + cornerType * 10);    }    @Override    public void updateDiskCacheKey(@NonNull MessageDigest messageDigest) {        messageDigest.update((ID + radius + diameter + margin + cornerType).getBytes(CHARSET));    }}

先绘一个全圆角,再根据条件绘制 某几的个角小矩形,以覆盖圆角效果


其它问题

由于transform变换操作,会影响glide的图片缓存。glide文档中是要求重写 equals、hashCode、updateDiskCacheKey这三个方法的。
在调试时,若对同一图片,一会设置左圆角,一会设置右圆角,类似这样,可能就会造成后设置的看不到效果,看到还是之前的设置的效果。这是由于 glide缓存造成的。这时重装项目就可以了。


参考

android中对Bitmap图片设置任意角为圆角
glide-transformations


更多相关文章

  1. Android实现书籍翻页效果--扩展版(转)
  2. Android实时监控项目第一篇:项目分析及AVD模拟效果图
  3. Android UI开发第九篇――SlidingDrawer 抽屉效果
  4. Android UI开发第九篇——SlidingDrawer 抽屉效果
  5. Android处理屏幕旋转时的解决方案
  6. Android实现上下滑动效果
  7. android TextView 阴影效果,和使用style学习

随机推荐

  1. 仿写Android屏幕解锁小应用
  2. Android位置策略(五)
  3. Android中 dip 和 px 的关系
  4. 面试时的那些坑之内存泄漏和内存溢出
  5. Android数据本地安全存储
  6. Android关于第三方h5在webview调用摄像头
  7. Android简单、高性能的高斯模糊(毛玻璃)效
  8. Android实现竖着的滑动刻度尺效果,选择身
  9. 一个3000万日活跃用户App的真实数据
  10. ubuntu 10.10 64Bit下编译android和andro