1

所以我知道 HTML5 画布像素方法与正常情况略有不同。我正在从 Scala Swing 应用程序中移植一个光线追踪器,其中旧的绘制方法如下所示:

for {
  x <- pixels.s.indices
  y <- pixels.s(x).indices
} {
  g.setColor(pixels.s(x)(y))
  g.fillRect(x, y, x, y)
}

pixels.s像这样的二维数组在哪里:

[[Color, Color, Color], 
 [Color, Color, Color], 
 [Color, Color, Color]]

即它精确地映射到二维笛卡尔平面。

所以现在我稍微改变了策略,我有一个 FLATTENED 对象数组,其中x,ycolor:

[{ x: 0, y: 0, color: { red: 33, green: 220, blue: 181 },
 { x: 0, y: 1, color: { red: 33, green: 220, blue: 231 },
 { x: 0, y: 2, color: { red: 33, green: 220, blue: 221 },
 ...
 { x: 319, y: 238, color: { red: 23, green: 10, blue: 31 },
 { x: 319, y: 239, color: { red: 13, green: 120, blue: 11 }]

我正在尝试使用以下代码将扁平的颜色数组绘制到屏幕上:

var imageData = context.createImageData(width, height);
var numPixels = width*height;
for (var i = 0; i < numPixels; i++) {
  imageData.data[(i*4)]     = tracedScene[i].color.red;
  imageData.data[(i*4) + 1] = tracedScene[i].color.green;
  imageData.data[(i*4) + 2] = tracedScene[i].color.blue;
  imageData.data[(i*4) + 3] = 255; // alpha  color
};
context.putImageData(imageData, 0, 0);

但结果有点不对劲。我已经检查了三倍的测试,实际数组是正确的屏幕数据。我只是渲染不正确。我目前得到这个:

在此处输入图像描述

而我应该看到:

在此处输入图像描述

现在(几年前)我在 Swing 版本中也有完全相同的图形异常,这是因为我绘制图像的方式。我不记得我是如何修复它的。

我希望能够做的是有一些方法:

drawPixel(x, y, color, canvas) { ... } 

能够在 x, y 处用颜色绘制特定像素。或者......一种传统的方式。

4

2 回答 2

1

您输入的“扁平化”数组的顺序错误:它应该按行排列,但您的是按列排列。

[{ x: 0, y: 0, color: { red: 33, green: 220, blue: 181 },
 { x: 1, y: 0, color: { red: 33, green: 220, blue: 231 },
 { x: 2, y: 0, color: { red: 33, green: 220, blue: 221 },
 ...

(假设 y 是从上到下,x - 从左到右)

于 2012-12-01T06:27:01.950 回答
1

图像数据从(0, 0)(1, 0),您的代码从(0, 0)(0, 1)。换句话说,存在行/列主要顺序的冲突。

无论如何,根据您的性能需求,您可能会想太多。

我希望能够做的是有一些方法:

drawPixel(x, y, color, canvas) { ... }

能够在 x, y 处用颜色绘制特定像素。

为什么不只填充单个像素?

ctx.fillStyle = 'rgba(red, green, blue, alpha)';
ctx.fillRect(x, y, 1, 1);

这将在填充大约 100 个像素时效率低下,并且您需要切换到图像数据。

如果你想保持你的数据结构相同,你可以使用这样的东西,它应该可以工作:

var imageData = context.createImageData(width, height);
var numPixels = width*height;
var pixelCount = 0;
for (var i = 0; i < width; i++) {
    for (var j = 0; j < height; j++) {
        var wpixel = j * width * 4;
        wpixel += i * 4;
        console.log(wpixel);
        imageData.data[(wpixel)]     = tracedScene[pixelCount].red;
        imageData.data[(wpixel) + 1] = tracedScene[pixelCount].green;
        imageData.data[(wpixel) + 2] = tracedScene[pixelCount].blue;
        imageData.data[(wpixel) + 3] = 255; // alpha  color
        pixelCount++; // independent of i and j the way I wrote it
    }
}
context.putImageData(imageData, 0, 0);

演示:http: //jsfiddle.net/t9edv/

于 2012-12-01T06:28:51.903 回答