キャンバスで遊び中 - 任意の色を透明にしてコピー

getImageData & putImageData !
http://www.fujidig.com/misc/js/canvas/transparent-color-copy.html

var Color = function Color(r, g, b, a) {
	this.r = r & 255;
	this.g = g & 255;
	this.b = b & 255;
	this.a = a;
	if (typeof (this.a) == 'undefined') {
		this.a = 1;
	}
	if (this.a > 1) {
		this.a = 1;
	}
	if (this.a < 0) {
		this.a = 0;
	}
}

Color.prototype.toRGBAString = function toRGBAString() {
	return 'rgba('+this.r+','+this.g+','+this.b+','+this.a+')';
}

Color.prototype.toRGBString = function toRGBString() {
	return 'rgb('+this.r+','+this.g+','+this.b+')';
}

Color.prototype.toHexString = function toHexString() {
	return '#' + (0x1000000 | this.r << 16 | this.g << 8 | this.b).toString(16).slice(1);
}

Color.prototype.toString = function toString() {
	if (this.a == 1) {
		return this.toRGBString();
	} else {
		return this.toRGBAString();
	}
}

Color.parse = function parse(string) {
	var m;
	if (m = string.match(/^#([0-9a-f]{3}|[0-9a-f]{6})$/)) {
		if (m[1].length == 3) {
			var code = parseInt(m[1], 16);
			var r = code >> 8 & 15, g = code >> 4 & 15, b = code & 15;
			r |= r << 4, g |= g << 4, b |= b << 4;
			return new Color(r, g, b);
		}
		var code = parseInt(m[1], 16);
		return new Color(code >> 16 & 255, code >> 8 & 255, code & 255);
	}
	if (m = string.match(/^rgb\((\d+),(\d+),(\d+)\)$/)) {
		return new Color(parseInt(m[1], 10),
		                 parseInt(m[2], 10),
		                 parseInt(m[3], 10));
	}
	if (m = string.match(/^rgba\((\d+),(\d+),(\d+),(.*)\)$/)) {
		return new Color(parseInt(m[1], 10),
		                 parseInt(m[2], 10),
		                 parseInt(m[3], 10),
		                 parseFloat(m[4]));
	}
	return null;
}

function new_canvas_context(width, height) {
	var canvas = document.createElement('canvas');
	canvas.width = width;
	canvas.height = height;
	return canvas.getContext('2d');
}

function image_for_copy(src, color, sx, sy, width, height) {
	if (src instanceof Image) {
		var ctx = new_canvas_context(width, height);
		ctx.drawImage(src, 0, 0);
		src = ctx;
	}
	var image_data = src.getImageData(sx, sy, width, height);
	var pixels = image_data.data;
	var r = color.r, g = color.g, b = color.b;
	for (var i = 0, l = pixels.length; i < l; i += 4) {
		if (pixels[i] == r && pixels[i+1] == g && pixels[i+2] == b) {
			pixels[i+3] = 0;
		}
	}
	var dest = new_canvas_context(width, height);
	dest.putImageData(image_data, 0, 0);
	return dest.canvas;
}

function run() {
	ctx.drawImage(img_bg, 0, 0);
	var w = img_chara.width, h = img_chara.height;
	ctx.drawImage(image_for_copy(img_chara, new Color(0,128,128), 0, 0, w, h),
	              0, 0, w, h,
	              (canvas.width - w) / 2, (canvas.height - h) / 2, w, h);
}

var onload = function(){
	var count = 0;
	return function() {
		if (++count < 2) {
			return;
		}
		run();
	}
}();

var canvas = document.body.appendChild(document.createElement('canvas'));
canvas.width = 400, canvas.height = 300;
var ctx = canvas.getContext('2d');

var h2 = document.createElement('h2');
h2.appendChild(document.createTextNode('source images'));
document.body.appendChild(h2);

var img_bg = new Image;
img_bg.src = 'sample_bg.png'
img_bg.onload = onload;
document.body.appendChild(img_bg);

var img_chara = new Image;
img_chara.src = 'sample_chara.png';
img_chara.onload = onload;
document.body.appendChild(img_chara);