用于在Canvas上的X,Y坐标处绘制像素的公式

时间:2012-12-01 06:17:07

标签: html5 canvas 2d

所以我知道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是2D数组,如下所示:

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

即。它精确映射到2D笛卡尔平面。

所以现在我稍微改变了一点,我有一个FLATTENED对象数组xycolor

[{ 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);

但它出现了一点错误。我已经三次检查我的测试,实际的数组是正确的屏幕数据。我只是错误地渲染它。我现在正在接受这个:

enter image description here

我应该看到:

enter image description here

现在我在Swing版本(几年前)之前已经有了完全相同的图形怪异,这是因为我绘制图像的方式。我不记得我是怎么修的。

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

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

能够使用颜色在x,y处绘制特定像素。或者......传统上这样做的方式。

2 个答案:

答案 0 :(得分: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 - 从左到右)

答案 1 :(得分: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/