use*_*307 4 html javascript canvas pixel draw
给定一个 40x30 的颜色数组,在 400x300 画布的屏幕上显示它们的最快方法是什么?也就是说,每种颜色在画布元素中都需要 100 个像素。
在 HTML5 中使用 canvas 元素我创建了 4 种可能的方法来做到这一点。http://jsperf.com/pixel-plotting
随机像素数据加载到 40x30 数组中。然后将其显示在大小为 400x300 的画布中,以便每个逻辑像素在屏幕上由 100 个像素表示。
最快的方法(使用 Chrome 38.0)是在隐藏的画布中创建图像数据,并使用 toDataURL 将其复制到屏幕上显示的画布中。属性 imageSmoothingEnabled 设置为 false 以在向上缩放时停止像素模糊。
有没有其他方法可以做到这一点?我尝试使用较小的画布尺寸并在 CSS 中将其放大,但这导致像素模糊。
我想知道测试在其他网络浏览器中的表现如何;尤其是手机的。
将像素数据绘制到屏幕上非常重要,因为它需要每秒发生至少 30 次,因此即使是一个小的调整也可以大大提高效率。
这是我测试的四种方式的代码。
方法一
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);
Run Code Online (Sandbox Code Playgroud)
方法二
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);
Run Code Online (Sandbox Code Playgroud)
方法三
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);
Run Code Online (Sandbox Code Playgroud)
方法四
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);
}
}
Run Code Online (Sandbox Code Playgroud)
感谢评论中的回复。从 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);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3591 次 |
| 最近记录: |