How to get image size (height & width) using JavaScript?

Viewed 1358237

Are there any JavaScript or jQuery APIs or methods to get the dimensions of an image on the page?

33 Answers

You can programmatically get the image and check the dimensions using Javascript...

const img = new Image();
img.onload = function() {
  alert(this.width + 'x' + this.height);
}
img.src = 'http://www.google.com/intl/en_ALL/images/logo.gif';

This can be useful if the image is not a part of the markup.

clientWidth and clientHeight are DOM properties that show the current in-browser size of the inner dimensions of a DOM element (excluding margin and border). So in the case of an IMG element, this will get the actual dimensions of the visible image.

var img = document.getElementById('imageid'); 
//or however you get a handle to the IMG
var width = img.clientWidth;
var height = img.clientHeight;

Also (in addition to Rex and Ian's answers) there is:

imageElement.naturalHeight

and

imageElement.naturalWidth

These provide the height and width of the image file itself (rather than just the image element).

Using JQuery you do this:

var imgWidth = $("#imgIDWhatever").width();

The thing all other have forgot is that you cant check image size before it loads. When the author checks all of posted methods it will work probably only on localhost. Since jQuery could be used here, remember that 'ready' event is fired before images are loaded. $('#xxx').width() and .height() should be fired in onload event or later.

You can only really do this using a callback of the load event as the size of the image is not known until it has actually finished loading. Something like the code below...

var imgTesting = new Image();

function CreateDelegate(contextObject, delegateMethod)
{
    return function()
    {
        return delegateMethod.apply(contextObject, arguments);
    }
}

function imgTesting_onload()
{
    alert(this.width + " by " + this.height);
}


imgTesting.onload = CreateDelegate(imgTesting, imgTesting_onload);
imgTesting.src = 'yourimage.jpg';

Let's combine everything we learned here into one simple function (imageDimensions()). It uses promises.

// helper to get dimensions of an image
const imageDimensions = file => 
    new Promise((resolve, reject) => {
        const img = new Image()

        // the following handler will fire after a successful loading of the image
        img.onload = () => {
            const { naturalWidth: width, naturalHeight: height } = img
            resolve({ width, height })
        }

        // and this handler will fire if there was an error with the image (like if it's not really an image or a corrupted one)
        img.onerror = () => {
            reject('There was some problem with the image.')
        }
    
        img.src = URL.createObjectURL(file)
})

// here's how to use the helper
const getInfo = async ({ target: { files } }) => {
    const [file] = files
 
    try {
        const dimensions = await imageDimensions(file)
        console.info(dimensions)
    } catch(error) {
        console.error(error)
    }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/7.0.0-beta.3/babel.min.js"></script>

Select an image:
<input
  type="file"
  onchange="getInfo(event)"
/>
<br />
<small>It works offline.</small>

Assuming, we want to get image dimensions of <img id="an-img" src"...">

// Query after all the elements on the page have loaded.
// Or, use `onload` on a particular element to check if it is loaded.
document.addEventListener('DOMContentLoaded', function () {
  var el = document.getElementById("an-img");

  console.log({
    "naturalWidth": el.naturalWidth, // Only on HTMLImageElement
    "naturalHeight": el.naturalHeight, // Only on HTMLImageElement
    "offsetWidth": el.offsetWidth,
    "offsetHeight": el.offsetHeight
  });

Natural Dimensions

el.naturalWidth and el.naturalHeight will get us the natural dimensions, the dimensions of the image file.

Layout Dimensions

el.offsetWidth and el.offsetHeight will get us the dimensions at which the element is rendered on the document.

To get the natural height and width:

document.querySelector("img").naturalHeight;
document.querySelector("img").naturalWidth;
<img src="img.png">

And if you want to get style height and width:

document.querySelector("img").offsetHeight;
document.querySelector("img").offsetWidth;

Thought this might be helpful to some who are using Javascript and/or Typescript in 2019.

I found the following, as some have suggested, to be incorrect:

let img = new Image();
img.onload = function() {
  console.log(this.width, this.height) // Error: undefined is not an object
};
img.src = "http://example.com/myimage.jpg";

This is correct:

let img = new Image();
img.onload = function() {
  console.log(img.width, img.height)
};
img.src = "http://example.com/myimage.jpg";

Conclusion:

Use img, not this, in onload function.

JQuery Answer:

$height = $('#image_id').height();
$width  = $('#image_id').width();

My two cents in jquery

Disclaimer: This does not necessarily answer this question, but broadens our capabilities. Tested and working in jQuery 3.3.1

Lets consider:

  1. You have the image url/path and you want to get the image width and height without rendering it on the DOM,

  2. Before rendering image on the DOM, you need to set offsetParent node or image div wrapper element to image width and height, to create a fluid wrapper for different image sizes, i.e when clicking a button to view image on a modal/lightbox

This is how i will do it:

// image path
const imageUrl = '/path/to/your/image.jpg'

// Create dummy image to get real width and height
$('<img alt="" src="">').attr("src", imageUrl).on('load', function(){
    const realWidth = this.width;
    const realHeight = this.height;
    alert(`Original width: ${realWidth}, Original height: ${realHeight}`);
})

This is an alternative answer for Node.js, that isn't likely what the OP meant, but could come in handy and seems to be in the scope of the question.

This is a solution with Node.js, the example uses Next.js framework but would work with any Node.js framework. It uses probe-image-size NPM package to resolve the image attributes from the server side.

Example use case: I used the below code to resolve the size of an image from an Airtable Automation script, which calls my own analyzeImage API and returns the image's props.

import {
  NextApiRequest,
  NextApiResponse,
} from 'next';
import probe from 'probe-image-size';

export const analyzeImage = async (req: NextApiRequest, res: NextApiResponse): Promise<void> => {
  try {
    const result = await probe('http://www.google.com/intl/en_ALL/images/logo.gif');

    res.json(result);
  } catch (e) {
    res.json({
      error: true,
      message: process.env.NODE_ENV === 'production' ? undefined : e.message,
    });
  }
};

export default analyzeImage;

Yields:

{
"width": 276,
"height": 110,
"type": "gif",
"mime": "image/gif",
"wUnits": "px",
"hUnits": "px",
"length": 8558,
"url": "http://www.google.com/intl/en_ALL/images/logo.gif"
}

Maybe this will help others. In my case, I have a File type (that is guaranteed to be an image) & I want the image dimensions without loading it on the DOM.

General strategy: Convert File to ArrayBuffer -> Convert ArrayBuffer to base64 string -> use this as the image source with an Image class -> use naturalHeight & naturalWidth to get dimensions.

const fr = new FileReader();
fr.readAsArrayBuffer(image); // image the the 'File' object
fr.onload = () => {
  const arrayBuffer: ArrayBuffer = fr.result as ArrayBuffer;

  // Convert to base64. String.fromCharCode can hit stack overflow error if you pass
  // the entire arrayBuffer in, iteration gets around this
  let binary = '';
  const bytes = new Uint8Array(arrayBuffer);
  bytes.forEach(b => binary += String.fromCharCode(b));
  const base64Data = window.btoa(binary);

  // Create image object. Note, a default width/height MUST be given to constructor (per 
  // the docs) or naturalWidth/Height will always return 0.
  const imageObj = new Image(100, 100);
  imageObj.src = `data:${image.type};base64,${base64Data}`;
  imageObj.onload = () => {
    console.log(imageObj.naturalWidth, imageObj.naturalHeight);
  }
}

This allows you to get the image dimensions & aspect ratio all from a File without rendering it. Can easily convert the onload functions to RxJS Observables using fromEvent for a better async experience:

// fr is the file reader, this is the same as fr.onload = () => { ... }
fromEvent(fr, 'load')

You can also use:

var image=document.getElementById("imageID");
var width=image.offsetWidth;
var height=image.offsetHeight;

just pass the img file object which is obtained by the input element when we select the correct file it will give the netural height and width of image

function getNeturalHeightWidth(file) {
     let h, w;
     let reader = new FileReader();
      reader.onload = () => {
        let tmpImgNode = document.createElement("img");
        tmpImgNode.onload = function() {
          h = this.naturalHeight;
          w = this.naturalWidth;
        };
        tmpImgNode.src = reader.result;
      };
      reader.readAsDataURL(file);
    }
   return h, w;
}
const file = event.target.files[0];
const img = new Image();
img.onload = function () {
  width = img.width;
  height = img.height;
};
img.src = URL.createObjectURL(file);
alert(width + "x" + height);

Try

function sizes() {
  console.log(`width: ${pic.width}, height:${pic.height}`);
}
<img id="pic" src="https://picsum.photos/300/150">
<button onclick="sizes()">show size</button>

Related