LoginSignup
87
78

More than 5 years have passed since last update.

input[type=file]で投稿画像を即時表示する際のメモ

Last updated at Posted at 2014-01-17

input[type=file]使って投稿画像を表示する時、
大抵の場合はFileReaderオブジェクトのreadAsDataURLメソッドを使うサンプルをよく見かけるけど、
Android4.0だと動作が不安定だった。

$(function(){

    var $input = $('#js-input'),
        $result = $('#js-result');

    $input.on('change', function(e){
        var file = e.target.files[0];
        if (!file) {
            return;
        };
        var filereader = new FileReader();
        filereader.onload = function(e){
            var url = e.target.result,
                $img = $('<img>').on('load error', function(){
                    $result.append(this);
                }).attr('src', url);
            alert(url);
        };
        filereader.readAsDataURL(file);
    });

});

何とかならないものかと調べてみると、
window.URL.createObjectURLを使いつつ、
フォールバックとしてreadAsDataURLを使うと良いみたい。

しかもreadAsDataURLだとクソでかいbase64文字列が生成されるので大量にメモリを食うけど、
window.URL.createObjectURLだとそうはならないらしい(まだ未確認。

下記だとAndroid4.0で不安定。

$(function(){

    var $input = $('#js-input'),
        $result = $('#js-result');

    $input.on('change', function(e){
        var file = e.target.files[0];
        if (!file) {
            return;
        };
        var url = window.URL.createObjectURL(file),
            $img = $('<img>').on('load error', function(){
                $result.append(this);
            }).attr('src', url);
        alert(url);
    });

});

下記はAndroid4.0でも安定。

var createObjectURL = (window.URL && window.URL.createObjectURL) ? function(file) {
    return window.URL.createObjectURL(file);
} : (window.webkitURL && window.webkitURL.createObjectURL) ? function(file) {
    return window.webkitURL.createObjectURL(file);
} : undefined;

$(function(){

    var $input = $('#js-input'),
        $result = $('#js-result');

    $input.on('change', function(e){
        var file = e.target.files[0];
        if (!file) {
            return;
        };
        var filereader = new FileReader();
        filereader.onload = function(e){
            var url = createObjectURL
                ? createObjectURL(file)
                : e.target.result,
                $img = $('<img>').on('load error', function(){
                    $result.append(this);
                }).attr('src', url);
            alert(url);
        };
        filereader.readAsDataURL(file);
    });

});

最高じゃないすか。。

参考URL

window.URL.createObjectURL - Web API インターフェイス | MDN
createObjectURLがすごい件 - プログラムモグモグ
createObjectURLとは何か? - NullPointer's Blog
モバイルブラウザでの画像アップロードについて覚え書き ::ハブろぐ
FileReader利用時のメモリ増減パターンをちょっと調べてみた ::ハブろぐ

ちなみにiPhoneで撮影した画像を表示しようとすると、
jpegに埋め込まれたexif情報のorientationを元に、
勝手に回転させられて表示が変になるので、
下記のような対応が別途必要になる。

ImageMagickでjpegの縦横(exifのOrientation)情報を元に画像を回転する - lxyuma BLOG
javascript - extract exif orientation data from image - Stack Overflow
https://github.com/jseidelin/exif-js/blob/master/exif.js
JavascriptでJPEG画像からEXIFのOrientation情報のみを取得する | egashira.jp

87
78
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
87
78