もどる TOP

[Canvas] RGBチャンネル指定して色の位置をずらす加工

 タイトルわかりにく!! グリッチっぽいあれです。ソースコードは一番下♪

元の画像
サンプル1: 赤を→2
サンプル2: 緑を←2, ↑2
サンプル3: 青を←4, ↓3

 書くほどではないですが、処理の流れは次の通りです。

  1. 全ピクセル (ImageData.data) をスキャンして、各座標の指定チャンネルの値を取得したあと、現在の値をゼロにします。
  2. ふたたび全ピクセルをスキャンして、移動先座標の指定チャンネルに、取得しておいた値を加算します。

 移動先座標を算出するので、2回目のスキャンはxyでやっています。xyは(y * 幅 + x) * 4ImageData.dataのインデックスに変換します。

JavaScript
/**
 * 指定チャンネルの描画位置をずらす
 * @param canvas Canvas要素
 * @param channel 0: 赤, 1: 緑, 2: 青
 * @param shiftX 右方向移動量 (px)
 * @param shiftY 下方向移動量 (px)
 */
function shiftRGB(canvas, channel, shiftX, shiftY) {
	var ctx = canvas.getContext('2d');
	var w = canvas.width;
	var h = canvas.height;
	var tmp = [];
	var imageData = ctx.getImageData(0, 0, w, h);
	for (var i = 0, len = imageData.data.length; i < len; i += 4) {
		tmp[i] = imageData.data[i + channel];
		imageData.data[i + channel] = 0;
	}
	for (var y = 0; y < h; ++y) {
		for (var x = 0; x < w; ++x) {
			var dstX = x + shiftX;
			var dstY = y + shiftY;
			if (0 <= dstX && dstX < w && 0 <= dstY && dstY < h) {
				var i = (y * w + x) * 4;
				var dstI = (dstY * w + dstX) * 4;
				imageData.data[dstI + channel] = imageData.data[dstI + channel] + tmp[i];
			}
		}
	}
	ctx.putImageData(imageData, 0, 0);
}


/* 以下このページでの使用例 */
window.addEventListener('load', function() {
	var sample1 = loadOrg(document.getElementById('rgb-channel-shifting_sample-1')); // サンプル描画先canvasのid
	var sample2 = loadOrg(document.getElementById('rgb-channel-shifting_sample-2'));
	var sample3 = loadOrg(document.getElementById('rgb-channel-shifting_sample-3'));
	
	// サンプル1: 赤を→2
	shiftRGB(sample1, 0, 2, 0); 
	
	// サンプル2: 緑を←2, ↑2
	shiftRGB(sample2, 1, -2, -2); 
	
	// サンプル3: 青を←4, ↓3
	shiftRGB(sample3, 2, -4, 3);
});

function loadOrg(canvas) {
	var org = document.getElementById('rgb-channel-shifting_sample-org'); // 元画像要素のid
	canvas.width = org.width;
	canvas.height = org.height;
	var ctx = canvas.getContext('2d');
	ctx.drawImage(org, 0, 0, canvas.width, canvas.height);
	return canvas;
}
サイドバーを表示する
ブログ
Whiteday
Whiteday
尋ね人
尋ね人
かつてレレノイドは彼の瞳の中に希望を見ていたが、そのことをあっちこっちに言いふらしまくると、キリウ君は怒ってそれを燃えるゴミの日に出してしまった。