超自己満足プログラミング このページをアンテナに追加 RSSフィード

2010-03-16

[][] canvasに描いた絵(画像)をサーバに保存

canvasに描かれたデータを取得するには、canvas.toDataURL() を使います。

toDataURL()で得られるのは、base64エンコードされた画像情報なので、

それをサーバに送って、base64デコードして保存という流れです。


toDataURL()して、そのデータをPOSTする部分のjavascript (ajax部分が面倒なので、prototype.jsを使用)

function saveImage() {
    var imgdata = $('canvas_id').toDataURL();  // デフォルトだとpng, 引数でjpegとかも可能
    imgdata = imgdata.replace('data:image/png;base64,', '');  // 頭のいらない部分を落とす

    new Ajax.Request(<画像保存CGIのURL>, {
        parameters: 'img=' + imgdata,  // 画像データを送信
        onComplete: function(res) {  // callback 別になくてもよいが。
            if (res.responseText != 'ok') alert('error');
        }
    });
}

サーバ画像保存CGI

#!/usr/bin/perl

use strict;
use warnings;
use CGI;
use MIME::Base64;

my $q   = CGI->new;
my $img = $q->param('img');  # base64エンコードされた画像データを取得

my $res_msg = 'error';
if ($img) {
    open(my $fh, '>', 'image.png') or die $!;  # 保存するファイル名でopen
    print $fh MIME::Base64::decode($img);  # base64デコード
    close($fh);

    $res_msg = 'ok';
}

print "Content-type:text/plain\n\n";
print $res_msg;
exit;

これで、image.pngcanvas画像が保存されます。


origin-clean flag

canvasにはセキュリティの面から、origin-cleanフラグというものが存在しているらしいです。

このフラグが false になっている場合、toDataURL()は「security error」となって、失敗します。


これに関する原文は、以下です。

Broken link


canvasは、最初はorigin-cleanフラグがtrueにセットされていますが、

いくつか特定のアクションをするとorigin-cleanフラグがfalseになります。


例えば、以前の記事 でやった画像の読み込み(drawImage)とかで、

その画像canvasを表示しているページと同じドメイン画像なら toDataURL()できますが、

ドメイン画像canvasに描画してしまうと、origin-cleanフラグがfalseになって、toDataURL()できなくなります。


なので、外部の画像を読み込ませて、お絵かきさせて、サーバで保存とかしたい場合は、

一度サーバ側で画像ダウンロードして、それをcanvasに描画する必要がありそうです。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

リンク元