美文网首页
Android 圆角&圆形图片

Android 圆角&圆形图片

作者: 王增辉 | 来源:发表于2015-11-25 12:59 被阅读309次

    利用 Xfermode 实现

    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.PorterDuff;
    import android.graphics.PorterDuffXfermode;
    import android.graphics.RectF;
    import android.graphics.Xfermode;
    import android.graphics.drawable.Drawable;
    import android.util.AttributeSet;
    import android.widget.ImageView;
    
    import java.lang.ref.WeakReference;
    
    /**
     * Created by wangzenghui on 15/8/24.
     */
    public class RoundImageView extends ImageView {
    
        public static final int TYPE_CIRCLE = 0;
        public static final int TYPE_ROUND = 1;
    
        public static final int BORDER_RADIUS_DEFAULT = 10;
    
        private Paint mPaint;
        private Xfermode mXfermode = new PorterDuffXfermode(PorterDuff.Mode.DST_IN);
        private Bitmap mMaskBitmap;
        private WeakReference<Bitmap> mWeakBitmap;
    
        private int mType = TYPE_CIRCLE;
        private int mBorderRadius = BORDER_RADIUS_DEFAULT;
    
        public RoundImageView(Context context) {
            this(context, null);
        }
    
        public RoundImageView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public RoundImageView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
    
            mPaint = new Paint();
            mPaint.setAntiAlias(true);
    
            if (attrs != null) {
    
            }
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    
            if (mType == TYPE_CIRCLE) {
                int width = Math.min(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec));
                setMeasuredDimension(width, width);
            }
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            Bitmap bitmap = mWeakBitmap == null ? null : mWeakBitmap.get();
    
            if (bitmap == null || bitmap.isRecycled()) {
                Drawable drawable = getDrawable();
    
                int dWidth = drawable.getIntrinsicWidth();
                int dHeight = drawable.getIntrinsicHeight();
    
                if (drawable != null) {
                    bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
    
                    float scale = 1.0f;
    
                    Canvas drawCanvas = new Canvas(bitmap);
    
                    if (mType == TYPE_ROUND) {
                        scale = Math.max(getWidth() * 1.0f / dWidth, getHeight() * 1.0f / dHeight);
                    } else if (mType == TYPE_CIRCLE) {
                        scale = getWidth() * 1.0f / Math.min(dWidth, dHeight);
                    }
    
                    drawable.setBounds(0, 0, (int) (scale * dWidth), (int) (scale * dHeight));
                    drawable.draw(drawCanvas);
    
                    if (mMaskBitmap == null || mMaskBitmap.isRecycled()) {
                        mMaskBitmap = getBitmap();
                    }
    
                    mPaint.reset();
                    mPaint.setFilterBitmap(false);
                    mPaint.setXfermode(mXfermode);
                    //绘制形状  
                    drawCanvas.drawBitmap(mMaskBitmap, 0, 0, mPaint);
                    mPaint.setXfermode(null);
                    //将准备好的bitmap绘制出来  
                    canvas.drawBitmap(bitmap, 0, 0, null);
                    //bitmap缓存起来,避免每次调用onDraw,分配内存  
                    mWeakBitmap = new WeakReference<Bitmap>(bitmap);
                }
            }
    
            //如果bitmap还存在,则直接绘制即可
            if (bitmap != null) {
                mPaint.setXfermode(null);
                canvas.drawBitmap(bitmap, 0.0f, 0.0f, mPaint);
                return;
            }
        }
    
        public Bitmap getBitmap() {
            Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(bitmap);
            Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
            paint.setColor(Color.BLACK);
    
            if (mType == TYPE_ROUND) {
                canvas.drawRoundRect(new RectF(0, 0, getWidth(), getHeight()), mBorderRadius, mBorderRadius, paint);
            } else {
                canvas.drawCircle(getWidth() / 2, getWidth() / 2, getWidth() / 2, mPaint);
            }
    
            return bitmap;
        }
    
        @Override
        public void invalidate() {
            mWeakBitmap = null;
    
            if (mMaskBitmap != null) {
                mMaskBitmap.recycle();
                mMaskBitmap = null;
            }
            super.invalidate();
        }
    }
    

    1.PorterDuff.Mode.CLEAR
    所绘制不会提交到画布上。
    2.PorterDuff.Mode.SRC
    显示上层绘制图片
    3.PorterDuff.Mode.DST
    显示下层绘制图片
    4.PorterDuff.Mode.SRC_OVER
    正常绘制显示,上下层绘制叠盖。
    5.PorterDuff.Mode.DST_OVER
    上下层都显示。下层居上显示。
    6.PorterDuff.Mode.SRC_IN
    取两层绘制交集。显示上层。
    7.PorterDuff.Mode.DST_IN
    取两层绘制交集。显示下层。
    8.PorterDuff.Mode.SRC_OUT
    取上层绘制非交集部分。
    9.PorterDuff.Mode.DST_OUT
    取下层绘制非交集部分。
    10.PorterDuff.Mode.SRC_ATOP
    取下层非交集部分与上层交集部分
    11.PorterDuff.Mode.DST_ATOP
    取上层非交集部分与下层交集部分
    12.PorterDuff.Mode.XOR
    异或:去除两图层交集部分
    13.PorterDuff.Mode.DARKEN
    取两图层全部区域,交集部分颜色加深
    14.PorterDuff.Mode.LIGHTEN
    取两图层全部,点亮交集部分颜色
    15.PorterDuff.Mode.MULTIPLY
    取两图层交集部分叠加后颜色
    16.PorterDuff.Mode.SCREEN
    取两图层全部区域,交集部分变为透明色

    Canvas canvas = new Canvas(dst);
    paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
    canvas.drawBitmap(src, 0f, 0f, paint);
    

    更多实现方式

    相关文章

      网友评论

          本文标题:Android 圆角&圆形图片

          本文链接:https://www.haomeiwen.com/subject/ooarhttx.html