97

I require to generate a thumbnail of an image in my web application. I make use of the HTML5 File API to generate the thumbnail.

I made use of the examples from Read files in JavaScript to generate the thumbnails.

I am successfully able to generate the thumbnails, but I am able to generate thumbnail only by using a static size. Is there a way to get the file dimensions from the selected file and then create the Image object?

1

5 Answers 5

171

Yes, read the file as a data URL and pass that data URL to the src of an Image: http://jsfiddle.net/pimvdb/eD2Ez/2/.

var fr = new FileReader;

fr.onload = function() { // file is loaded
    var img = new Image;

    img.onload = function() {
        alert(img.width); // image is loaded; sizes are available
    };

    img.src = fr.result; // is the data URL because called with readAsDataURL
};

fr.readAsDataURL(this.files[0]); // I'm using a <input type="file"> for demonstrating
Sign up to request clarification or add additional context in comments.

4 Comments

img.onload = function() { never triggers
do img.src = fr.result; before img.onload
img.onload is the handler for the onload event on the Image and will only be called after something is loaded. In this case img.src = fr.result; will trigger the onload event. Semantically you would want your event handler bound before your event could possibly fire. If the onload is not firing, then try img.onerror = function(err) { console.error(err); } to see if the file reader failed to load something that Image can handle. (or if something else went wrong)
I wrapped it all in a new Promise() so that it would be asynchronous
46

Or use an object URL: http://jsfiddle.net/8C4UB/

var url = URL.createObjectURL(this.files[0]);
var img = new Image;

img.onload = function() {
    alert(img.width);
    URL.revokeObjectURL(img.src);
};

img.src = url;

2 Comments

This approach doesn't load the image into memory. readAsDataURL does. stackoverflow.com/questions/6217652/…
Generally it's best to revoke url in the onload handler: URL.revokeObjectURL(url).
41

The existing answers helped me a lot. However, the odd order of events due to the img.onload event made things a little messy for me. So I adjusted the existing solutions and combined them with a promise-based approach.

Here is a function returning a promise with the dimensions as an object:

const getHeightAndWidthFromDataUrl = dataURL => new Promise(resolve => {
  const img = new Image()
  img.onload = () => {
    resolve({
      height: img.height,
      width: img.width
    })
  }
  img.src = dataURL
})

Here is how you could use it with an async function:

// Get a file from an input field
const file = document.querySelector('[type="file"]').files[0]

// Get the data URL of the image as a string
const fileAsDataURL = window.URL.createObjectURL(file)

// Get dimensions
const someFunction = async () => {
  const dimensions = await getHeightAndWidthFromDataUrl(fileAsDataURL)
  // Do something with dimensions ...
}

And here is how you could use it using the then() syntax:

// Get a file from an input field
const file = document.querySelector('[type="file"]').files[0]

// Get the data URL of the image as a string
const fileAsDataURL = window.URL.createObjectURL(file)

// Get the dimensions
getHeightAndWidthFromDataUrl(fileAsDataURL).then(dimensions => {
  // Do something with dimensions
})

1 Comment

the only relevant answer i found on the internet. thank you very much kind sir ヽ( ̄д ̄)ノ
5

I have wrapped pimvdb's answer in a function for general-purpose use in my project:

function checkImageSize(image, minW, minH, maxW, maxH, cbOK, cbKO) {
    // Check whether browser fully supports all File API
    if (window.File && window.FileReader && window.FileList && window.Blob) {
        var fr = new FileReader;
        fr.onload = function() { // File is loaded
            var img = new Image;
            img.onload = function() { // The image is loaded; sizes are available
                if(img.width < minW || img.height < minH || img.width > maxW || img.height > maxH) {
                    cbKO();
                } else {
                    cbOK();
                }
            };
            img.src = fr.result; // Is the data URL because called with readAsDataURL
        };
        fr.readAsDataURL(image.files[0]);
    } else {
        alert("Please upgrade your browser, because your current browser lacks some new features we need!");
    }
}

Comments

-1
const img = new Image();
img.src = url;

console.log(img.width, img.height);

Nothing fancy and does the job.

1 Comment

Not working. Try stackoverflow.com/a/64268847/1537413 instead

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.