今天來整理Canvas的畫素操作指令
DOM 關於pixel的操作
let can;
let ctx;
function setup() {
can = createCanvas(400, 500);
can.id("can1");
can.position(100, 100);
ctx = can.elt.getContext("2d");
console.log(ctx);
background(0);
//-----------------------------
let img = createImg(
"assets/asterisk-01.png",
"the p5 magenta asterisk", "", img1 => {
//-- 使用callback來確保圖檔都載入後才執行接下來的指令
ctx.drawImage(img1.elt, 50, 430, 50, 50);
ctx.drawImage(img.elt, 50, 50);
//-- 取得 在座標(0, 0)的位置,寬高各為200區域的圖像
let imgData1 = ctx.getImageData(0, 0, 200, 200);
ctx.putImageData(imgData1, 50, 200);
//-- 將影像資料繪入canvas中,座標(100, 100)
ctx.putImageData(imgData, 100, 100);
}
);
img.id("img1");
img.position(50, 200);
img.hide();
//-- 建立一個空的影像資料物件 ImageData object 尺寸 100x100
//-- imgData.data.length的陣列資料長度 w x h x 4 = 100x100x4
//-- imgData.data 為影像畫素陣列資料
let imgData = ctx.createImageData(100, 100);
for (let i = 0; i < imgData.data.length; i += 4) {
imgData.data[i + 0] = 255;
imgData.data[i + 1] = 255;
imgData.data[i + 2] = 0;
imgData.data[i + 3] = 20;
}
console.log(imgData.data.length);
}
每個圖像的畫素包括R,G,B,A等4個數值,在資料陣列的儲存上,一個畫素pixel就會用掉4個陣列的元素,
一張 100 x 100 的圖像,就會用到 100 x 100 x 4個陣列的元素
也就是 影像資料陣列的長度為 imgData.data.length = w x h x 4
影像資料陣列的index位置與圖像x, y座標關係如下
index = (y * w + x) * 4;
Red -> index+0
Green -> index+1
Blue -> index+2
Alpha -> index+3
//-- 畫素指令整理
let imgData = ctx.createImageData(w, h);
let imgData1 = ctx.getImageData(x, y, w, h);
putImageData(imgData1, x, y);
imgData.data[index]
由 ctx.putImageData(imgData, x, y) 繪入到canvas中,
是將canvas區域中的畫素資料代換成新的畫素資料,
而不是疊上去的概念,因此,在 imgData.data[i + 3] = 20; 設定成有alpha的顏色,
是將該畫素代換成有alpha的顏色,而不是疊上alpha的顏色。
p5.js 關於pixel的操作
let can;
let ctx;
function setup() {
can = createCanvas(400, 500);
can.id("can1");
can.position(100, 100);
background(0);
//-----------------------------
let img = loadImage(
"assets/asterisk-01.png", img1 => {
//-- 使用callback來確保圖檔都載入後才執行接下來的指令
image(img1, 50, 430, 50, 50);
image(img, 50, 50);
//-- 取得 在座標(0, 0)的位置,寬高各為200區域的圖像
let imgData1 = get(0, 0, 200, 200);
image(imgData1, 50, 200);
//-- 將影像資料繪入canvas中,座標(100, 100)
image(imgData, 100, 100);
}
);
//-- 利用 createImage(100, 100) 建立一個空的影像資料物件,尺寸 100x100
let imgData = createImage(100, 100);
for (let i = 0; i < 100; i++) {
for (let j = 0; j < 100; j++) {
//-- 設定座標(i, j)的顏色
imgData.set(i, j, color(255, 255, 0, 20));
}
}
imgData.updatePixels();
image(imgData, 100, 100);
}
使用image()指令繪製到canvas,才會有疊層的效果。
取得影像畫素陣列
img.loadPixels();
img.pixels[]
let imgData = createImage(100, 100);
imgData.loadPixels();
for (let i = 0; i < imgData.pixels.length; i += 4) {
imgData.pixels[i] = 255;
imgData.pixels[i + 1] = 255;
imgData.pixels[i + 2] = 0;
imgData.pixels[i + 3] = 50;
}
imgData.updatePixels();
image(imgData, 100, 100);
執行結果
p5.js Reference get(), set()
https://p5js.org/reference/#/p5/get
https://p5js.org/reference/#/p5/set
HTML canvas ImageData data Property
https://www.w3schools.com/tags/canvas_imagedata_data.asp