58.圆角图片
![](https://images2015.cnblogs.com/blog/798130/201512/798130-20151223131531781-282895004.png)
绘制流程:
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 取两层图像的非交集部门