このページの本文へ

PROGRAMMING 古籏一浩のJavaScriptラボ第31回

HTML5のCanvasで作る、Flash不要のお絵かきツール

2010年04月15日 11時00分更新

古籏一浩

  • この記事をはてなブックマークに追加
本文印刷

描いた画像をファイルに保存する

 ここまでで、最低限の機能を持つお絵かきツールができました。ここからさらに機能を追加していきたいところですが、その前に「描いた画像を保存する」機能を付けておきましょう。

 Canvasに描いたデータは、どのような方法で保存したらよいのでしょうか。Webブラウザーには、ページ内で生成されたデータを保存する機能はありません。せっかくCanvasで絵を描いても、それを保存する手段が標準では存在しないのです。そのため、もっとも簡単で、OSに関係なく確実に保存できる手段は、画面をキャプチャーする、ということになります。

 画面キャプチャーでも悪くはないのですが、ここではほかの方法を考えます。Firefox/Safari/Operaに用意されているJavaScriptのdataスキーム(data:)を使用する方法です。dataスキームを利用すると、Canvasに描いた画像をデータとしてダウンロードできます。ピクセル値を読み出してからBase64にエンコード(変換)し、dataスキームにMIMEタイプとともに指定します。たとえばPNG形式なら、data:image/png;base64,~ といった具合になります。

 ありがたいことに、これらの処理をまとめた「Canvas2Image」というライブラリーが以下のサイトで配布されています。現在ところ、Canvas2ImageはIEを除く主要ブラウザー(Firefox/Safari/Opera)で利用できますので(Opera 10.50では色味がおかしくなることがあります)、今回はこのライブラリーを使いましょう。なお、Canvas2ImageはPNG形式だけでなくJPEG形式とBMP形式にも対応しています。



 使い方は簡単で、ライブラリーを読み込ませた後に保存形式に応じたメソッドを呼び出すだけです。たとえばPNG形式で保存する場合は以下のように記述します。


var can = document.getElementById("myCanvas");
Canvas2Image.saveAsPNG(can);    // PNG形式で保存


 サンプル03に、PNG形式での保存機能を組み込んだものがサンプル04です。絵を描いて保存ボタンを押すとファイルを保存できます。保存先はブラウザーによって異なり、確認のダイアログが出る場合もあります。また、生成されるファイルに拡張子は付かないので、.pngの拡張子を追加する必要があります。

fig4-1
サンプル03の実行画面。適当な絵を描いて保存ボタンをクリックする
fig4-1
ファイルをダウンロードできたら、拡張子を.pngに変更する。なお、Mac OS X/Safariでは拡張子を付けなくてもファイルアイコンをダブルクリックするだけで表示できる
fig4-1
ダウンロードしたPNGファイルをPhotoshopで表示した状態。Canvasには透明情報があるため、PNG形式で書き出すと透明情報を保持したまま利用できる

サンプル04[HTML]


<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="utf-8">
        <title>シンプルペイント</title>
        <link rel="stylesheet" href="css/main.css" type="text/css" media="all">
        <script type="text/javascript" src="js/base64.js"></script>
        <script type="text/javascript" src="js/canvas2image.js"></script>
        <script type="text/javascript" src="js/draw.js"></script>
    </head>
    <body>
    <canvas id="myCanvas" width="640" height="480">
        HTML5 Canvasに対応したブラウザーを使用してください。
    </canvas>
    <div id="menu">
        <button onclick="saveData()">保存</button>
    </div>
</body>
</html>


サンプル04[JavaScript:sample.js]


var drawFlag = false;
var oldX = 0;
var oldY = 0;
window.addEventListener("load", function(){
    var can = document.getElementById("myCanvas");
    can.addEventListener("mousemove", draw, true);
    can.addEventListener("mousedown", function(e){
        drawFlag = true;
        oldX = e.clientX;
        oldY = e.clientY;
    }, true);
    can.addEventListener("mouseup", function(){
        drawFlag = false;
    }, true);
}, true);
// 描画処理
function draw(e){
    if (!drawFlag) return;
    var x = e.clientX;
    var y = e.clientY;
    var can = document.getElementById("myCanvas");
    var context = can.getContext("2d");
    context.strokeStyle = "rgba(255,0,0,1)";
    context.lineWidth = 1;
    context.beginPath();
    context.moveTo(oldX, oldY);
    context.lineTo(x, y);
    context.stroke();
    context.closePath();
    oldX = x;
    oldY = y;
}
// 保存処理 (Canvas2Image)
// http://www.nihilogic.dk/labs/canvas2image/
function saveData(){
    var can = document.getElementById("myCanvas");
    Canvas2Image.saveAsPNG(can);    // PNG形式で保存
}



 今回のところはここまでです。次回はシンプルペイントにペンの色やサイズを選べる機能を付けて、より本格的なお絵かきツールに仕上げていきましょう。



ライブラリーを使わずにPNG形式で保存する

 今回はCanvas2Imageライブラリーを利用して画像を保存しましたが、PNG形式に限定すればライブラリーを使わなくても以下のような処理で保存できます。


// 保存処理
function saveData(){
    var can = document.getElementById("myCanvas");
    var d = can.toDataURL("image/png");
    d = d.replace("image/png", "image/octet-stream");
    window.open(d,"save");
}


 toDataURL()はピクセルデータをBase64形式に変換します。あとは、image/pngのMIME形式をimage/octet-streamに置換し、window.open()の引数として渡します。

Web Professionalトップへ

この連載の記事

一覧へ
Web Professionalトップページバナー

この記事の編集者は以下の記事をオススメしています

ASCII.jp会員サービス 週刊Web Professional登録

Webディレクター江口明日香が行く