2017-08-30 16 views
1

5×5像素圖像數據在線性化圖像數據陣列中是類似的東西 -HTML5畫布 - 如何從線性化圖像數據獲取相鄰像素位置Uint8ClampedArray?

[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]

因此,3x3像素數據是 - 0 0 0 255.我怎樣才能得到相鄰的像素位置?左側和右側相鄰的很容易,分別只有4和4。

+0

你需要知道圖像的尺寸,那麼它也很容易 - 分別只有4 *尺寸和4 *尺寸。 – Bergi

+0

@Bergi是的,圖像尺寸很容易通過image.width和image.height檢索,因爲我使用Image()構造函數。 – yemon

回答

2

訪問像素數據

中的像素數據從.getImageData().dataUint8ClampedArray類型的TypedArray。讀取值時,它們的範圍是0-255,順序爲紅色,綠色,藍色,阿爾法。如果alpha的值爲零,那麼紅色,綠色和藍色也將爲零。

爲了得到一個像素

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; 

如果在左側或右邊緣與您在邊緣的方向上移動,如果移動你將環繞,在上方和右側的線如果向下移動,則左側和下方的線以及左側的線。

當設定值將地板和鉗位到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 

的圖像數據如果設置索引是數組大小會被忽略外

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

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阿爾法,23-16藍,綠15-8,7-0紅色。

可以使用一個十六進制值

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 
設置的像素

可以設置的所有像素中的單個呼叫

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頭信息一起提供的相同的域或圖像。文件系統上的圖像不能訪問其像素。一旦畫布被污染,它不能被清理。

當您致電ctx.getImageData(0,0,1,1,) MDN由於某種原因未列出此異常時,受污染的畫布將引發錯誤。你會看到「SecurityError」DOMException;在DevTools控制檯中,在StackOverflow中有很多關於該主題的回答問題。

+0

是的,所以相鄰像素是:index - imageData.width * 4 - 4,index - imageData.width * 4,index - imageData.width * 4 + 4,index - 4,index + 4,index + imageData.width * 4 - 4,索引+ imageData.width * 4,索引+ imageData.width * 4 + 4.謝謝! – yemon

2

你可以與基質的寬度和4一個單元的長度計算的索引。

的訪問是從零開始的。

function getPos(array, x, y, width) { 
 
    var p = 4 * (x + y * width); 
 
    return array.slice(p, p + 4); 
 
} 
 

 
var 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, 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, 241, 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 
 
    ]; 
 

 
// element above 
 
console.log(JSON.stringify(getPos(array, 2, 1, 5))); // [0, 0, 0, 240] 
 

 
// actual element 
 
console.log(JSON.stringify(getPos(array, 2, 2, 5))); // [0, 0, 0, 255] 
 

 
// element below 
 
console.log(JSON.stringify(getPos(array, 2, 3, 5))); // [0, 0, 0, 241]

+0

對角線不相鄰? – bluehipy

+0

只是座標,然後你得到的價值。 –

+0

感謝@NinaScholz這是一種很好的方式來訪問像矩陣像素的方式。 – yemon