CSS缩放比drawImage缩放更有效吗?

问题描述 投票:0回答:1

我想知道用drawImage和CSS缩放之间的区别是什么。我都尝试过,而CSS似乎给出了更平滑的结果,而drawImage往往会有些失真-尤其是当我平移图像时,在几个动画帧的过程中,从不同的源x和y发出斑点。我在许多不同的比例因子下进行测试后得出了这个结论。我在下面有一个简单的例子。

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的不同区域中冒出来。我只将整数上交到drawImage,以使内容尽可能清晰。我也有image-rendering:pixelated和CSS画布上定义的其他变量,用于CSS缩放以使情况保持清晰。

我知道我的具体示例,我可以将img放大一次,然后平移到最终缩放的img,但这不是问题。问题是哪个表现更好。对于我的应用程序,我必须在每个帧上按比例放大一个动画图块地图,因此我要从多个来源向1:1空间中的画布进行缩放,然后使用requestAnimationFrame将最终的画布每秒缩放30至60次。

最后,他们给出了非常相似的结果。 CSS仅比原始图像更清晰明了。 CSS更快/更有效吗?还是用drawImage缩放更有效?

注意/编辑:

[我发现,如果我在<!DOCTYPE html>中使用标准模式,则必须将字符串值传递给CSS方法的style.widthstyle.height。因此,如果您使用标准模式,请确保将其设置为"200px"而不是仅设置为200,否则您的画布将无法缩放。

javascript html5-canvas scaling css-transforms drawimage
1个回答
1
投票

画布Alpha有所作为

为了获得最佳结果,应使画布尺寸与其分辨率相同。如果画布上没有任何透明像素,则应关闭Alpha。

使用const ctx = canvas.getContext("2d",{alpha: false})关闭画布Alpha

缩放无关紧要

[对于大多数设备,缩放不比绘制未缩放图像更昂贵。

渲染成本下降到绘制的像素数,而不是源中的像素数。

估计渲染成本

drawImage的费用

如果画布分辨率为200 x 200,并且您绘制的图像ctx.drawImage填充为需要渲染的40,000像素。

合成成本

如果该画布通过CSS规则缩放,即使alpha处于禁用状态,也必须将canvas元素合成才能显示。成本将是画布大小占用的像素数。

如果画布的alpha为true,则必须将其与背景合成,因此渲染成本为画布的显示尺寸(以像素为单位。)>

[如果画布大小(CSS)与分辨率匹配,并且alpha处于关闭状态,则不需要为最终呈现而将画布进行合成,并且没有额外的合成成本。

渲染成本示例
  • [canvas是可见的画布元素

  • image是可以放入GPU RAM的图像
  • 最好关闭alpha并且没有CSS缩放

    canvas.width = canvas.height = 100;
    canvas.style.width = canvas.style.height = "100px";
    const ctx = canvas.getContext("2d", {alpha: false});
    ctx.drawImage(image, 100, 100);
    
    // Total rendering cost 100 * 100 = 10,000 pixels
    

    通过CSS缩放并关闭alpha

    canvas.width = canvas.height = 200;
    canvas.style.width = canvas.style.height = "100px";
    const ctx = canvas.getContext("2d", {alpha: false});
    ctx.drawImage(image, 200, 200);
    
    // Total rendering cost 200 * 200 + 100 * 100 = 50,000 pixels
    

    启用alpha渲染,没有CSS缩放

    canvas.width = canvas.height = 100;
    canvas.style.width = canvas.style.height = "100px";
    const ctx = canvas.getContext("2d");  // alpha is on
    // same as const ctx = canvas.getContext("2d", {alpha: true});
    ctx.drawImage(image, 100, 100);
    
    // Total rendering cost 100 * 100 + 100 * 100 = 20,000 pixels
    

    注释

    • 由于页面设置,滚动和各种其他因素,不可避免的渲染成本。由于无法避免,因此忽略了这些成本。
    • 可能无法在所有浏览器上都使用打开字母转换选项。
    • 软件渲染和设备功能将对渲染性能产生最大的影响。
    © www.soinside.com 2019 - 2024. All rights reserved.