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);//可以不用 按道理多图层应该是会用到!!!但是不知道为啥不用也好使!!!如果有人懂的话 求告知
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories