API
1 | void drawImage(Object image, float dx, float dy[float dw, float, dh]); |
drawImage 的第一个参数可以是 HTMLImageElement(绘图),HTMLCanvasElement(复制)或者 HTMLVideoElement(截屏)。
缓存 Canvas 中间数据
如果我们需要在一个 Canvas 上画很多图片,其中一部分是固定(或短期内固定)存在的,那么最好的办法是将他们绘制完毕之后,将他们保存起来,等下一次需要绘制这些图片的时候,一次性绘制缓存结果。这样可以减少渲染次数,以提高渲染效率。
首先想到的是 getImageData 和 putImageData。所以做了如下测试:
1 | var repeat_times = 10000; |
简单起见,这里我们仅仅绘制一张图片。打印出来的结果完全出乎意料,putImageData 非但没有更快,反而比 drawImage 慢 600 倍左右。至于为什么会这么慢,我还不知道答案。总之 putImageData 远远不是我想象中的那么高效。
后来才考虑到可以将 Canvas 中的数据缓存到某个隐藏 Canvas 中去,然后再调用 DrawImage 方法。
1 | console.time('drawCanvas'); |
经过测试以后发现比 drawImage 方法慢了一倍,相对于 10000 次循环,这点性能损失可以忽略不计,因为我们仅仅绘制一张图片。图片的数目每增加 1,drawImage 绘图次数增加 10000,而 drawCanvas 绘图次数仅仅增加 1。
小结
putImageData
的优点在于能够像素级别操作图像,但是因其效率很低,并不适合做 Canvas 的数据缓存,而drawImage(canvas, 0, 0)
较为适合。