Paint.setXfermode终极解析
效果图
关于Paint.setXfermode网上有很多篇文档,但有些未详细说明或讲解有错误,经本人测试,以下是测试结果效果图
由于时间关系只能简要说明思路和结果,如无有疑问请阅读代码
- 灰色的canvas背景色
- 创建一个空白的mDstBitmap并画一个黄色的圆
- 创建一个空白的mSrcBitmap并画一个蓝色的矩形(注意这个矩形画在mSrcBitmap中间,mSrcBitmap没有画满是为了观察到组合后差异)
结论
设置 | 意义 |
---|---|
CLEAR | src无像素+重叠消失 |
SRC | src无像素消失,src完全显示 |
SRC_OVER | src重叠显示,src未重叠显示 |
SRC_ATOP | src重叠显示 |
SRC_IN | src无像素消失,重叠显示src |
SRC_OUT | src无像素和重叠消失,src未重叠显示 |
DST | dst不变,src无显示 |
DST_OVER | dst不变,src未重叠显示 |
DST_ATOP | src无像素消失,重叠显示dst,显示src |
DST_IN | src无像素消失,重叠显示dst |
DST_OUT | 重叠消失,src不显示 |
XOR | 重叠消失,src未重叠显示 |
DARKEN | 重叠颜色加深,src未重叠显示 |
LIGHTEN | 重叠颜色变亮,src未重叠显示 |
MULTIPLY | src无像素消失,重叠加深显示 |
SCREEN | 重叠变亮,src未重叠显示 |
ADD | 重叠变亮,src未重叠显示 |
OVERLAY | 重叠变亮,src未重叠显示 |
Dome代码
布局文件
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal"> <LinearLayout android:layout_width="wrap_content" android:layout_height="match_parent" android:orientation="vertical" android:padding="5dp" tools:context="com.feadre.customview.MainActivity"> <com.feadre.customview.myview.SetXfermodeView android:layout_width="85dp" android:layout_height="85dp" app:set_mode="1" app:show_text="CLEAR" /> <com.feadre.customview.myview.SetXfermodeView android:layout_width="85dp" android:layout_height="85dp" android:layout_marginTop="10dp" app:set_mode="12" app:show_text="XOR" /> <com.feadre.customview.myview.SetXfermodeView android:layout_width="85dp" android:layout_height="85dp" android:layout_marginTop="10dp" app:set_mode="13" app:show_text="DARKEN" /> <com.feadre.customview.myview.SetXfermodeView android:layout_width="85dp" android:layout_height="85dp" android:layout_marginTop="10dp" app:set_mode="14" app:show_text="LIGHTEN" /> <com.feadre.customview.myview.SetXfermodeView android:layout_width="85dp" android:layout_height="85dp" android:layout_marginTop="10dp" app:set_mode="15" app:show_text="MULTIPLY" /> <com.feadre.customview.myview.SetXfermodeView android:layout_width="85dp" android:layout_height="85dp" android:layout_marginTop="10dp" app:set_mode="16" app:show_text="SCREEN" /> </LinearLayout> <LinearLayout android:layout_width="wrap_content" android:layout_height="match_parent" android:orientation="vertical" android:padding="5dp" tools:context="com.feadre.customview.MainActivity"> <com.feadre.customview.myview.SetXfermodeView android:layout_width="85dp" android:layout_height="85dp" app:set_mode="2" app:show_text="SRC" /> <com.feadre.customview.myview.SetXfermodeView android:layout_width="85dp" android:layout_height="85dp" android:layout_marginTop="10dp" app:set_mode="3" app:show_text="SRC_OVER" /> <com.feadre.customview.myview.SetXfermodeView android:layout_width="85dp" android:layout_height="85dp" android:layout_marginTop="10dp" app:set_mode="4" app:show_text="SRC_ATOP" /> <com.feadre.customview.myview.SetXfermodeView android:layout_width="85dp" android:layout_height="85dp" android:layout_marginTop="10dp" app:set_mode="5" app:show_text="SRC_IN" /> <com.feadre.customview.myview.SetXfermodeView android:layout_width="85dp" android:layout_height="85dp" android:layout_marginTop="10dp" app:set_mode="6" app:show_text="SRC_OUT" /> <com.feadre.customview.myview.SetXfermodeView android:layout_width="85dp" android:layout_height="85dp" android:layout_marginTop="10dp" app:set_mode="17" app:show_text="ADD" /> </LinearLayout> <LinearLayout android:layout_width="wrap_content" android:layout_height="match_parent" android:orientation="vertical" android:padding="5dp" tools:context="com.feadre.customview.MainActivity"> <com.feadre.customview.myview.SetXfermodeView android:layout_width="85dp" android:layout_height="85dp" app:set_mode="7" app:show_text="DST" /> <com.feadre.customview.myview.SetXfermodeView android:layout_width="85dp" android:layout_height="85dp" android:layout_marginTop="10dp" app:set_mode="8" app:show_text="DST_OVER" /> <com.feadre.customview.myview.SetXfermodeView android:layout_width="85dp" android:layout_height="85dp" android:layout_marginTop="10dp" app:set_mode="9" app:show_text="DST_ATOP" /> <com.feadre.customview.myview.SetXfermodeView android:layout_width="85dp" android:layout_height="85dp" android:layout_marginTop="10dp" app:set_mode="10" app:show_text="DST_IN" /> <com.feadre.customview.myview.SetXfermodeView android:layout_width="85dp" android:layout_height="85dp" android:layout_marginTop="10dp" app:set_mode="11" app:show_text="DST_OUT" /> <com.feadre.customview.myview.SetXfermodeView android:layout_width="85dp" android:layout_height="85dp" android:layout_marginTop="10dp" app:set_mode="18" app:show_text="OVERLAY" /> </LinearLayout>
代码
public class SetXfermodeView extends View { public String mText = "没有设置哦"; private final Paint mPaint; private Bitmap mSrcBitmap; private Bitmap mDstBitmap; private int mMode; private Paint mTitlePaint; public SetXfermodeView(Context context) { this(context, null); } public SetXfermodeView(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } public SetXfermodeView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); setLayerType(View.LAYER_TYPE_SOFTWARE, null); TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.SetXfermodeView, defStyleAttr, 0); String text = array.getString(R.styleable.SetXfermodeView_show_text); mMode = array.getInt(R.styleable.SetXfermodeView_set_mode, 0); if (!TextUtils.isEmpty(text)) { mText = mMode + " " + text + " 模式"; } mPaint = new Paint(); mTitlePaint = new Paint(); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { int width = w / 8 * 7; int height = h / 8 * 7; mSrcBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); mDstBitmap = Bitmap.createBitmap(width-50, height-50, Bitmap.Config.ARGB_8888); drawDST(); } private void drawTitle(Canvas canvas) { mTitlePaint.setColor(Color.RED); mTitlePaint.setFakeBoldText(true); mTitlePaint.setStyle(Paint.Style.FILL); mTitlePaint.setTextSize(30); canvas.drawText(mText, 0, getHeight()-10, mTitlePaint); } private void drawDST() { Canvas c = new Canvas(mSrcBitmap); Paint p = new Paint(Paint.ANTI_ALIAS_FLAG); p.setColor(0xFFFFCC44); c.drawOval(new RectF(10, 10, mSrcBitmap.getWidth(), mSrcBitmap.getHeight()), p); } private void drawSRC() { Canvas c = new Canvas(mDstBitmap); Paint p = new Paint(Paint.ANTI_ALIAS_FLAG); p.setColor(0xFF66AAFF); c.drawRect(30, 30, mDstBitmap.getWidth()-30, mDstBitmap.getHeight()-30, p); } @Override protected void onDraw(Canvas canvas) { canvas.drawColor(Color.GRAY); int layerId = canvas.saveLayer(0, 0, getWidth(), getHeight(), null, Canvas.ALL_SAVE_FLAG); canvas.drawBitmap(mSrcBitmap, 0, 0, mPaint); drawSRC(); switch (mMode) { case 1: mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); break; case 2: mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC)); break; case 3: mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER)); break; case 4: mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP)); break; case 5: mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); break; case 6: mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT)); break; case 7: mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST)); break; case 8: mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OVER)); break; case 9: mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP)); break; case 10: mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN)); break; case 11: mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT)); break; case 12: mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.XOR)); break; case 13: mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DARKEN)); break; case 14: mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.LIGHTEN)); break; case 15: mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY)); break; case 16: mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SCREEN)); break; case 17: mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.ADD)); break; case 18: mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.OVERLAY)); break; } canvas.drawBitmap(mDstBitmap, 90, 40, mPaint); mPaint.setXfermode(null); drawTitle(canvas); canvas.restoreToCount(layerId); } }
结束语
如果您觉得这篇文章能够帮助到您,请帮忙顶一下,您的鼓励是对我的最大支持!
如需转载请标明出处。