HTML5 Canvas - 如何从线性化图像数据Uint8ClampedArray中获取相邻像素的位置?

HTML5 Canvas  - 如何从线性化图像数据Uint8ClampedArray中获取相邻像素的位置?

问题描述:

线性化图像数据阵列中的5 x 5像素图像数据是这样的 -

A 5 by 5 pixel image data is something like this in linearized imagedata array-

[0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,240,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0,0,0,0,240, 0,0,0,255 ,0,0, 0,240,0,0,0,0,0,0,0,0,0,0,0,0,0,0,240,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, 0, 0, 0, 255, 0, 0, 0, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

因此,3x3像素数据为-0 0 0 255.如何获得相邻的像素位置?左右相邻的很容易,分别只有4和4加。

So, the 3x3 pixel data is- 0 0 0 255. How can I get the adjacent pixel positions? Left and right adjacent ones are easy, just minus 4 and plus 4 respectively.

访问像素数据



来自 .getImageData()。data TypedArray Uint8ClampedArray 。读取值时,它们将在0-255范围内,顺序为红色,绿色,蓝色,Alpha。如果alpha的值为零,那么红色,绿色和蓝色也将为零。

Accessing pixel data

The pixel data from .getImageData().data is a TypedArray of type Uint8ClampedArray. When reading the values they will be in the range 0-255 and in the order Red, Green, Blue, Alpha. If the value of alpha is zero then red, green, and blue will also be zero.

获取像素的索引

const imageData = ctx.getImageData(0,0,ctx.canvas.width, ctx.canvas.height);
var index = (x + y * imageData.width) * 4;
const red   = imageData.data[index];
const green = imageData.data[index + 1];
const blue  = imageData.data[index + 2];
const alpha = imageData.data[index + 3];

向下移动一个像素

index += imageData.width * 4;

向上移动

index -= imageData.width * 4;

向左移动。

index -= 4;

向右移动

index += 4;

如果您在左边缘或右边缘并沿边缘方向移动,则将包裹如果向左移动,则在上方和右方的线上,如果向下移动则向下和向左移动。

If you are on the left or right edge and you move in the direction of the edge you will wrap around, on the line above and to the right if moving left and the line below and on the left if moving down.

设置图像数据时,值将被移动并限制为0-255

When setting the image data the values will be floored and clamped to 0-255

 imageData.data[index] = 29.5
 console.log(imageData.data[index]); // 29

 imageData.data[index] = -283
 console.log(imageData.data[index]); // 0

 imageData.data[index] = 283
 console.log(imageData.data[index]); // 255

如果设置一个超出数组大小的索引,它将被忽略

If you set an index that is outside the array size it will be ignored

 imageData.data[-100] = 255;
 console.log(imageData.data[-100]); // Undefined
 imageData.data[imageData.data.length + 4] = 255;
 console.log(imageData.data[imageData.data.length + 4]); // Undefined

您可以使用不同的数组类型加快访问和处理速度。例如,使用 Uint32Array

You can speed up access and processing by using different array types. For example all of a pixel's channels as one value using Uint32Array

const imageData = ctx.getImageData(0,0,ctx.canvas.width, ctx.canvas.height);
const pixels = new Uint32Array(imageData.data.buffer);
var index32 = x + y * imageData.width;  // note there is no 4*;

const pixel = pixels[index32];

频道存储在31-24 Alpha,23-16 Blue,15-8 Green, 7-0红色。

The channels are stored in bits 31-24 Alpha, 23-16 Blue, 15-8 Green, 7-0 Red.

您可以使用十六进制值设置像素

You can set a pixel using a hex value

 pixels[x + y * imageData.width] = 0xFF0000FF;  // red 
 pixels[x + y * imageData.width] = 0xFF00FF00;  // Green 
 pixels[x + y * imageData.width] = 0xFFFF0000;  // Blue 
 pixels[x + y * imageData.width] = 0xFF000000;  // Black 
 pixels[x + y * imageData.width] = 0xFFFFFFFF;  // White
 pixels[x + y * imageData.width] = 0;  // Transparent

您可以在一次通话中设置所有像素

You can set all the pixels in a single call

 pixels.fill(0xFF000000); // all pixels black

您可以使用

 // set 3 pixels in a row at x,y Red, Yellow, White
 pixels.set([0xFF0000FF,0xFF00FFFF,0xFFFFFFFF], x+y * imageData.width);



警告



如果画布有任何像素/来自不受信任的来源,它将被污染,你将无法读取像素数据。可信源是使用适当的CORS头信息提供的相同域或图像。文件系统上的图像无法访问其像素。一旦帆布被污染,就无法清洁。

Warning

If the canvas has any pixel/s that are from an untrusted source it will be tainted and you will not be able to read the pixel data. Trusted sources are same domain or images served with the appropriate CORS header information. Images that are on the file system can not have their pixels accessed. Once a canvas is tainted it can not be cleaned.

当你调用 ctx.getImageData(0,0,1,1,)时,受污染的画布会抛出错误> MDN由于某种原因未列出此异常。您将看到SecurityErrorDOMException;在DevTools控制台中,StackOverflow中有很多回答问题。

A tainted canvas will throw an error when you call ctx.getImageData(0,0,1,1,) MDN does not list this exception for some reason. You will see "SecurityError" DOMException; in the DevTools console and there are plenty of answered question here in StackOverflow on the subject.