web-dev-qa-db-ja.com

アップロードする前に画像をプレビューし、ファイルサイズ、画像の高さと幅を取得する方法は?

JQueryまたはJavaScriptを使用して、Webサイトにアップロードする前にファイルサイズ、画像の高さ、幅を取得するにはどうすればよいですか?

91
Afshin

HTML5および File API

以下は、コメントを外した動作コードスニペットの例です

window.URL    = window.URL || window.webkitURL;
var elBrowse  = document.getElementById("browse"),
    elPreview = document.getElementById("preview"),
    useBlob   = false && window.URL; // set to `true` to use Blob instead of Data-URL

function readImage (file) {
  var reader = new FileReader();

  reader.addEventListener("load", function () {
    var image  = new Image();
    
    image.addEventListener("load", function () {
      var imageInfo = file.name +' '+
          image.width +'×'+
          image.height +' '+
          file.type +' '+
          Math.round(file.size/1024) +'KB';

      // Show image and info
      elPreview.appendChild( this );
      elPreview.insertAdjacentHTML("beforeend", imageInfo +'<br>');

      if (useBlob) {
        // Free some memory
        window.URL.revokeObjectURL(image.src);
      }
    });
    image.src = useBlob ? window.URL.createObjectURL(file) : reader.result;
  });

  reader.readAsDataURL(file);  
}


elBrowse.addEventListener("change", function() {

  var files = this.files, errors = "";

  if (!files) {
    errors += "File upload not supported by your browser.";
  }

  if (files && files[0]) {

    for(var i=0; i<files.length; i++) {
      var file = files[i];
      
      if ( (/\.(png|jpeg|jpg|gif)$/i).test(file.name) ) {
        readImage( file ); 
      } else {
        errors += file.name +" Unsupported Image extension\n";  
      }
      
    }
  }

  // Handle errors
  if (errors) {
    alert(errors); 
  }

});
#preview img{height:100px;}
<input id="browse" type="file"  multiple />
<div id="preview"></div>

画像プレビュー領域に入力とdivを使用する

<input id="browse" type="file" multiple>
<div id="preview"></div>

また、CSSを使用して、結果の画像を適切な高さに保ちましょう。

#preview img{ height:100px; }

JavaScript

window.URL    = window.URL || window.webkitURL;
var elBrowse  = document.getElementById("browse"),
    elPreview = document.getElementById("preview"),
    useBlob   = false && window.URL; // Set to `true` to use Blob instead of Data-URL

// 2.
function readImage (file) {

  // Create a new FileReader instance
  // https://developer.mozilla.org/en/docs/Web/API/FileReader
  var reader = new FileReader();

  // Once a file is successfully readed:
  reader.addEventListener("load", function () {

    // At this point `reader.result` contains already the Base64 Data-URL
    // and we've could immediately show an image using
    // `elPreview.insertAdjacentHTML("beforeend", "<img src='"+ reader.result +"'>");`
    // But we want to get that image's width and height px values!
    // Since the File Object does not hold the size of an image
    // we need to create a new image and assign it's src, so when
    // the image is loaded we can calculate it's width and height:
    var image  = new Image();
    image.addEventListener("load", function () {

      // Concatenate our HTML image info 
      var imageInfo = file.name    +' '+ // get the value of `name` from the `file` Obj
          image.width  +'×'+ // But get the width from our `image`
          image.height +' '+
          file.type    +' '+
          Math.round(file.size/1024) +'KB';

      // Finally append our created image and the HTML info string to our `#preview` 
      elPreview.appendChild( this );
      elPreview.insertAdjacentHTML("beforeend", imageInfo +'<br>');

      // If we set the variable `useBlob` to true:
      // (Data-URLs can end up being really large
      // `src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAA...........etc`
      // Blobs are usually faster and the image src will hold a shorter blob name
      // src="blob:http%3A//example.com/2a303acf-c34c-4d0a-85d4-2136eef7d723"
      if (useBlob) {
        // Free some memory for optimal performance
        window.URL.revokeObjectURL(image.src);
      }
    });

    image.src = useBlob ? window.URL.createObjectURL(file) : reader.result;

  });

  // https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsDataURL
  reader.readAsDataURL(file);  
}

// 1.
// Once the user selects all the files to upload
// that will trigger a `change` event on the `#browse` input
elBrowse.addEventListener("change", function() {

  // Let's store the FileList Array into a variable:
  // https://developer.mozilla.org/en-US/docs/Web/API/FileList
  var files  = this.files;
  // Let's create an empty `errors` String to collect eventual errors into:
  var errors = "";

  if (!files) {
    errors += "File upload not supported by your browser.";
  }

  // Check for `files` (FileList) support and if contains at least one file:
  if (files && files[0]) {

    // Iterate over every File object in the FileList array
    for(var i=0; i<files.length; i++) {

      // Let's refer to the current File as a `file` variable
      // https://developer.mozilla.org/en-US/docs/Web/API/File
      var file = files[i];

      // Test the `file.name` for a valid image extension:
      // (pipe `|` delimit more image extensions)
      // The regex can also be expressed like: /\.(png|jpe?g|gif)$/i
      if ( (/\.(png|jpeg|jpg|gif)$/i).test(file.name) ) {
        // SUCCESS! It's an image!
        // Send our image `file` to our `readImage` function!
        readImage( file ); 
      } else {
        errors += file.name +" Unsupported Image extension\n";  
      }
    }
  }

  // Notify the user for any errors (i.e: try uploading a .txt file)
  if (errors) {
    alert(errors); 
  }

});

JSFIDDLE

169
Roko C. Buljan

JQuery検証プラグインを使用できる場合は、次のように実行できます。

Html:

<input type="file" name="photo" id="photoInput" />

JavaScript:

$.validator.addMethod('imagedim', function(value, element, param) {
  var _URL = window.URL;
        var  img;
        if ((element = this.files[0])) {
            img = new Image();
            img.onload = function () {
                console.log("Width:" + this.width + "   Height: " + this.height);//this will give you image width and height and you can easily validate here....

                return this.width >= param
            };
            img.src = _URL.createObjectURL(element);
        }
});

この関数は、ab onload関数として渡されます。

コードは here から取得されます

7

デモ

それがあなたが望むものかどうかはわかりませんが、単純な例です:

var input = document.getElementById('input');

input.addEventListener("change", function() {
    var file  = this.files[0];
    var img = new Image();

    img.onload = function() {
        var sizes = {
            width:this.width,
            height: this.height
        };
        URL.revokeObjectURL(this.src);

        console.log('onload: sizes', sizes);
        console.log('onload: this', this);
    }

    var objectURL = URL.createObjectURL(file);

    console.log('change: file', file);
    console.log('change: objectURL', objectURL);
    img.src = objectURL;
});
4
WebBrother

以下は、画像ファイルを選択して表示し、画像プロパティをループし、キャンバスの画像のサイズをIMGタグに変更し、サイズ変更された画像タイプを明示的にjpegに設定する純粋なJavaScriptの例です。

キャンバスタグで一番上の画像を右クリックし、[ファイルに名前を付けて保存]を選択すると、デフォルトでPNG形式になります。右クリックして、ファイルを下の画像として保存すると、デフォルトでJPEG形式になります。幅が400ピクセルを超えるファイルは、幅が400ピクセルに縮小され、高さは元のファイルに比例します。

HTML

<form class='frmUpload'>
  <input name="picOneUpload" type="file" accept="image/*" onchange="picUpload(this.files[0])" >
</form>

<canvas id="cnvsForFormat" width="400" height="266" style="border:1px solid #c3c3c3"></canvas>
<div id='allImgProperties' style="display:inline"></div>

<div id='imgTwoForJPG'></div>

スクリプト

<script>

window.picUpload = function(frmData) {
  console.log("picUpload ran: " + frmData);

var allObjtProperties = '';
for (objProprty in frmData) {
    console.log(objProprty + " : " + frmData[objProprty]);
    allObjtProperties = allObjtProperties + "<span>" + objProprty + ": " + frmData[objProprty] + ", </span>";
};

document.getElementById('allImgProperties').innerHTML = allObjtProperties;

var cnvs=document.getElementById("cnvsForFormat");
console.log("cnvs: " + cnvs);
var ctx=cnvs.getContext("2d");

var img = new Image;
img.src = URL.createObjectURL(frmData);

console.log('img: ' + img);

img.onload = function() {
  var picWidth = this.width;
  var picHeight = this.height;

  var wdthHghtRatio = picHeight/picWidth;
  console.log('wdthHghtRatio: ' + wdthHghtRatio);

  if (Number(picWidth) > 400) {
    var newHeight = Math.round(Number(400) * wdthHghtRatio);
  } else {
    return false;
  };

    document.getElementById('cnvsForFormat').height = newHeight;
    console.log('width: 400  h: ' + newHeight);
    //You must change the width and height settings in order to decrease the image size, but
    //it needs to be proportional to the original dimensions.
    console.log('This is BEFORE the DRAW IMAGE');
    ctx.drawImage(img,0,0, 400, newHeight);

    console.log('THIS IS AFTER THE DRAW IMAGE!');

    //Even if original image is jpeg, getting data out of the canvas will default to png if not specified
    var canvasToDtaUrl = cnvs.toDataURL("image/jpeg");
    //The type and size of the image in this new IMG tag will be JPEG, and possibly much smaller in size
    document.getElementById('imgTwoForJPG').innerHTML = "<img src='" + canvasToDtaUrl + "'>";
};
};

</script>

JsFiddleは次のとおりです。

jsFiddle画像ファイルの選択、表示、取得、サイズ変更

JsFiddleで、キャンバスである上部の画像を右クリックしても、IMGタグの下部の画像を右クリックした場合と同じ保存オプションは提供されません。

2
Alan Wells

そこで、FileReader APIが提供しなければならないさまざまなことを試し始め、DATA URLを使用してIMGタグを作成することができました。

欠点:携帯電話では動作しませんが、Google Chromeでは正常に動作します。

$('input').change(function() {
    
    var fr = new FileReader;
    
    fr.onload = function() {
        var img = new Image;
        
        img.onload = function() { 
//I loaded the image and have complete control over all attributes, like width and src, which is the purpose of filereader.
            $.ajax({url: img.src, async: false, success: function(result){
                        $("#result").html("READING IMAGE, PLEASE WAIT...")
                        $("#result").html("<img src='" + img.src + "' />");
                console.log("Finished reading Image");
                        }});
        };
        
        img.src = fr.result;
    };
    
    fr.readAsDataURL(this.files[0]);
    
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="file" accept="image/*" capture="camera">
<div id='result'>Please choose a file to view it. <br/>(Tested successfully on Chrome - 100% SUCCESS RATE)</div>

(これは http://jsfiddle.net/eD2Ez/530/ のjsfiddleで参照してください)
http://jsfiddle.net/eD2Ez/ に追加した元のjsfiddleを参照)

1
Stardust

私の知る限り、Javascript/JQueryにはローカルファイルシステムへのアクセス権がないため、これを行う簡単な方法はありません。 html 5には、ファイルサイズなどの特定のメタデータをチェックできる新しい機能がいくつかありますが、実際に画像のサイズを取得できるかどうかはわかりません。

ここに、HTML 5の機能に関して見つけた記事と、ActiveXコントロールの使用を伴うIEの回避策があります。 http://jquerybyexample.blogspot.com/2012/03/how-to-check-file-size-before-uploading.html

0
Russell Durham

動作するjQuery検証の例:

   $(function () {
        $('input[type=file]').on('change', function() {
            var $el = $(this);
            var files = this.files;
            var image = new Image();
            image.onload = function() {
                $el
                    .attr('data-upload-width', this.naturalWidth)
                    .attr('data-upload-height', this.naturalHeight);
            }

            image.src = URL.createObjectURL(files[0]);
        });

        jQuery.validator.unobtrusive.adapters.add('imageminwidth', ['imageminwidth'], function (options) {
            var params = {
                imageminwidth: options.params.imageminwidth.split(',')
            };

            options.rules['imageminwidth'] = params;
            if (options.message) {
                options.messages['imageminwidth'] = options.message;
            }
        });

        jQuery.validator.addMethod("imageminwidth", function (value, element, param) {
            var $el = $(element);
            if(!element.files && element.files[0]) return true;
            return parseInt($el.attr('data-upload-width')) >=  parseInt(param["imageminwidth"][0]);
        });

    } (jQuery));
0