HTML5 – Canvas: Vẽ ảnh và thao tác với pixel

Canvas 2D API - ImageData- RGBAMuốn tạo ra những hiệu ứng đồ họa đặc biệt khi sử dụng canvas, bạn không thể chỉ sử dụng cá thuộc tính và phương thức có sẵn của đối tượng context. Chính vì vậy, bài viết này sẽ giới thiệu cho bạn cách vẽ ảnh và thao tác với các pixel từ đối tượng ImageData.

Nạp và vẽ ảnh

Để vẽ một ảnh ra canvas, ta tạo một đối tượng image và thực hiện phương thức context.drawImage() trong sự kiện load của image. Như vậy để đảm bảo rằng hình ảnh chỉ được vẽ sau khi đã được nạp hoàn tất. Ngoài ra, bạn nên đặt sự kiện load trước khi gán đường dẫn cho ảnh. Nếu không image có thể được load xong trước khi bạn gắn sự kiện load cho nó.

Phương thức drawImage() có ba overload sau:

– Vẽ image tại một vị trí destX, destY:

context.drawImage(image,destX,destY);

– Vẽ image tại vị trí destX, destY và kích thước destWidth, destHeight:

context.drawImage(image,destX,destY,destWidth,destHeight);

– Cắt image tại vị trí [sourceX, sourceY, sourceWidth, sourceHeight] và vẽ tại [destX, destY, destWidth, destHeight]:

context.drawImage(image, sourceX, sourceY, sourceWidth,

sourceHeight, destX, destY, destWidth, destHeight);

Ví dụ:

window.onload = function(){

	var canvas = document.getElementById("mycanvas");
	var context = canvas.getContext("2d");

	var img = new Image();

	img.onload = function(){
		context.drawImage(img, 10, 10,50,50);
	};
	img.src = "foo.png";
};

Thao tác với pixel

Một ảnh bao gồm một mảng các pixel với các giá trị red, green, blue và alpha (RGBA). Trong đó alpha là giá trị xác định độ mờ đục (opacity) của ảnh. Giá trị alpha càng lớn thì độ màu sắc càng rõ nét và màu sắc sẽ trở nên trong suốt nếu alpha là 0.

Trong Canvas 2D API, dữ liệu ảnh được lưu trong một đối tượng ImageData với 3 thuộc tính là width, height và data. Trong đó data là một mảng một chiều chứa các pixel. Mỗi pixel chứa 4 phần tử tương ứng là R,G,B,A.

Như vậy với một ảnh có kích thước 10×20 ta sẽ có 200 pixel và có 200*4=400 phần tử trong mảng ImageData.data.

Canvas 2D API - ImageData- RGBA

Bạn có thể tham khảo thông tin về các API này tại: http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#pixel-manipulation:

 

imagedata = context.createImageData(sw, sh)

Trả về một đối tượng ImageData với kích thước sw x sh. Tất cả pixel của đối tượng này có màu đen trong suốt.

imagedata = context.createImageData(imagedata)

Trả về đối tượng ImageData với kích thước bằng với đối tượng trong tham số. Tất cả pixel có màu đen trong suốt.

imagedata = context.getImageData(sx, sy, sw, sh)

Trả về một đối tượng ImageData chứa dữ liệu ảnh vùng chữ nhật (xác định bởi các tham số) của canvas.

Ném NotSupportedError exception nếu như có bất kì tham số nào không phải là số hợp lệ. Ném IndexSizeError exception nếu width hoặc height là zero.

imagedata.width

imagedata.height

Trả về kích thước thật của đối tượng ImageData, tính theo pixel.

imagedata.data

Trả về mảng một chiều chứa dữ liệu dạng RGBA, mỗi giá trị nằm trong khoảng 0 đến 255.

context . putImageData(imagedata, dx, dy [, dirtyX, dirtyY, dirtyWidth, dirtyHeight ])

Vẽ dữ liệu từ đối tượng ImageData lên canvas tại vị trí dx, dy.  Nếu như hình chữ nhật (từ các tham số dirtyX, dirtyY, dirtWidth, dirtyHeight) được xác định, thì phần dữ liệu của ImageData trong vùng chữ nhật này mới được vẽ lên canvas.

HTML5 - Canvas - PutImageData Method

Các thuộc tính xác định hiệu ứng vẽ của context sẽ bị bỏ qua khi phương thức này được gọi. Các pixel từ canvas sẽ được thay thế hoàn toàn bởi ImageData mà không có các sự kết hợp màu sắc, hiệu ứng, … với các dữ liệu ảnh sẵn có trên canvas.

Một trong những ví dụ  thường gặp và đơn giản nhất là đảo ngược màu của ảnh. Điều này được thực hiện bằng cách lấy giá trị màu tối đa (255) trừ đi giá trị của mỗi kênh màu RGB hiện tại của mỗi pixel. Giá trị alpha sẽ để giá trị tối đa để ảnh được rõ nét nhất.

<html>
<head>
<script>
	window.onload = function(){

		var img = new Image();
		img.onload = function(){
			invertColor(this);
		};
		img.src="panda.jpg";
	};
	function invertColor(img){
		var canvas = document.getElementById("mycanvas");
		var context = canvas.getContext("2d");

		// draw image at top-left corner
		context.drawImage(img,0,0);
		// draw original image right beside the previous image
		context.drawImage(img,img.width,0);

		// get ImageData object from the left image
		var imageData = context.getImageData(0, 0, img.width, img.height);
		var data = imageData.data;

		for (var i = 0; i < data.length; i += 4) {

			data[i]		=	255 - data[i]; // red
			data[i + 1]	=	255 - data[i+1]; // green
			data[i + 2]	=	255 - data[i+2]; // blue
			data[i + 3]	=	255; // alpha
		}

		context.putImageData(imageData,0,0);

	}
</script>
</head>
<body>
   <canvas id="mycanvas" width="600" height="250"></canvas>
</body>
</html>

Kết quả:

Html5 - Canvas - Invert Color

Bạn có thể thêm các tham số để tạo một “dirty rectangle” trong phương thức putImageData() nếu muốn vẽ ImageData lên một vùng chữ nhật xác định của canvas.

Ví dụ tôi chọn cùng một vùng chữ nhật trên ImageData và vẽ lên hai vùng chữ nhật khác nhau trên canvas để được kết quả sau:

context.putImageData(imageData,0,0,0,0,img.width/2,img.height/2);
context.putImageData(imageData,img.width,0,0,0,img.width/2,img.height/2);

HTML 5 - Canvas - PutImageData Example
YinYang’s Programming Blog

2 thoughts on “HTML5 – Canvas: Vẽ ảnh và thao tác với pixel

Gửi phản hồi

Mời bạn điền thông tin vào ô dưới đây hoặc kích vào một biểu tượng để đăng nhập:

WordPress.com Logo

Bạn đang bình luận bằng tài khoản WordPress.com Log Out / Thay đổi )

Twitter picture

Bạn đang bình luận bằng tài khoản Twitter Log Out / Thay đổi )

Facebook photo

Bạn đang bình luận bằng tài khoản Facebook Log Out / Thay đổi )

Google+ photo

Bạn đang bình luận bằng tài khoản Google+ Log Out / Thay đổi )

Connecting to %s