Safari/Google Chrome編:
getImageData()/putImageData()でまとめて処理
レンダリングエンジン「WebKit」を利用している「Safari」「Google Chrome」には、Friefox同様、getImageData()/putImageData()が用意されています。本来であればサンプル3のプログラムがそのまま動くはずです。
ところが実際には、サンプル3のプログラムはSafari/Google Chromeでは動作しません。どうやらピクセル単位の読み書きの処理を繰り返すとうまく動作しないようです。そこで、Safari/Google Chromeでは、繰り返し処理の前にすべてのキャンバスのピクセルデータをgetImageData()で取得しておきます。取得したピクセル情報はdata配列に入っていますので、参照する位置を順番に変えていきフィルター処理をかけます。
フィルター処理が完了したらputImageData()を使って、処理済みの画像データを一括で描画します。この方法はFirefoxでも利用でき、毎回ピクセル値を読み出さないため、処理は高速です。
実際のプログラムはサンプル4です。Safari/Google ChromeでもFirefox同様、あらかじめ画像を読み込んでいないと画像が表示されませんので、imgタグで読み込ませています(Google Chromeでは読み込みタイミングのためか、画像が表示されず真っ黒になることがあります)。
●サンプル4(Safari 4/Google Chrome 2以降専用)
【HTML】
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html lang="ja">
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>Sample</title>
<link rel="stylesheet" href="css/main.css" type="text/css" media="all">
<script type="text/javascript" src="js/sample.js"></script>
</head>
<body>
<h1>ブラウザーでフィルター処理</h1>
<canvas id="myCanvas" width="300" height="169">canvasに対応したブラウザーで実行してください</canvas>
</body>
</html>
【sample.js】
window.onload = function(){
var _canvasW = 300; // 横幅300ピクセル
var _canvasH = 169; // 縦幅169ピクセル
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
var imgObj = new Image(_canvasW, _canvasH);
imgObj.src = "http://■■■■/●●●●/asama.jpg";
context.drawImage(imgObj, 0, 0);
var imageData = context.getImageData(0, 0, _canvasW, _canvasH); // ピクセル値を取得する
var w = imageData.width;
var h = imageData.height;
var pixelImage = context.createImageData(w, h);
// フィルター処理
for(var y=0; y<h; y++){
for(var x=0; x<w; x++){
var ptr = (y * w + x ) * 4; // ピクセル処理する配列の要素位置を計算
var R = imageData.data[ptr + 0];
var G = imageData.data[ptr + 1];
var B = imageData.data[ptr + 2];
R = R * 2;
if (R > 255) R = 255;
G = Math.floor(G / 2);
B = Math.floor(B / 2);
pixelImage.data[ptr + 0] = R;
pixelImage.data[ptr + 1] = G;
pixelImage.data[ptr + 2] = B;
pixelImage.data[ptr + 3] = 255;
}
}
context.putImageData(pixelImage, 0, 0);
}
■■■■:ドメイン
●●●●:ディレクトリパス