我想更好地了解 Android (2D) Canvas 绘图管道的组件如何组合在一起。
例如,XferMode、Shader、MaskFilter和ColorFilter是如何交互的?这些类的参考文档非常少,Canvas和Paint的文档并没有真正添加任何有用的解释。
我也不完全清楚具有固有颜色的绘图操作(例如:drawBitmap
,与“矢量”原语如drawRect
)如何适应所有这些 - 他们总是忽略Paint
's 颜色并使用它们的固有颜色代替吗?
我也很惊讶一个人可以做这样的事情:
Paint eraser = new Paint();
eraser.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
canvas.drawOval(rectF, eraser);
这会擦除一个椭圆。在我注意到这一点之前,我的心智模型是绘制到画布(概念上)绘制到单独的“层”,然后使用 Paint 的传输模式与 Canvas 的位图组合该层。如果它像那样简单,那么上面的代码将擦除整个位图(在剪辑区域内),因为 CLEAR总是将颜色(和 alpha)设置为 0,而不考虑源的 alpha。所以这意味着有一种额外的掩蔽将擦除限制为椭圆形。
我确实找到了API 演示,但每个演示都“在真空中”工作,并且没有显示它关注的东西(例如:XferModes)如何与其他东西(例如:ColorFilters)交互。
通过足够的时间和精力,我可以凭经验弄清楚这些部分是如何关联的,或者去破译来源,但我希望其他人已经解决了这个问题,或者更好的是有一些关于管道/绘图模型的实际文档我错过了。
这个问题的灵感来自于看到另一个 SO question 的答案中的代码。
更新
在四处寻找一些文档时,我突然想到,由于我在这里感兴趣的很多东西似乎是在skia之上的一个非常薄的单板,也许有一些 skia 文档会有所帮助。我能找到的最好的东西是文档,SkPaint
其中说:
有 6 种类型的效果可以分配给绘画:
- SkPathEffect - 在生成 Alpha 蒙版之前修改几何体(路径)(例如虚线)
- SkRasterizer - 组成自定义遮罩层(例如阴影)
- SkMaskFilter - 在着色和绘制之前修改 alpha 蒙版(例如模糊、浮雕)
- SkShader - 例如渐变(线性、径向、扫描)、位图图案(钳位、重复、镜像)
- SkColorFilter - 在应用 xfermode 之前修改源颜色(例如颜色矩阵)
- SkXfermode - 例如 porter-duff 传输模式、混合模式
它没有明确说明,但我猜这里的效果顺序是它们出现在管道中的顺序。