利用 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 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还存在,则直接绘制即可        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);

更多实现方式

更多相关文章

  1. Android学习之抽象类AbsListView
  2. Android(安卓)图片添加水印
  3. 绘制直角坐标系
  4. [Android] 零碎知识汇总 - RecyclerView 顶部悬浮
  5. Android_绘制圆形图片
  6. Android(安卓)基于surfaceView绘制正弦曲线
  7. android recycler添加分割线 点击事件等
  8. View 绘制机制 -- How Android(安卓)Draws Views
  9. Android屏幕简单 截图

随机推荐

  1. 第五章 以数据为中心—数据存取(4)
  2. android 注册页面实现
  3. 【30篇突击 android】源码统计八
  4. Android(安卓)实现简单的登陆注册功能(Sha
  5. android推送学习——google的C2DM
  6. WARNING: APP_PLATFORM android-14 is la
  7. android文章 - 收藏集 - 掘金
  8. Android(安卓)lollipop 更新问题
  9. 如何将一个acitvity同时设置多个theme
  10. eclipse Alt+/ 代码失灵、不响应的解决办