Getting width & height of an image with filereader

64,005

Solution 1

You have to wait for the image to load. Try handling the element inside .onload.

I've also simplified the process of setting the source of the two elements to how you should be doing it (with jQuery).

reader.onload = (function(theFile) { 
    var image = new Image();
    image.src = theFile.target.result;

    image.onload = function() {
        // access image size here 
        console.log(this.width);

        $('#imgresizepreview, #profilepicturepreview').attr('src', this.src);
    };
});

Solution 2

For me the solution of Austin didn't work, so I present the one worked for me:

var reader = new FileReader;

reader.onload = function() {
    var image = new Image();

    image.src = reader.result;

    image.onload = function() {
        alert(image.width);
    };

};

reader.readAsDataURL(this.files[0]);

And if you find that assignment image.src = reader.result; takes place after image.onload a bit wired, I think so too.

Solution 3

fileChangeEventHeader(fileInput) {
    const oFReader = new FileReader();
    oFReader.readAsDataURL(fileInput.target.files[0]);
    oFReader.onload = (event: any) => {
      var image = new Image();
      image.src = event.target.result;
      image.onload = function () {
        console.log(`width : ${image.width} px`, `height: ${image.height} px`);
      };
    };
  }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>

<input type="file" name="profile_img" accept="image/*" (change)="fileChangeEventHeader($event)"
                  class="input-file">

Solution 4

Here's an answer inspired by Austin Brunkhorst with a callback for ascertaining image size in case you want to reuse the function elsewhere in your code.

fileControl is assumed to be a jQuery element.

function didUploadImage(fileControl) {      
   // Render image if file exists.
   var domFileControl = fileControl[0];
   if (domFileControl.files && domFileControl.files[0]) {
      // Get first file.
      var firstFile = domFileControl.files[0];

      // Create reader.
      var reader = new FileReader();

      // Notify parent when image read.
      reader.onload = function(e) {
         // Get image URL.
         var imageURL = reader.result;

        // Get image size for image.
        getImageSize(imageURL, function(imageWidth, imageHeight) {
            // Do stuff here.
        });
      };

      // Read image from hard disk.
      reader.readAsDataURL(firstFile);

      // Print status.
      console.log("Uploaded image: " + firstFile.name);
   }
}


function getImageSize(imageURL, callback) {      
   // Create image object to ascertain dimensions.
   var image = new Image();

   // Get image data when loaded.
   image.onload = function() {      
      // No callback? Show error.
      if (!callback) {
         console.log("Error getting image size: no callback. Image URL: " + imageURL);

      // Yes, invoke callback with image size.
      } else {
         callback(this.naturalWidth, this.naturalHeight);
      }
   }

   // Load image.
   image.src = imageURL;
}
Share:
64,005
Martin Alderson
Author by

Martin Alderson

Updated on July 23, 2020

Comments

  • Martin Alderson
    Martin Alderson almost 4 years

    I am building an image resize/crop, and I'd like to show a live preview after they've edited it in a modal (bootstrap). This should work, I believe, but I just get 0 in console.log. This requires feeding the width and the height of the original image into another script (which I'll do after, just need them in console.log/a variable for now)

    function doProfilePictureChangeEdit(e) {
        var files = document.getElementById('fileupload').files[0];
        var reader = new FileReader();
        reader.onload = (function(theFile) {
            document.getElementById('imgresizepreview').src = theFile.target.result;
    
            document.getElementById('profilepicturepreview').src = theFile.target.result;
          }
        );
        reader.readAsDataURL(files);
        var imagepreview = document.getElementById('imgresizepreview');
        console.log(imagepreview.offsetWidth);
        $('img#imgresizepreview').imgAreaSelect({
            handles: true,
            enable: true,
            aspectRatio: "1:1",
            onSelectEnd: preview
        });
        $('#resizeprofilepicturemodal').modal('show');
        };
    
  • Martin Alderson
    Martin Alderson about 11 years
    Great, thanks very much. I was under the misinformed impression that the files would of loaded with the readAsDataURL call.
  • Austin Brunkhorst
    Austin Brunkhorst about 11 years
    reader.onload is called when the file system is finished reading the file from the hardrive. image.onload is called essentially when essentially the image object has buffered the image data in browser. I see how you could have misinterpreted the onload functions; glad to have help though.
  • Benny Neugebauer
    Benny Neugebauer over 10 years
    Note: This works only when you use "reader.readAsDataURL". With "reader.readAsBinaryString" you have to go a different way.
  • andilabs
    andilabs almost 10 years
    @BennyNeugebauer which way? Provide some details or link to example.
  • Austin Brunkhorst
    Austin Brunkhorst almost 10 years
    You eventually need to get to a data uri from the image contents, so using .readAsBinaryString() is pointless.
  • Robert Koritnik
    Robert Koritnik over 8 years
    @AustinBrunkhorst It isn't pointless if you send the same binary string to server (file uploads). using readAsBinaryString() is significantly faster than creating it manually in javascript from data URL.
  • BrightShadow
    BrightShadow almost 8 years
    It is not wired that image loading is asynchronous. All data in src must be decoded, if the src is a link it must be loaded and decoded to image, if base64 also. So it's quite natural :-)
  • Sunil Pachlangia
    Sunil Pachlangia over 6 years
    This is giving me 250 in console every time. No matter what is size of image.
  • uruk
    uruk over 5 years
    @SunilPachlangia: Are you displaying the image somewhere? Then the 250 px is the width of the displayed image. When setting the src of a newly created image ( myPreviewImage = new Image() ), then you get the correct dimensions.
  • Avner Moshkovitz
    Avner Moshkovitz about 5 years
    I am using readAsArrayBuffer. How can I get the image width in such case? I'm now getting the following error: [object%20ArrayBuffer]:1 GET http://localhost/[object%20ArrayBuffer] 404 (Not Found)