コンピュータクワガタ

かっぱのかっぱによるコンピュータ関連のサイトです

HTML5でローカルファイルのドラッグアンドドロップで画像ファイルを表示

HTML5でローカルの画像ファイルをファイルのアップロードなしでプレビューするというのをやってみたかったのでやってみました。
意外にというか、つまらないところで引っかかったのでメモしておきます。

まず、参考したサイトは以下の2つです。

html5の File API を使って、アップロード無しで画像プレビュー

http://d.hatena.ne.jp/favril/20100506/1273143063

Canvas + File API + Drag&Drop API で Instagram みたいな画像フィルターを作ってみた

http://d.hatena.ne.jp/scalar/20101026/1288068169

作ったのが以下のソースとなります。上記のサイトのコピペを駆使しております。

<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8">
  <title>画像の表示</title>
  <script type="text/javascript" src="jquery.js"></script>
  <script type="text/javascript">
$(function() {
    window.addEventListener('dragover', function(event) {
        event.preventDefault(); // ブラウザのデフォルトの画像表示処理をOFF
    }, false);

    window.addEventListener('drop', function(event) {
        event.preventDefault(); // ブラウザのデフォルトの画像表示処理をOFF
        var file = event.dataTransfer.files[0];
        // ファイルタイプ(MIME)で対応しているファイルか判定
        if (!file.type.match(/image\/\w+/)) {
            alert('画像ファイル以外は利用できません');
            return;
        }

        var reader = new FileReader(); 
        reader.onload = function() {
            var imageObject = $('<img>');
            imageObject.attr('src', reader.result);
            $('#imageDiv').append(imageObject);
        };
        reader.onerror = function(e) {
            var result = $('#result');
            result.html('');
            for (var key in reader.error) {
                result.append(key + '=' + reader.error[key] + '<br>');
            }
        };
        reader.readAsDataURL(file);

        $('#imageInfo').html('name=' + file.name + '<br>type=' +file.type + '<br>size=' + file.size);
    }, false);
});
  </script>
 </head>
 <body>
  <div>画像をドラッグ</div>
  <div id="imageDiv"></div>
  <div id="imageInfo"></div>
  <div id="result"></div>
 </body>
</html>

動かすと以下のような感じで表示されます。

何が苦労したかというと、最初にローカルのhtmlで作っていてFirefox 3.6では動くのに、Chrome 8ではファイルのメタデータは取れるのに、肝心のファイルの読み込みで「NOT_READABLE_ERR」が出てしまうことでした。

よくよく調べるとChromeの仕様のようです。

JavaScriptにおけるローカルファイルアクセス権限のポリシー

http://feather.cocolog-nifty.com/weblog/2010/05/javascript-e781.html

によると、Chrome起動時に以下のオプションを付けるとFirefoxと同じ挙動になるようです。

--allow-file-access-from-files 

実際に試すと、ローカルのHTMLでも問題なく動作しました。

上記オプションは以下でも確認できます。

// By default, file:// URIs cannot read other file:// URIs. This is an
// override for developers who need the old behavior for testing.
const char kAllowFileAccessFromFiles[] = "allow-file-access-from-files";

http://src.chromium.org/svn/branches/552/src/chrome/common/chrome_switches.cc

サンプルを以下に置いたので、Firefox 3.6やChrome 8等でアクセスして、画像ファイルをドラッグしてみてください。
http://www.kuwalab.net/html5/image.html