上传头像时圆形裁剪框

上传头像到服务端时需要将图片裁剪,项目中用到的是圆形的裁剪框,先看效果:



代码实现如下:

public class ClipImageBorderView extends View
{
   /**
    * 水平方向与View的边距
    */
   private int mHorizontalPadding;
   /**
    * 垂直方向与View的边距
    */
   private int mVerticalPadding;
   /**
    * 绘制的矩形的宽度
    */
   private int mWidth;
   /**
    * 边框的颜色,默认为白色
    */
   private int mBorderColor = Color.parseColor("#FFFFFF");
   /**
    * 边框的宽度 单位dp
    */
   private int mBorderWidth = 1;

   private Paint mPaint;

   public ClipImageBorderView(Context context)
   {
      this(context, null);
   }

   public ClipImageBorderView(Context context, AttributeSet attrs)
   {
      this(context, attrs, 0);
   }

   public ClipImageBorderView(Context context, AttributeSet attrs, int defStyle)
   {
      super(context, attrs, defStyle);
   
      mBorderWidth = (int) TypedValue.applyDimension(
            TypedValue.COMPLEX_UNIT_DIP, mBorderWidth, getResources()
                  .getDisplayMetrics());
      mPaint = new Paint();
      mPaint.setAntiAlias(true);
   }

   @Override
   protected void onDraw(Canvas canvas)
   {
      super.onDraw(canvas);
      // 计算矩形区域的宽度
      mWidth = getWidth() - 2 * mHorizontalPadding;
      // 计算距离屏幕垂直边界 的边距
      mVerticalPadding = (getHeight() - mWidth) / 2;
      mPaint.setColor(Color.parseColor("#aa000000"));
      mPaint.setStyle(Style.FILL);
      // 绘制左边1
      canvas.drawRect(0, 0, mHorizontalPadding, getHeight(), mPaint);
      // 绘制右边2
      canvas.drawRect(getWidth() - mHorizontalPadding, 0, getWidth(),
            getHeight(), mPaint);
      // 绘制上边3
      canvas.drawRect(mHorizontalPadding, 0, getWidth() - mHorizontalPadding,
            mVerticalPadding, mPaint);
      // 绘制下边4
      canvas.drawRect(mHorizontalPadding, getHeight() - mVerticalPadding,
            getWidth() - mHorizontalPadding, getHeight(), mPaint);


      RectF rect = new RectF(mHorizontalPadding, mVerticalPadding, getWidth()
            - mHorizontalPadding, getHeight() - mVerticalPadding);
      Path mPath = new Path();
      mPath.moveTo(mHorizontalPadding,mVerticalPadding);
      mPath.lineTo(mHorizontalPadding,getHeight()/2);
      mPath.arcTo(rect,180,90);
      mPath.lineTo(mHorizontalPadding,mVerticalPadding);
      canvas.drawPath(mPath,mPaint);

      mPath.reset();

      mPath.moveTo(getWidth() - mHorizontalPadding,mVerticalPadding);
      mPath.lineTo(getWidth()/2,mVerticalPadding);
      mPath.arcTo(rect,270,90);
      mPath.lineTo(getWidth() - mHorizontalPadding,mVerticalPadding);
      canvas.drawPath(mPath,mPaint);

      mPath.reset();

      mPath.moveTo(getWidth() - mHorizontalPadding,getHeight() - mVerticalPadding);
      mPath.lineTo(getWidth() - mHorizontalPadding,getHeight()/2);
      mPath.arcTo(rect,0,90);
      mPath.lineTo(getWidth() - mHorizontalPadding,getHeight() - mVerticalPadding);
      canvas.drawPath(mPath,mPaint);

      mPath.reset();

      mPath.moveTo(mHorizontalPadding,getHeight() - mVerticalPadding);
      mPath.lineTo(getWidth()/2,getHeight()-mVerticalPadding);
      mPath.arcTo(rect,90,90);
      mPath.lineTo(mHorizontalPadding,getHeight() - mVerticalPadding);
      canvas.drawPath(mPath,mPaint);

      // 绘制外边框
      mPaint.setColor(mBorderColor);
      mPaint.setStrokeWidth(mBorderWidth);
      mPaint.setStyle(Style.STROKE);
      canvas.drawCircle(getWidth()/2,getHeight()/2 ,getWidth()/2 - mHorizontalPadding,mPaint);

   }

   public void setHorizontalPadding(int mHorizontalPadding)
   {
      this.mHorizontalPadding = mHorizontalPadding;
      
   }

}

代码的思路就是中间有个矩形,那个矩形的内接圆就是我们要的圆形,在这个圆形外画一层半透明遮罩来达到效果


上面代码还是比较复杂,改进之后代码如下:


public class CutImageBorderView extends View {
    //水平方向与View的边
    private int mHorizontalPadding;
    //垂直方向与View的边
    private int mVerticalPadding;
    //绘制矩形的宽度
    private int mWidth;
    //边框的颜色
    private int mBorderColor;
    //边框的宽度,单位为dip
    private int mBorderWidth = 1;
    //画笔
    private Paint mPaint;
    private Paint mBoderPaint;
    //圆的画笔
    private int mRadius = 360;
    private Xfermode cur_xfermode;
    private Rect r;
    private RectF rf;


    public CutImageBorderView(Context context) {
        this(context, null);
    }

    public CutImageBorderView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
        // TODO Auto-generated constructor stub
    }

    public CutImageBorderView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        // TODO Auto-generated constructor stub
        WindowManager manager = ((Activity) context).getWindowManager();
        DisplayMetrics outMetrics = new DisplayMetrics();
        manager.getDefaultDisplay().getMetrics(outMetrics);
        int width = outMetrics.widthPixels;
        mRadius = width / 2;
        mBorderColor = Color.parseColor("#FFFFFF");
        mBorderWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                mBorderWidth,
                getResources().getDisplayMetrics());
        mPaint = new Paint();
        mBoderPaint = new Paint();
        mBoderPaint.setAntiAlias(true);
        mBoderPaint.setStyle(Style.STROKE);
        mBoderPaint.setStrokeWidth(mBorderWidth);
        mBoderPaint.setColor(Color.parseColor("#FFFFFF"));
        //抗锯齿
        mPaint.setAntiAlias(true);
        //取下层绘制非交集部分
        cur_xfermode = new PorterDuffXfermode(PorterDuff.Mode.DST_OUT);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        // TODO Auto-generated method stub
        super.onDraw(canvas);
        //计算矩形的宽度
        mWidth = getWidth() - 2 * mHorizontalPadding;
        //计算垂直距离边的高度
        mVerticalPadding = (getHeight() - mWidth) / 2;

        if (rf == null || rf.isEmpty()) {
            r = new Rect(0, 0, getWidth(), getHeight());
            rf = new RectF(r);
        }
        mPaint.setStyle(Style.STROKE);

        // 在imageview上面画入背景和 圆形
        int sc = canvas.saveLayer(rf, null, Canvas.MATRIX_SAVE_FLAG | Canvas.CLIP_SAVE_FLAG | Canvas.HAS_ALPHA_LAYER_SAVE_FLAG | Canvas.FULL_COLOR_LAYER_SAVE_FLAG | Canvas.CLIP_TO_LAYER_SAVE_FLAG | Canvas.ALL_SAVE_FLAG);
        mPaint.setColor(Color.parseColor("#aa000000"));
        mPaint.setStyle(Style.FILL);
        canvas.drawRect(r, mPaint);
        mPaint.setXfermode(cur_xfermode);

        canvas.drawCircle(getWidth() / 2, getHeight() / 2, mRadius, mPaint);

        canvas.drawCircle(getWidth() / 2, getHeight() / 2, mRadius, mBoderPaint);
        canvas.restoreToCount(sc);
        mPaint.setXfermode(null);
    }
}

改进之后代码量变少,但是能达到同样效果,请参考,如有错误,欢迎指正~

猜你喜欢

转载自blog.csdn.net/abs625/article/details/76668036
今日推荐