zoukankan      html  css  js  c++  java
  • 58.圆角图片


    绘制流程:
    1.根据获取的属性值,判断显示模式,并设置圆形图片、外边框、内边框的半径值
    2.画边框
    3.画图片内容
    (1)获取原图
    (2)得到正方形图
    (3)得到缩放图
    (4)得到圆形图

    public class MyRoundImageView extends ImageView {

    private int defaultColor = 0xffffffff;
    private ShowType mShowType = ShowType.NoBorder;
    private int mBorderThickness = 0;
    private int mBorderInsideColor;
    private int mBorderOutsideColor;
    private int mRadius = 0;

    enum ShowType {
    InsideBorder,
    OutsideBorder,
    InsideAndOutsideBorder,
    NoBorder
    }

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

    public MyRoundImageView(Context context, AttributeSet attrs) {
    super(context, attrs);
    readAttrs(attrs);
    }

    public MyRoundImageView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    readAttrs(attrs);
    }

    private void readAttrs(AttributeSet attrs) {
    TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.RoundImageView);
    mBorderThickness = a.getDimensionPixelSize(R.styleable.RoundImageView_border_thickness, 0);
    mBorderInsideColor = a.getColor(R.styleable.RoundImageView_border_inside_color, defaultColor);
    mBorderOutsideColor = a.getColor(R.styleable.RoundImageView_border_outside_color, defaultColor);
    readShowType();
    }

    private void readShowType() {
    if (mBorderInsideColor != defaultColor && mBorderOutsideColor != defaultColor) {
    mShowType = ShowType.InsideAndOutsideBorder;
    } else if (mBorderInsideColor != defaultColor && mBorderOutsideColor == defaultColor) {
    mShowType = ShowType.InsideBorder;
    } else if (mBorderInsideColor == defaultColor && mBorderOutsideColor != defaultColor) {
    mShowType = ShowType.OutsideBorder;
    } else {
    mShowType = ShowType.NoBorder;
    }
    }

    @Override
    protected void onDraw(Canvas canvas) {
    switch (mShowType) {
    case InsideBorder:
    mRadius = (getWidth() < getHeight() ? getWidth() : getHeight()) / 2 - mBorderThickness;
    drawRoundBorder(canvas, mRadius + mBorderThickness / 2, mBorderInsideColor);
    break;
    case OutsideBorder:
    mRadius = (getWidth() < getHeight() ? getWidth() : getHeight()) / 2 - mBorderThickness;
    drawRoundBorder(canvas, mRadius + mBorderThickness / 2, mBorderOutsideColor);
    break;
    case InsideAndOutsideBorder:
    mRadius = (getWidth() < getHeight() ? getWidth() : getHeight()) / 2 - mBorderThickness * 2;
    drawRoundBorder(canvas, mRadius + mBorderThickness / 2, mBorderInsideColor);
    drawRoundBorder(canvas, mRadius + mBorderThickness / 2 + mBorderThickness, mBorderOutsideColor);
    break;
    case NoBorder:
    mRadius = (getWidth() < getHeight() ? getWidth() : getHeight()) / 2;
    break;
    default:
    }
    drawBitmapContent(canvas);
    }

    private void drawRoundBorder(Canvas canvas, int radius, int color) {
    Paint paint = new Paint();
    paint.setAntiAlias(true);
    paint.setFilterBitmap(true);
    paint.setDither(true);
    paint.setColor(color);
    paint.setStyle(Paint.Style.STROKE);
    paint.setStrokeWidth(mBorderThickness);
    canvas.drawCircle(getWidth() / 2, getHeight() / 2, radius, paint);
    }

    private void drawBitmapContent(Canvas canvas) {
    canvas.drawBitmap(bitmapToRound(bitmapToScale(bitmapToSquare(readBitmap()))), getWidth() / 2 - mRadius, getHeight() / 2 - mRadius, null);
    }

    private Bitmap readBitmap() {
    Drawable drawable = getDrawable();
    if (drawable == null) {
    return null;
    }
    if (drawable instanceof NinePatchDrawable) {
    return null;
    }
    if (drawable instanceof BitmapDrawable) {
    return ((BitmapDrawable) drawable).getBitmap().copy(Bitmap.Config.ARGB_8888, true);
    }
    return null;
    }

    private Bitmap bitmapToSquare(Bitmap bitmap) {
    int w = bitmap.getWidth();
    int h = bitmap.getHeight();
    int x = w > h ? (w - h) / 2 : 0;
    int y = w > h ? 0 : (h - w) / 2;
    int sideLength = w > h ? h : w;
    return Bitmap.createBitmap(bitmap, 0, 0, sideLength, sideLength);
    }

    private Bitmap bitmapToScale(Bitmap bitmap) {
    return Bitmap.createScaledBitmap(bitmap, mRadius * 2,
    mRadius * 2, true);
    }

    public Bitmap bitmapToRound(Bitmap bitmap) {
    Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
    bitmap.getHeight(), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(output);
    Paint paint = new Paint();
    Rect rect = new Rect(0, 0, output.getWidth(),output.getHeight());
    paint.setAntiAlias(true);
    canvas.drawRoundRect(new RectF(rect), rect.width()/2, rect.height()/2, paint);
    //output的图层与bitmap的图层的交集
    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
    //参数2是截取原图区域,可以不是全部图片,参数3是显示位置区域
    canvas.drawBitmap(bitmap, rect, rect, paint);
    return output;
    }

    }

    附1.设置两张图片相交时的模式
    /**
    * setXfermode 设置两张图片相交时的模式
    */
    // PorterDuff.Mode.CLEAR 清除画布上图像
    // PorterDuff.Mode.SRC 显示上层图像
    // PorterDuff.Mode.DST 显示下层图像
    // PorterDuff.Mode.SRC_OVER上下层图像都显示,上层居上显示
    // PorterDuff.Mode.DST_OVER 上下层都显示,下层居上显示
    // PorterDuff.Mode.SRC_IN 取两层图像交集部门,只显示上层图像
    // PorterDuff.Mode.DST_IN 取两层图像交集部门,只显示下层图像
    // PorterDuff.Mode.SRC_OUT 取上层图像非交集部门
    // PorterDuff.Mode.DST_OUT 取下层图像非交集部门
    // PorterDuff.Mode.SRC_ATOP 取下层图像非交集部门与上层图像交集部门
    // PorterDuff.Mode.DST_ATOP 取上层图像非交集部门与下层图像交集部门
    // PorterDuff.Mode.XOR 取两层图像的非交集部门

    参考资料:



  • 相关阅读:
    记一次对网站的SEO优化改造
    pc端页面添加响应式布局
    linux开启coredump
    vue中鼠标事件
    垂直居中的几种方法
    最准确的身份证号码正则验证
    将数组[NaN ,1,21,32,NaN,41,5]里面的NaN成员剔除(复用underscore.js的filter方法)
    项目中使用Mockjs模拟数据
    研究生学习与生活(2019)
    研究生学习与生活(九)
  • 原文地址:https://www.cnblogs.com/yutianran/p/5069650.html
Copyright © 2011-2022 走看看