53

As part of a web app, once images have been downloaded and rendered on a web page, I need to determine an image's file size (kb) and resolution within the browser context (so I could, for example, display that info on the page. This needs to be done client-side, obviously. Must be able to be solved x-browser without an ActiveX control or Java applet (IE7+, FF3+, Safari 3+, IE6 nice to have), though it doesn't have to be the same solution per browser.

Ideally this would be done using system Javascript, but if I absolutely need a JQuery or similar library (or a tiny subset of it), that could be done.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
scottru
  • 5,280
  • 3
  • 21
  • 13
  • Note that the first three answers are about the incorrect writeup I started with (where I said I was talking about image upload). My apologies to those folks. – scottru Aug 21 '09 at 07:11

11 Answers11

85

Edit:

To get the current in-browser pixel size of a DOM element (in your case IMG elements) excluding the border and margin, you can use the clientWidth and clientHeight properties.

var img = document.getElementById('imageId'); 

var width = img.clientWidth;
var height = img.clientHeight;

Now to get the file size, now I can only think about the fileSize property that Internet Explorer exposes for document and IMG elements...

Edit 2: Something comes to my mind...

To get the size of a file hosted on the server, you could simply make an HEAD HTTP Request using Ajax. This kind of request is used to obtain metainformation about the url implied by the request without transferring any content of it in the response.

At the end of the HTTP Request, we have access to the response HTTP Headers, including the Content-Length which represents the size of the file in bytes.

A basic example using raw XHR:

var xhr = new XMLHttpRequest();
xhr.open('HEAD', 'img/test.jpg', true);
xhr.onreadystatechange = function(){
  if ( xhr.readyState == 4 ) {
    if ( xhr.status == 200 ) {
      alert('Size in bytes: ' + xhr.getResponseHeader('Content-Length'));
    } else {
      alert('ERROR');
    }
  }
};
xhr.send(null);

Note: Keep in mind that when you do Ajax requests, you are restricted by the Same origin policy, which allows you to make requests only within the same domain.

Check a working proof of concept here.

Edit 3:

1.) About the Content-Length, I think that a size mismatch could happen for example if the server response is gzipped, you can do some tests to see if this happens on your server.

2.) For get the original dimensions of a image, you could create an IMG element programmatically, for example:

var img = document.createElement('img');

img.onload = function () { alert(img.width + ' x ' + img.height); };

img.src='http://sstatic.net/so/img/logo.png';
Christian
  • 27,509
  • 17
  • 111
  • 155
Christian C. Salvadó
  • 807,428
  • 183
  • 922
  • 838
  • Note that content-length is >= the real file size since the data can be encoded for transport. – Aaron Digulla Aug 21 '09 at 08:12
  • 1
    Thanks. A few followups: 1) what kind of encoding would happen for jpgs that could increase the size? 2) If the image is resized in-browser, is there any way to get the original image dimensions? – scottru Aug 21 '09 at 16:07
  • hm doesnt work for me, what am i doing wrong (it shows me 0 )? $("#temp_image").html(''); var img = document.getElementById('tmp'); alert(img.clientWidth); – mm. Sep 29 '09 at 08:04
  • In case anyone else is curious to try this out, chrome at the very least will throw a cross site scripting error on data urls (i.e. from a canvas.toDataURL() result ). It's apparently expected behaviour. – euxneks May 15 '13 at 21:12
  • Best way i realized was to make a call to backend service, which could fetch the image and return the required data. I have source code for the same service here http://censore.blogspot.in/2015/12/determining-image-file-size-in.html – biplav Dec 17 '15 at 07:40
  • 3
    That's old, but for the **edit 3**, instead of creating a new img element, you can get directly the img's `naturalWidth` and `naturalHeight` properties. – Kaiido Jan 31 '18 at 03:48
  • To get the size of the image in bytes, we can also use [this solution](https://stackoverflow.com/a/45409613/5286034) – Илья Зеленько Sep 03 '19 at 09:14
  • img.naturalWidth and img.naturalHeight is correct answer – Kamlesh Oct 09 '19 at 05:30
  • Regarding `excluding the border and margin, you can use the clientWidth and clientHeight properties`, I just tested it and these properties are not excluding margins and paddings. In order to exclude these, we should use simply `height` and `width` properties. – kodfire Aug 21 '22 at 08:02
  • So what to do when we are not sure if the client is using gzip or any other compression on his/her server or not? How can we get the exact file size with the url in the img tag in javascript? – kodfire Aug 21 '22 at 08:14
19

Check the uploaded image size using Javascript

<script type="text/javascript">
    function check(){
      var imgpath=document.getElementById('imgfile');
      if (!imgpath.value==""){
        var img=imgpath.files[0].size;
        var imgsize=img/1024; 
        alert(imgsize);
      }
    }
</script>

Html code

<form method="post" enctype="multipart/form-data" onsubmit="return check();">
<input type="file" name="imgfile" id="imgfile"><br><input type="submit">
</form>
Mohanrajan
  • 721
  • 9
  • 18
  • 2
    i really like this hack :) but sadly you can't set the value of an file upload input element :( – Jan Wiemers Aug 12 '14 at 12:45
  • the browser is displaying the file upload filed like as button, Here we can browse and pick a file. So I didn't set value for file upload – Mohanrajan Jul 21 '16 at 12:00
14

Getting the Original Dimensions of the Image

If you need to get the original image dimensions (not in the browser context), clientWidth and clientHeight properties do not work since they return incorrect values if the image is stretched/shrunk via css.

To get original image dimensions, use naturalHeight and naturalWidth properties.

var img = document.getElementById('imageId'); 

var width = img.naturalWidth;
var height = img.naturalHeight;

p.s. This does not answer the original question as the accepted answer does the job. This, instead, serves like addition to it.

Community
  • 1
  • 1
Niket Pathak
  • 6,323
  • 1
  • 39
  • 51
11

How about this:

var imageUrl = 'https://cdn.sstatic.net/Sites/stackoverflow/img/sprites.svg';
var blob = null;
var xhr = new XMLHttpRequest(); 
xhr.open('GET', imageUrl, true); 
xhr.responseType = 'blob';
xhr.onload = function() 
{
    blob = xhr.response;
    console.log(blob, blob.size);
}
xhr.send();

http://qnimate.com/javascript-create-file-object-from-url/

due to Same Origin Policy, only work under same origin

White Wang
  • 151
  • 1
  • 5
11

Regarding the width and height:

var img = document.getElementById('imageId'); 

var width = img.clientWidth;
var height = img.clientHeight;

Regarding the filesize you can use performance

var size = performance.getEntriesByName(url)[0];
console.log(size.transferSize); // or decodedBodySize might differ if compression is used on server side
michal.jakubeczy
  • 8,221
  • 1
  • 59
  • 63
3

Service workers have access to header informations, including the Content-Length header.

Service workers are a bit complicated to understand, so I've built a small library called sw-get-headers.

Than you need to:

  1. subscribe to the library's response event
  2. identify the image's url among all the network requests
  3. here you go, you can read the Content-Length header!

Note that your website needs to be on HTTPS to use Service Workers, the browser needs to be compatible with Service Workers and the images must be on the same origin as your page.

Gaël Métais
  • 804
  • 7
  • 7
2

Most folks have answered how a downloaded image's dimensions can be known so I'll just try to answer other part of the question - knowing downloaded image's file-size.

You can do this using resource timing api. Very specifically transferSize, encodedBodySize and decodedBodySize properties can be used for the purpose.

Check out my answer here for code snippet and more information if you seek : JavaScript - Get size in bytes from HTML img src

Punit S
  • 3,079
  • 1
  • 21
  • 26
2

You can use generic Image object to load source dynamically then measure it:

    const img = new Image();
    img.src = this.getUrlSource()
    img.onload = ({target}) =>{
      let width = target.width;
      let height = target.height;
    }
Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
  • 1
    I was looking for a solution where the image is not in the DOM but rather in a base64 string and this worked nicely – J. Barca Apr 02 '21 at 02:08
0

You can get the dimensions using getElement(...).width and ...height.

Since JavaScript can't access anything on the local disk for security reasons, you can't examine local files. This is also true for files in the browser's cache.

You really need a server which can process AJAX requests. On that server, install a service that downloads the image and saves the data stream in a dummy output which just counts the bytes. Note that you can't always rely on the Content-length header field since the image data might be encoded. Otherwise, it would be enough to send a HTTP HEAD request.

Community
  • 1
  • 1
Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820
-4
var img = new Image();
img.src = sYourFilePath;
var iSize = img.fileSize;
sjngm
  • 12,423
  • 14
  • 84
  • 114
Brett
  • 37
  • 1
  • 9
    .fileSize is an IE-only property. – jorisw Oct 17 '12 at 12:01
  • 5
    Just in case if anyone is using this - as of IE 11 the support for this will be stopped - http://msdn.microsoft.com/en-us/library/ie/bg182625(v=vs.85).aspx#legacyAPIs – Bakudan Oct 09 '14 at 10:49
-9

The only thing you can do is to upload the image to a server and check the image size and dimension using some server side language like C#.

Edit:

Your need can't be done using javascript only.

rahul
  • 184,426
  • 49
  • 232
  • 263
  • 3
    This is not true... You can set the file path in JS, turn it into an image element and return the width and height, offset or not. (The browser does a little work, but you can do it with purely JS in a browser) – Eric Hodonsky Apr 08 '13 at 22:27