繁体   English   中英

HTML5 Canvas - 在屏幕上显示像素颜色数组的最快方法

[英]HTML5 Canvas - Fastest way to display an array of pixel colors on the screen

如果有40x30的颜色阵列,那么在400x300画布上以最快的方式在屏幕上显示它们会是什么? 也就是说,每种颜色在画布元素中需要100个像素。

使用HTML5中的canvas元素,我创建了4种可能的方法。 http://jsperf.com/pixel-plotting

随机像素数据被加载到40x30阵列中。 然后将其显示在尺寸为400x300的画布中,使得每个逻辑像素在屏幕上由100个像素表示。

最快的方法(使用Chrome 38.0)是在隐藏的画布中创建图像数据,并使用toDataURL将其复制到屏幕上显示的画布中。 属性imageSmoothingEnabled设置为false,以在像素向上缩放时停止像素模糊。

有没有其他方法这样做? 我尝试使用小的画布尺寸,只是在CSS中缩放它,但这导致像素模糊。

我想知道测试在其他网络浏览器中的表现; 尤其是手机。

将像素数据绘制到屏幕上是非常重要的,因为它需要每秒至少发生30次,所以即使是小的调整也可以提高效率。

这是我测试的四种方式的代码。

方法1

var png = document.createElement("img");
var c2 = document.getElementById("myCanvas");
var ctx2 = c2.getContext("2d");

var c1 = document.createElement("canvas");
c1.width = 40;
c1.height = 30;
var ctx1 = c1.getContext("2d");

var imgData = ctx1.createImageData(40, 30);
for (var i=0; i<imgData.data.length; i+=4) {
var x = (i/4)%40;
    var y = Math.floor(i/160);
    imgData.data[i] = pixelData1[x][y].r;
    imgData.data[i+1] = pixelData1[x][y].g;
    imgData.data[i+2] = pixelData1[x][y].b;
    imgData.data[i+3] = 255;
}
ctx1.putImageData(imgData, 0, 0);

png.src = c1.toDataURL("image/png");

c2.width = 400;
c2.height = 300;

ctx2.imageSmoothingEnabled = false;
ctx2.drawImage(png, 0, 0, 400, 300);

方法2

var c = document.getElementById("myCanvas");
c.width = 400;
c.height = 300;
var ctx = c.getContext("2d");

var imgData = ctx.createImageData(400, 300);
for (var i=0; i<imgData.data.length; i+=4) {
    var x = Math.floor(((i/4)%400)/10);
    var y = Math.floor(i/16000);
    imgData.data[i] = pixelData1[x][y].r;
    imgData.data[i+1] = pixelData1[x][y].g;
    imgData.data[i+2] = pixelData1[x][y].b;
    imgData.data[i+3] = 255;
}
ctx.putImageData(imgData, 0, 0);

方法3

var png = document.createElement("img");
var c2 = document.getElementById("myCanvas");
var ctx2 = c2.getContext("2d");

var c1 = document.createElement("canvas");
c1.width = 40;
c1.height = 30;
var ctx1 = c1.getContext("2d");

for (var x = 0; x < 40; x++) {
    for (var y = 0; y < 30; y++) {
        ctx1.fillStyle = pixelData2[x][y];
        ctx1.fillRect(x, y, 1, 1);
    }
}

png.src = c1.toDataURL("image/png");

c2.width = 400;
c2.height = 300;

ctx2.imageSmoothingEnabled = false;
ctx2.drawImage(png, 0, 0, 400, 300);

方法4

var c = document.getElementById("myCanvas");
c.width = 400;
c.height = 300;
var ctx = c.getContext("2d");

for (var x=0; x<40; x++) {
    for (var y=0; y<30; y++) {
        ctx.fillStyle = pixelData2[x][y];
        ctx.fillRect(x*10, y*10, 10, 10);
    }
}

感谢评论中的回复。 根据Ken Frystenberg的评论我更新了jsperf上的测试: http ://jsperf.com/pixel-plotting/5

似乎最快的方法是编辑屏幕上不可见的画布的图像数据。 然后,在第二个画布的上下文中,将属性imageSmoothingEnabled设置为false。 最后调用drawImage将第一个画布作为图像的源传递。

为了在大多数浏览器中支持此方法,将相应的前缀添加到画布上下文的imageSmoothingEnabled属性中。

这是最终的代码:

var c2 = document.getElementById("myCanvas");
var ctx2 = c2.getContext("2d");

var c1 = document.createElement("canvas");
c1.width = 40;
c1.height = 30;
var ctx1 = c1.getContext("2d");

var imgData = ctx1.createImageData(40, 30);
for (var i=0; i<imgData.data.length; i+=4) {
    var x = (i/4)%40; 
    var y = Math.floor(i/160); 
    imgData.data[i] = pixelData1[x][y].r; 
    imgData.data[i+1] = pixelData1[x][y].g; 
    imgData.data[i+2] = pixelData1[x][y].b; 
    imgData.data[i+3] = 255; 
}
ctx1.putImageData(imgData, 0, 0);

c2.width = 400;
c2.height = 300;

ctx2.mozImageSmoothingEnabled = false;
ctx2.webkitImageSmoothingEnabled = false;
ctx2.msImageSmoothingEnabled = false;
ctx2.imageSmoothingEnabled = false;
ctx2.drawImage(c1, 0, 0, 400, 300);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM