Get file size, image width and height before upload

201,130

Solution 1

Multiple images upload with info data preview

Using HTML5 and the File API

Example using URL API

The images sources will be a URL representing the Blob object
<img src="blob:null/026cceb9-edr4-4281-babb-b56cbf759a3d">

const EL_browse  = document.getElementById('browse');
const EL_preview = document.getElementById('preview');
const readImage  = file => {
  if ( !(/^image\/(png|jpe?g|gif)$/).test(file.type) )
    return EL_preview.insertAdjacentHTML('beforeend', `Unsupported format ${file.type}: ${file.name}<br>`);
  const img = new Image();
  img.addEventListener('load', () => {
    EL_preview.appendChild(img);
    EL_preview.insertAdjacentHTML('beforeend', `<div>${file.name} ${img.width}×${img.height} ${file.type} ${Math.round(file.size/1024)}KB<div>`);
    window.URL.revokeObjectURL(img.src); // Free some memory
  });
  img.src = window.URL.createObjectURL(file);
}
EL_browse.addEventListener('change', ev => {
  EL_preview.innerHTML = ''; // Remove old images and data
  const files = ev.target.files;
  if (!files || !files[0]) return alert('File upload not supported');
  [...files].forEach( readImage );
});
#preview img { max-height: 100px; }
<input id="browse" type="file" multiple>
<div id="preview"></div>

Example using FileReader API

In case you need images sources as long Base64 encoded data strings
<img src="data:image/png;base64,iVBORw0KGg... ...lF/++TkSuQmCC=">

const EL_browse  = document.getElementById('browse');
const EL_preview = document.getElementById('preview');
const readImage = file => {
  if ( !(/^image\/(png|jpe?g|gif)$/).test(file.type) )
    return EL_preview.insertAdjacentHTML('beforeend', `<div>Unsupported format ${file.type}: ${file.name}</div>`);
  const reader = new FileReader();
  reader.addEventListener('load', () => {
    const img  = new Image();
    img.addEventListener('load', () => {
      EL_preview.appendChild(img);
      EL_preview.insertAdjacentHTML('beforeend', `<div>${file.name} ${img.width}×${img.height} ${file.type} ${Math.round(file.size/1024)}KB</div>`);
    });
    img.src = reader.result;
  });
  reader.readAsDataURL(file);  
};
EL_browse.addEventListener('change', ev => {
  EL_preview.innerHTML = ''; // Clear Preview
  const files = ev.target.files;
  if (!files || !files[0]) return alert('File upload not supported');
  [...files].forEach( readImage );
});
#preview img { max-height: 100px; }
<input id="browse" type="file"  multiple>
<div id="preview"></div>
  

Solution 2

Demo

Not sure if it is what you want, but just simple example:

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;
});

Solution 3

If you can use the jQuery validation plugin you can do it like so:

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);
        }
});

The function is passed as ab onload function.

The code is taken from here

Solution 4

Here is a pure JavaScript example of picking an image file, displaying it, looping through the image properties, and then re-sizing the image from the canvas into an IMG tag and explicitly setting the re-sized image type to jpeg.

If you right click the top image, in the canvas tag, and choose Save File As, it will default to a PNG format. If you right click, and Save File as the lower image, it will default to a JPEG format. Any file over 400px in width is reduced to 400px in width, and a height proportional to the original file.

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

<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>

Here is a jsFiddle:

jsFiddle Pick, display, get properties, and Re-size an image file

In jsFiddle, right clicking the top image, which is a canvas, won't give you the same save options as right clicking the bottom image in an IMG tag.

Solution 5

So I started experimenting with the different things that FileReader API had to offer and could create an IMG tag with a DATA URL.

Drawback: It doesn't work on mobile phones, but it works fine on 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>

(see this on a jsfiddle at http://jsfiddle.net/eD2Ez/530/)
(see the original jsfiddle that i added upon to at http://jsfiddle.net/eD2Ez/)

Share:
201,130

Related videos on Youtube

Afshin
Author by

Afshin

Updated on July 08, 2022

Comments

  • Afshin
    Afshin 6 months

    How can I get the file size, image height and width before upload to my website, with jQuery or JavaScript?

  • Roko C. Buljan
    Roko C. Buljan almost 10 years
    @SMC caniuse.com/fileapi only recently supports File API. I'll take a look
  • freerunner almost 9 years
    when the value of i is alerted in the callback function reader.onload it shows a random increment! e.g. for 4 files the value as alerted was 0 3 2 1 . Can any one explain that?
  • Roko C. Buljan
    Roko C. Buljan over 8 years
    @freerunner your files are different size, therefore not loaded at the same time.
  • MrFox
    MrFox about 8 years
    Sadly this requires loading the image twice. It would be much better if we could get the width and height as file properties like file type.
  • Roko C. Buljan
    Roko C. Buljan about 8 years
    @MrFox "Sadly this requires loading the image twice" - That's not quite true, you should use your Console and simply log an _file.target.result to understand that it's already a base64 string. You're not pulling again the same image but applying that string to an in-memory new Image() in order to read the W/H. But yes... it would be nice, occasionally.
  • Stardust
    Stardust almost 7 years
    Thanks, but could you explain how the code works? I'm new to the File API
  • Roko C. Buljan
    Roko C. Buljan almost 7 years
    @Stardust edited to add more relevant info and improved the code.
  • Roko C. Buljan
    Roko C. Buljan almost 7 years
    @Stardust tested on Samsung S3 Chrome.
  • jetlej
    jetlej over 6 years
    'this' in this'files[0] has no value. This must be changed to element.files[0] for it to work.
  • drooh
    drooh over 6 years
    I'm getting an error in the console TypeError: elBrowse is null
  • Roko C. Buljan
    Roko C. Buljan over 6 years
    @drooh put your <script> tags before the closing </body> tag (or use a document ready variant)
  • drooh
    drooh over 6 years
    Had to wrap it all in $(document).ready(function(){ }) for it to work.
  • Roko C. Buljan
    Roko C. Buljan over 6 years
    @drooh yes if you're using jQuery, otherwise simply make sure all your JavaScript is included right before the closing </body> tag.
  • Mohammadali Mirhamed
    Mohammadali Mirhamed about 6 years
    @RokoC.Buljan Thanks For Code . How to make it on button Click Event ??
  • DCJones
    DCJones about 6 years
    @Roko C. Buljan Thanks for the code, is there a way the display the file info below the image. Many thanks in advance.
  • Roko C. Buljan
    Roko C. Buljan about 6 years
    @DCJones sure, instead of imageInfo +'<br>' use '<p>'+ imageInfo +'</p>' Hope it makes sense.
  • WebBrother
    WebBrother about 6 years
  • user764754
    user764754 almost 6 years
    Shouldn't the ObjectURL be revoked in the load handler of the image?? Also I'm pretty sure revokeObjectURL expects a string parameter (e.g. the image src) and not a file.
  • Roko C. Buljan
    Roko C. Buljan almost 6 years
    @user764754 ufff indeed. Great catch & thanks! Edited to reflect.
  • Fahmi almost 6 years
    window.URL is not supported in IE at all. Not really important but just to point it out.
  • Joe Platano
    Joe Platano over 5 years
    @RokoC.Buljan, thanks. one question, if I want to upload this file with XMLHttpRequest and formData, do you suggest a new function that i call after readImage( file ); ?
  • Shaik Nizamuddin over 4 years
    How to acheive this for multiple file selection ?

Related