【发布时间】:2020-01-23 13:16:11
【问题描述】:
我想知道使用drawImage 缩放和CSS 之间的区别是什么。我已经尝试了这两种方法,CSS 似乎给出了稍微平滑的结果,而 drawImage 往往有点失真 - 特别是如果我平移图像,在几个动画帧的过程中从不同的源 x 和 y 进行 blitting。在对许多不同的比例因子进行测试后,我得出了这个结论。下面我有一个简单的例子。
var img = new Image();
var ctx = document.querySelector("canvas").getContext("2d");
img.src = "img1000x1000.png";// width and height are 1000
ctx.canvas.width = 100;
ctx.canvas.height = 100;
ctx.imageSmoothingEnabled = false;
这在 img 完全加载后运行。
// method 1 uses drawImage to scale
ctx.drawImage(img, 0, 0, 100, 100, 0, 0, 200, 200);
// method 2 draws the img with no scaling and then uses css to scale
ctx.drawImage(img, 0, 0, 100, 100, 0, 0, 100, 100);
ctx.canvas.style.width = 200;
ctx.canvas.style.height = 200;
请记住,我并不总是精确地缩放 2 倍大小,而是从 img 的不同区域进行 blitting。我只将整数提交给 drawImage 以使事情尽可能清晰。我还有image-rendering:pixelated 和其他在 CSS 画布上定义的变体,用于 CSS 缩放以保持清晰。
我知道对于我的具体示例,我可以将 img 放大一次并围绕最终缩放的 img 平移,但这不是问题所在。问题是哪个性能更高。对于我的应用程序,我必须在每一帧上放大一个动画平铺地图,因此我在 1:1 空间中从多个源到一个画布,然后使用 requestAnimationFrame 以每秒 30 到 60 次放大最终画布。
最后,它们给出了非常相似的结果。 CSS 对原始图像几乎没有更清晰和真实。 CSS 更快/更高效吗?还是使用 drawImage 进行缩放更高效?
注意/编辑:
我发现如果我使用<!DOCTYPE html> 的标准模式,我必须将字符串值传递给style.width 和style.height 以用于CSS 方法。因此,如果您使用的是标准模式,请确保将其设置为 "200px" 而不仅仅是 200,否则您的画布将无法缩放。
【问题讨论】:
-
CSS 会更快。
-
我倾向于同意,但我没有证据。我想它是硬件加速的,就像 CSS 所做的一切一样。这可能也是我会坚持的方法。但是,我无法在网上找到任何速度比较或解释。我看到的三个主要选项是
ctx.drawImage、ctx.scale和 CSS 样式。我还没试过scale。到目前为止,我只使用 CSS,因为它看起来更干净,并且每帧需要减少 1 次对drawImage的调用。 -
似乎可以使用您可以创建和运行的测试来衡量...
-
@HereticMonkey,如果我找到答案,我会在这里发布或者其他人可能会。无论哪种方式,对于其他有此问题的人来说,它都会派上用场。就是这样。
标签: javascript html5-canvas scaling css-transforms drawimage