您的位置:首页 > 其它

上传头像时圆形裁剪框

2017-08-04 10:43 190 查看
上传头像到服务端时需要将图片裁剪,项目中用到的是圆形的裁剪框,先看效果:



代码实现如下:

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);
}
}


改进之后代码量变少,但是能达到同样效果,请参考,如有错误,欢迎指正~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: