您的位置:首页 > Web前端

PorterDuffXfermode 正确使用方式(详解)

2016-05-06 11:16 441 查看


正确姿势中:黄色的为先画的 即下层 蓝色的为后画的 即上层

SRC是上层 dst是下层 in是交集 out是 不想交的

举例:PorterDuff.Mode.SRC_IN参数,表示的是取两层绘制交集。显示上层

核心原理(边界):

图一(正确姿势):两张bitmap已手机宽高为例 边界:宽高既是手机的宽高 所以 里面连个图形 不透明与不透明颜色相交 不相交的 在边界里用叠加模式 所以和左边给的效果是一致的

图二(平时的误解):一个bitmap drawCircle 的两个 所以边界是我画的两个矩形 注意 :边界就是是第层的区域 边界内用叠加模式去弄 边界之外不用叠加模式 所以会变成这样

SrcIn的时候

例子:这里所有的注释 都是非常重要的 所以都需要去用心的看!!!(我认为的~)

github上的代码演示->动画、surfaceView、绘图方面的研究->Xfermode->选择mode

https://github.com/luhaoaimama1/ZoneStudio/blob/master/Android_Zone_Test/src/com/example/mylib_test/activity/animal/viewa/XfermodeView.java

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
onDrawFinal(canvas);
}
private void onDrawFinal(Canvas canvas) {
if (mode!=null) {
paint.reset();
//都好使
//            bitmapXfermodeExample1(canvas);
graphXfermodeExample2(canvas);
}
}
//这种对应情况图2
private void graphXfermodeExample2(Canvas canvas) {
//为什么这么写savelayer因为 super.draw会又底图层  想要与底层不干扰 不叠加需要save或者 直接画bitmap
//但是画bitmap的画 那个bitmap又需要一个新的画布去叠加 所以savelayer最快了!!!!
//这两种都行
//        canvas.saveLayer(0, 0, getWidth(), getHeight(), paint,Canvas.ALL_SAVE_FLAG);
canvas.saveLayerAlpha(0, 0, getWidth(), getHeight(), 255,
Canvas.ALL_SAVE_FLAG);
paint.setColor(Color.YELLOW);
canvas.drawCircle(getWidth() / 2, getHeight() / 2, 200, paint);
paint.setXfermode(new PorterDuffXfermode(mode));
paint.setColor(Color.BLUE);
canvas.drawCircle(getWidth() / 2 + 200, getHeight() / 2 + 200, 200, paint);
//        canvas.restoreToCount(1);//可以不用  按道理多图层应该是会用到!!!但是不知道为啥不用也好使!!!
}
//这种对应情况图1
private void bitmapXfermodeExample1(Canvas canvas) {
Canvas canvas2=new Canvas();
//画黄色的圆 满屏幕那种 bitmap
Bitmap bt = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_4444);
canvas2.setBitmap(bt);
paint.setColor(Color.YELLOW);
canvas2.drawCircle(getWidth() / 2, getHeight() / 2, 200, paint);
//画蓝色的圆 满屏幕那种 bitmap
Bitmap bt2 = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_4444);
canvas2.setBitmap(bt2);
paint.setColor(Color.BLUE);
canvas2.drawCircle(getWidth() / 2 + 200, getHeight() / 2 + 200, 200, paint);
//--------可用1 bitmap叠加 最简单的------------------------------------------------------------------------------------------------
//        canvas2.setBitmap(bt);
//        paint.setXfermode(new PorterDuffXfermode(mode));
//        canvas2.drawBitmap(bt2, 0, 0, paint);
//        //如果canvas.draw的时候 这句话是必须的 因为系统super.draw会绘制一个图层如果不制空叠加模式 会导致混乱的
//        paint.setXfermode(null);
//        //最后用画布展现出那个最终合成的bitmap
//        canvas.drawBitmap(bt, 0, 0, paint);
//--------可用1 结束------------------------------------------------------------------------------------------------
//--------可用2  bitmap叠加   最後发现模式和 setBitmap和此相当  并且 叠加模式可以在draw上用而且可以的不是一次
//        Bitmap bt3 = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_4444);
//        canvas2=new Canvas(bt3);
//        canvas2.drawBitmap(bt, 0, 0, paint);
//        paint.setXfermode(new PorterDuffXfermode(mode));
//        canvas2.drawBitmap(bt2, 0, 0, paint);
//        paint.setXfermode(null);
//        canvas.drawBitmap(bt3, 0, 0, paint);
//--------可用2 结束------------------------------------------------------------------------------------------------
//--------可用3  第二图层layer 叠加
//        paint.setXfermode(null);//此行要注意 super.draw也会话的 如果用叠加模式 会混乱的 当然默认模式是null 如果没写过 可以不写此行
//        canvas.saveLayer(0, 0, getWidth(), getHeight(), paint,
//                Canvas.ALL_SAVE_FLAG);
//        canvas.drawBitmap(bt, 0, 0, paint);
//        paint.setXfermode(new PorterDuffXfermode(mode));
//        canvas.drawBitmap(bt2, 0, 0, paint);
//        canvas.restoreToCount(1);//可以不用  按道理多图层应该是会用到!!!但是不知道为啥不用也好使!!!
//--------可用3 结束------------------------------------------------------------------------------------------------
//--------可用4  多图层layer 叠加
//        paint.setXfermode(null);//此行要注意 super.draw也会话的 如果用叠加模式 会混乱的 当然默认模式是null 如果没写过 可以不写此行
canvas.saveLayer(0, 0, getWidth(), getHeight(), paint,
Canvas.ALL_SAVE_FLAG);
canvas.drawBitmap(bt, 0, 0, paint);
paint.setXfermode(new PorterDuffXfermode(mode));
//注意这里savelayer的paint 是有叠加模式的!!!!!!!!!!!!!!!!!
canvas.saveLayer(0, 0, getWidth(), getHeight(), paint,
Canvas.ALL_SAVE_FLAG);
paint.setXfermode(null);//注意这里需要吧叠加模式制空 不然会与layer的空位图 进行叠加
canvas.drawBitmap(bt2, 0, 0, paint);
//        canvas.restoreToCount(1);//可以不用  按道理多图层应该是会用到!!!但是不知道为啥不用也好使!!!
//--------可用4 结束-------------------------------------------------------------------
}


setXfermode的注意

1 paint.setXfermode(null);

… 2和1相互作用

2 paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));

… 这个之间的算2的 都与1相互作用

3 paint.setXfermode(null);

… 4和3 相互作用

4 paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));

layer入栈出栈的理解

这个出栈:restore,restoreToCount但Layer入栈时,后续的DrawXXX操作都发生在这个Layer上,而Layer退栈时,就会把本层绘制的图像“绘制”到上层或是Canvas上

最后最好加上  能让原始的背景色显示出来

paint.setXfermode(null);// 这样就没有了叠加模式 

canvas.restoreToCount(1);//因为让layer退栈 把本层绘制到上层 那么 上边这个 也是对应的叠加模式

即canvas为最下层即1 栈顺序如下图所示



疑问:

canvas.restoreToCount(1);//可以不用 按道理多图层应该是会用到!!!但是不知道为啥不用也好使!!!

如果有人懂的话 求告知
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息