本文出自Zone的博客,如需转载请标明出处,尊重原创谢谢 博客地址:https://luhaoaimama1.github.io/2016/05/18/Canvas/
以我个人主观推断的Canvas工作原理
如果有错误请指出谢谢~
This behaves the same as save(), but in addition it allocates and redirects drawing to an offscreen bitmap.
All drawing calls are directed to a newly allocated offscreen bitmap.
Only when the balancing call to restore() is made,
is that offscreen buffer drawn back to the current target of the Canvas (either the screen, it's target Bitmap, or the previous layer).
大概意思:新建的一个bitmap(离屏)代表Layer(叫他是因为层的概念我们好理解),后续全部的操作(包括drawingXXX)都会定向到这个新的离屏bitmap,仅仅当restore的时候,离屏的绘制缓存才能绘制到current target of the Canvas(bt/offscreen)上
先看一个例子:
new Cavas(bitmap);
cavas.translate(0,10);
cavas.drawLine(...)//横线
cavas.translate(0,10);
cavas.drawLine(...)//横线
结果是:bitmap没有随着cavas.translate位移而改变,但是canvas.translate后边的draw后边的发生改变了 说明draw方法是已canvas的参考系为参考,而canvas的参考系有rorate,translate,clip 等属性; 经过这些属性的调整最终映射到bitmap坐标系进行绘制,绘制在bitmap的图像就和canvas没关系了(既调整canvas也不会改变bitmap的图像)
结论:canvas就像 辅助坐标系,辅助draw方法绘制到最终的bitmap上 鼠绘的人会不停的旋转画布翻转画布,来绘制线条,主要为了为更舒适(对我们来说就是更简单,更容易理解 );
new Cavas(bitmap);cavas.drawLine(...)//横线
cavas.rorate(90°,x,y);
cavas.drawLine(...)//横线
如果没有画布你怎么绘制Line 会计算 cos(90°)与sin(90°)算成坐标点 然后drawLine 发现简单了吧
我认为原理大概是:bitmap会有个方法(假想)叫setAlpha(int alpha)导致所有drawXXX系列的图像的透明度(drawAlpha)最终会=alpha/255*drawAlpha;
restoreToCount(int saveCount):就是对restore的封装(saveCount必须>=1)
例如:save四次 然后restore三次;
save();1
save();2
save();3
save();4
//save栈中为1->2->3->4->5(now)
restore();到4
restore();到3
restore();到2
//save栈中为 1->2 也相当于直接使用 restoreToCount(2)
源码大概最后会使用canvas.restoreToCount(1)吧
Tips:自己弄的Canvas 注意一定要restore 把离屏缓存 不然 layer绘制的不会显示!
所以我们要养成习惯restore,这样代码在哪都不会错
因为canvas.save() 返回的值 是上个图层的值。而且Canvas提供了图层(Layer)支持,缺省情况可以看作是只有一个图 层Layer。
restoreToCount(2)是不显示的!而且可以理解为
restore();到4
restore();到3
restore();到2
所以这是的图像 在第2个Layer(bitmap)上呢
必须restore(1)因为第一层Layer(bt)的引用的正是我们new Canvas(bt)的bt;
public int saveLayer(RectF bounds, Paint paint, int saveFlags)