圆形图片

之前有写过简单的实现圆形图片,不过效果不是很好,今天偶然看到很老的项目中用到自定义的圆形图片,也是基于画布裁剪实现的,会发现这种效果很不好圆形图片的一圈有明显的锯齿(也可以看一下之前的文章几行代码简单搞定圆形图片),即使使用抗锯齿也不行。于是就重新写了一下代码,在记录一下,其中关于PorterDuffXfermode的使用可以看之前的一篇文章关于PorterDuff.Mode的一点理解,具体实现代码如下:

public class CircleImageView extends ImageView {
    private Paint mPaint;
    private Bitmap mBitmap;
    private int mSize;

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

    public CircleImageView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CircleImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setDither(true);
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setAlpha(255);
        //PorterDuffXfermode使用时候要去掉硬件加速,避免黑色背景
        setLayerType(View.LAYER_TYPE_SOFTWARE, null);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int width_mode = MeasureSpec.getMode(widthMeasureSpec);
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height_mode = MeasureSpec.getMode(heightMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
        mSize = Math.min(width, height);
        int mode;
        if (width_mode != MeasureSpec.UNSPECIFIED || height_mode != MeasureSpec.UNSPECIFIED) {
            mode = MeasureSpec.EXACTLY;
        } else {
            mode = MeasureSpec.UNSPECIFIED;
        }
        setMeasuredDimension(MeasureSpec.makeMeasureSpec(mSize, mode), MeasureSpec.makeMeasureSpec(mSize, mode));
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(mBitmap);
        //祛除padding造成的影响,根据padding来调整圆心和半径
        int centerX = w / 2 + getPaddingLeft() - getPaddingRight();
        int centerY = h / 2 + getPaddingTop() - getPaddingBottom();
        int radiusX = (w - getPaddingLeft() - getPaddingRight()) / 2;
        int radiusY = (h - getPaddingTop() - getPaddingBottom()) / 2;
        int radius = Math.min(radiusX, radiusY);
        //半径减去2避免太靠边缘
        canvas.drawCircle(centerX, centerY, (radius - 2) > 0 ? radius - 2 : radius, mPaint);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
        canvas.drawBitmap(mBitmap, 0, 0, mPaint);
        if (!mBitmap.isRecycled()) {
            mBitmap.recycle();
            mBitmap = null;
        }
    }
}

代码很简单效果还不错,看一下效果图:


圆形图片_第1张图片
圆形图片

基于此份代码可以很容易扩展各种各样的图片,比如圆角图,五星图等;

你可能感兴趣的:(圆形图片)