iT邦幫忙

2022 iThome 鐵人賽

DAY 5
0
Modern Web

從新開始學習p5.js畫出一片天系列 第 5

D05_Canvas的圖像畫素

  • 分享至 

  • xImage
  •  

DOM的Canvas與p5.js的Canvas的畫素操作

今天來整理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


上一篇
D04_Canvas的圖像核心
下一篇
D06_Canvas的全螢幕,儲存,上傳
系列文
從新開始學習p5.js畫出一片天40
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言