« C言語:TRUEとFALSEの値 | トップページ | Java:文字コード変換ツールを作る(1)文字コード変換 »

JavaScript:excanvasを使ってWebページに画像を表示する

【概要】
JavaScriptでWeb上にグラフィックを描く技術に「Canvas」があります。
Canvasは現在IE9,FireFox,Google Chrome,Safariなどで実装されていますが,IEは8以前では実装されていません。
IEの8以前でCanvasの機能を使うために,Googleから「excanvas」というライブラリが公開されています。
今回のエントリでは,excanvasを使って画像データを表示させたときに嵌ったところを紹介します。

●excanvasの参照
嵌ったところではありませんが,excanvasはjavascriptで書かれた外部ファイルなので,HTMLのheader内で参照する必要があります。
このとき,ネットで見つかるサンプルの多くは以下のようなコードになっています。

<!--[if IE]>
<script type="text/javascript" src="js/excanvas.min.js"></script>
<![endif]-->

しかしながら,canvasはIE9で実装されているので,IE9ではexcanvasは不要です。
なので次のように書くべきかと思います。

<!--[if lt IE 9]>
<script type="text/javascript" src="js/excanvas.min.js"></script>
<![endif]-->

●画像の読み込み
画像データはImageクラスで読み込んで,読み込みが完了してから描画を行います。
この処理でよく見かけるサンプルコードは以下のようなものです。

var image = new Image();
image.src = 'path/filename.jpeg';
image.onload = function () {
  // 画像描画処理.
};

このコードは,画像ファイルを読み込んで,読み込みが完了したらonloadの中の画像描画処理が実行される,という動作を意図したものです。Canvasの画像描画は事前に画像データの読み込みが完了していなければならないので,このような処理になります。
このコードはブラウザによってはうまく動作しますが,Imageクラスの使用方法としては誤りのようです。少なくともIE8ではonloadは呼ばれませんでした。
誤っている点ですが,Imageクラスではsrcにパスを指定するより前にonloadを設定しなければならないようです。正しいコードは以下になります。

var image = new Image();
image.onload = function () {
  // 画像描画処理.
};
image.src = 'path/filename.jpeg';

●同一イメージファイルを何度も読み込む場合
IE8以前でImageクラスを使った場合,一度画像データを読み込んでキャッシュされた状態で同じ画像ファイルを読み込もうとすると,onloadの処理が呼ばれず画像描画処理が実行されない問題があるようです。
この問題の対処方法としてよく見かけるのは,ファイルパスの最後に「?+ランダムな値」を付加して同一のファイルを毎度異なるファイル名で読み込む方法です。
他の方法では,試してはいませんが,jQueryのempty()関数はキャッシュも削除するようなので,これで対処できる可能性があります。

●canvasエレメントをcreateElementで作った場合の問題
canvasエレメントをdocument.createElementで生成した場合,excanvasの環境ではcanvasエレメントとして初期化されず,canvasエレメントにあるはずのgetContext関数が存在しない状態になってしまいます。このような場合はexcanvasの初期化関数を使って明示的に初期化する必要があります。canvasタグをHTMLファイルに直接書いた場合は,初期化コードが自動的に実行されるので問題は起きません。

var canvas = document.createElement('canvas');
if (typeof G_vmlCanvasManager !== 'undefined') {
  canvas = G_vmlCanvasManager.initElement(canvas);
}

なお,G_vmlCanvasManager.initElementは引数のcanvasエレメントが初期化済みかチェックするので,すでに初期化されたエレメントを渡しても問題ありません。また,G_vmlCanvasManagerはexcanvas固有のクラスなので,Canvasが実装されていてexcanvasを使用しない環境でこのコードを実行しても,G_vmlCanvasManagerの存在確認をすれば問題ありません。

Imageクラスの問題とcanvasエレメントの問題に対処したコードは以下のようになります(一部jQueryを使っています)。

var parent = document.getElementById('parentElementId');
$(parent).empty();

var image = new Image();
image.onload = function () {
  var canvas = document.createElement('canvas');
  $(parent).append($(canvas).attr('id','canvasElementId'));

  if (typeof G_vmlCanvasManager !== 'undefined') {
    canvas = G_vmlCanvasManager.initElement(canvas);
  }
  if (canvas.getContext) {
    var context = canvas.getContext('2d');
    context.drawImage(this, 0, 0, this.width, this.height);
  }
};
image.src = 'path/filename.jpeg';
※ image.onload=function() {...}内ではimageインスタンスは「this」で参照できます。

■参考URL
Googleのexcanvas配布元:http://excanvas.sourceforge.net/
HTML5.jpのCanvasドキュメント:http://www.html5.jp/canvas/index.html
mozillaのCanvasドキュメント:https://developer.mozilla.org/ja/Canvas_tutorial/Using_images

■関連書籍をAmazonで検索:[Canvas]
HTML5 Canvas

にほんブログ村 IT技術ブログへ にほんブログ村 IT技術ブログ プログラム・プログラマへ 人気ブログランキングへ ←この記事が役に立ったという方はクリックお願いします。


ノートンモバイルセキュリティバナー

|

« C言語:TRUEとFALSEの値 | トップページ | Java:文字コード変換ツールを作る(1)文字コード変換 »

プログラミング」カテゴリの記事

JavaScript」カテゴリの記事

トラックバック


この記事へのトラックバック一覧です: JavaScript:excanvasを使ってWebページに画像を表示する:

« C言語:TRUEとFALSEの値 | トップページ | Java:文字コード変換ツールを作る(1)文字コード変換 »