Android-PorterDuffXfermode的正确使用方式
文章目录
看这篇文章请确保看过本站的Android-Canvas这篇文章,主要理解其工作模式后会更容易理解;
官方合成图
如正确姿势的图,首先要明白的
官方文档带图:https://developer.android.com/reference/android/graphics/PorterDuff.Mode
粉红色就是上面的黄色
1 | //dst:Destination image |
当需要清空图像时,使用Mode.CLEAR
我的理解是 对于Xfermode src 是对当前层的图案,而dst是 作用目标层
名字 | 解释2 | 名字 | 解释2 |
---|---|---|---|
DST黄色 | 先画 就是Ps蒙版中的底层 | in | 交集 |
SOURCE蓝色 | 后画 就是Ps蒙版中的上层 | out | 不相交的 |
举例:PorterDuff.Mode.SRC_IN参数 显示 是交集部分 图像为SRC部分
名字 | 解释2 |
---|---|
图2 | 创建两个Bitmap 手机宽高 bitmap上绘制圆 如果看不懂看下面的代码 |
图1 | 绘两个圆 如果看不懂看下面的代码 |
核心原理(边界):
Xfermode效果:作用在
两个边界之内
;边界之外
没有Xfermode效果
;
图 | 边界 | SRC_IN | SRC_OUT |
---|---|---|---|
图2 正确姿势 |
每个都是手机的宽高 | 正确姿势图中的SRC_IN | 如正确姿势图中的 SRC_OUT |
图1 平时的误解 |
每个都是绘的圆那么大 | 如 正确姿势图中的SRC_IN 但多出黄色的部分 |
如 正确姿势图中的SRC_OUT 但多出黄色的部分 |
正确姿势图 是官方给的图;
Tips:为什么多出黄色的部分? 因为这个部分是 边界未相交的部分,那么不会有Xfermode的效果 所以剩下;
那么大家会很疑惑,为什么DST剩下了,SRC边界之外为何不剩下?
因为DST先绘制的 就是底图.SRC是为了给DST添加叠加模式的效果的.
最终显示的都是DST只是变成有叠加效果的DST;
demo效果:动画、surfaceView、绘图方面的研究->Xfermode;然后选择模式;
xfermode代码
图1的代码:
1 | canvas.saveLayerAlpha(0, 0, getWidth(), getHeight(), 255, |
图2的代码:
1 | //画黄色的圆 满屏幕那种 bitmap |
Tips:如果用到 canvas.saveLayer(,paint,) 图层的方式进行xfermode 最好给图层一个单独的paint。不要和 图层内部draw的paint的xfermode混淆. 这里被坑过
Tips2: 叠加模式的paint和绘制的paint不要用一个, 因为会混乱.因为很重要所以还要重复~
问题延伸
为什么 不用saveLayerAlpha有时候就不好使 其实就是边界 混合区域
harvic博客解释了为什么不用saveLayerAlpha有时候就不好使?
1 | int layerID = canvas.saveLayer(0, 0, width * 2, height * 2, mPaint, Canvas.ALL_SAVE_FLAG); |
有saveLayer的绘图流程
这是因为在调用saveLayer时,会生成了一个全新的bitmap,这个bitmap的大小就是我们指定的保存区域的大小,新生成的bitmap是全透明的,在调用saveLayer后所有的绘图操作都是在这个bitmap上进行的。
没有saveLayer的绘图流程
由于我们先把整个画布给染成了绿色,然后再画上了一个圆形,所以在应用xfermode来画源图像的时候,目标图像当前Bitmap上的所有图像了,也就是整个绿色的屏幕和一个圆形了。所以这时候源图像的相交区域是没有透明像素的,透明度全是100%,这也就不难解释结果是这样的原因了。
总结就是 saveLayer为了区分,哪一步的图形,应该与合成模式的bitmap去合成 运算;
layer入栈出栈的理解
这个出栈:restore,restoreToCount但Layer入栈时,后续的DrawXXX操作都发生在这个Layer上,而Layer退栈时,就会把本层绘制的图像“绘制”到上层或是Canvas上