[an error occurred while processing this directive] [an error occurred while processing this directive]

html に表示されている画像を base64 で cgi に送信する

html に表示されている jpeg や png をサーバーに送りたいとき、従来は結構面倒な作業が必要でした。 それが、HTML5 の canvas が出現したおかげで、とても楽にできるようになりました。
クライアント側の手順は以下の通りです。 これを受けるサーバーの処理はこんな感じです。 それでは実例を見てみます。

クライアント側の処理

早速ですが、orig.png を送信するコードは以下のとおりです。
<script>
img = new Image();
img.src="orig.png";
img.onload = function(){
  var cvs = document.createElement("canvas");
  cvs.width = img.naturalWidth;
  cvs.height = img.naturalHeight;
  var ctx = cvs.getContext("2d");
  ctx.drawImage(img,0, 0);
  var b64img = cvs.toDataURL();
  // ここで b64img でなんかする
};
<script>
まず image 要素を作成します。そこで画像をロードさせます。 画像のロードが終わったら、onload に代入している関数に処理が続きます。
createElement() で canvas 要素を作成します。 さらに、canvas のサイズを画像サイズにそろえます。 画像の大きさとしては、img.width と img.height を指定してもよいのですが、 image が変形されている時には width と height も正しくない値になってしまいます。 一方、naturalWidth と naturalHeight を用いると、画像本来の大きさが取得できます。 (ただし IE では使えないかもしれません)
canvas が準備できたら、img を drawImage() で貼り付けます。 なお、drawImage() を使って切り抜いて画像を表示する場合、 引数画像が変形されていても画像本来のサイズを元にしているので注意が必要です。
さらに、canvas の便利関数、 toDataURL() で base64 された文字列に変換します。 引数に "image/jpeg" を入れることで jpeg にもできます。
変換した画像の文字列は、例えば ajax で送信できます。 jQuery を使って送信する例を示します。
  ...
  var b64img = cvs.toDataURL();
  $.ajax({
    type: 'POST',
    url: './post.cgi',
    data: {
        'data': b64img,
    },
    dataType: 'text',
    success: function(data) {
      console.debug("image sent");
    },
    fail: function (d){
      console.debug(d);
    }
  });

これで、posg.cgi に対して、"data" という名前で base64 エンコードされたデータが送信されました。

サーバー側の処理 (python)

送信されたデータは、例えばこんな感じでファイルに保存できます。
#!/usr/bin/env python

import cgi,base64

imgname = "hoge.png"

f = cgi.FieldStorage()
txt = f.getfirst('data', '')
A=b64=txt.split(",")
if len(A) == 2:
        b64=txt.split(",")[1]
        b = base64.b64decode(b64)
        fd=open(imgname, "w")
        fd.write(b)
        fd.close()

print """Content-type: text/html
Pragma: no-cache

<html>
<body>
<img src="%s" />
</body>
</html>
"""%(imgname)

ソース

今回使ったサンプルを置いておきます。
[an error occurred while processing this directive]