0

I'm using the FileReader function to load a local image file, get the height and width in pixels and convert those two into millimeters for printing in 300 dpi.

the code displays the thumbnail correct every time but the measurements are sometimes updated on the first try, sometimes only after selecting the file again, sometimes using F5 or even CRTL + F5 for reload.

I've tried to troubleshoot the reader.addEventListener function, the Math.round function, basically blindly trial and error.

<!doctype html>
<html lang="en">
 <head>
 <meta charset="utf-8">
 <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
 <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

 <title>Pixelkonverter</title>
</head>

<body>
 <div class="container">
   <div class="row">
     <div class="col-sm my-5">
      <input type="file" onchange="previewFile()"><br>
      <hr>
      <img src="" height="200" alt="Bildvorschau...">
    </div>
    <div class="col-sm my-5">
      Bei 300 dpi ist das gewählte Bild <br>
      <span id="height_mm"></span> mm hoch </br>
      <span id="width_mm"></span> mm breit </br>
    </div>
  </div>
</div>

<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>

<script>
  function previewFile() {
    var preview = document.querySelector('img');
    var file    = document.querySelector('input[type=file]').files[0];
    var reader  = new FileReader();
    var img = new Image();
    var height_mm = 0;
    var width_mm = 0;


    reader.addEventListener("load", function () {
      preview.src = reader.result;
      img.src = reader.result;
      var height_mm = Math.round((img.height * 25.4 / 300) * 100) / 100;
      var width_mm =  Math.round((img.width * 25.4 /300) * 100) / 100;
      document.getElementById("height_mm").innerHTML = height_mm;
      document.getElementById("width_mm").innerHTML = width_mm;
    }, false);


    if (file) {
      reader.readAsDataURL(file);
    }
  }
</script>
</body>
</html>

I'd like to be able to display the correct results of the calculation every single time a file is selected.

Sven Tenscher
  • 185
  • 1
  • 15
  • Have you tried using file reader.onload instead of adding an a load event listener? https://developer.mozilla.org/en-US/docs/Web/API/FileReader/onload – Jonathan Hinds May 24 '19 at 14:49
  • https://stackoverflow.com/questions/3511200/new-image-how-to-know-if-image-100-loaded-or-not – Loveen Dyall May 24 '19 at 15:12
  • when you assign img.src the image might not have been loaded hence the width and height attributes are null or undefined – Loveen Dyall May 24 '19 at 15:13

2 Answers2

1
function previewFile() {
var preview = document.querySelector('img');
var file    = document.querySelector('input[type=file]').files[0];
var reader  = new FileReader();
var img = new Image();
var height_mm = 0;
var width_mm = 0;


reader.addEventListener("load", function () {
  preview.src = reader.result;
  img.onload = function() {
       var height_mm = Math.round((img.height * 25.4 / 300) * 100) / 100;
       var width_mm =  Math.round((img.width * 25.4 /300) * 100) / 100;
       document.getElementById("height_mm").innerHTML = height_mm;
       document.getElementById("width_mm").innerHTML = width_mm;
  }
  img.src = reader.result;
}, false);


if (file) {
  reader.readAsDataURL(file);
}
}

I have explained why this may work in the comments above

Loveen Dyall
  • 824
  • 2
  • 8
  • 20
  • Thank you very much. Didn't think about that. I guessed when the thumbnail was correct so should everything else. With the onload it works like a dream – Sven Tenscher May 24 '19 at 15:27
0

I'd put an onload event into the preview element itself. That way you're 100% sure the image has been rendered.

Diodeus - James MacFarlane
  • 112,730
  • 33
  • 157
  • 176