How to generate a thumbnail image after adding an image inside an input type="file" in a form and submitting them both on the same form

I found This simpler yet powerful tutorial. It simply creates an img element and, using the fileReader object, assigns its source attribute as the value of the form input

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

  reader.onloadend = function () {
    preview.src = reader.result;
  }

  if (file) {
    reader.readAsDataURL(file);
  } else {
    preview.src = "";
  }
}
<input type="file" onchange="previewFile()"><br>
<img src="" height="200" alt="Image preview...">


After a better search online I found the answer to my question.

It is possible to combine canvas together with the File API.

Try to upload any picture in the demo below and see that a new generated thumbnail will appear on the right side of the form.

DEMO: http://jsfiddle.net/a_incarnati/fua75hpv/

function handleImage(e){
    var reader = new FileReader();
    reader.onload = function(event){
        var img = new Image();
        img.onload = function(){
            canvas.width = img.width;
            canvas.height = img.height;
            ctx.drawImage(img,0,0);
        }
        img.src = event.target.result;
    }
    reader.readAsDataURL(e.target.files[0]);     
}

A good answer has been given by DerekR to this question:

How to upload image into HTML5 canvas


Building on top of what Allesandro wrote to something more pragmatic.

The function takes a file from the File API and tries to fit it in the boundBox while preserving the aspect ratio. Nothing is drawn, but instead you get back a Promise that spits the dataUrl generated.

// Creates a thumbnail fitted insize the boundBox (w x h)
generateThumbnail(file, boundBox){
  if (!boundBox || boundBox.length != 2){
    throw "You need to give the boundBox"
  }
  var scaleRatio = Math.min(...boundBox) / Math.max(file.width, file.height)
  var reader = new FileReader();
  var canvas = document.createElement("canvas")
  var ctx = canvas.getContext('2d');

  return new Promise((resolve, reject) => {
    reader.onload = function(event){
        var img = new Image();
        img.onload = function(){
            var scaleRatio = Math.min(...boundBox) / Math.max(img.width, img.height)
            let w = img.width*scaleRatio
            let h = img.height*scaleRatio
            canvas.width = w;
            canvas.height = h;
            ctx.drawImage(img, 0, 0, w, h);
            return resolve(canvas.toDataURL(file.type))
        }
        img.src = event.target.result;
    }
    reader.readAsDataURL(file);
  })
}

It can be used like below

generateThumbnail(file, [300, 300]).then(function(dataUrl){
    console.log(dataUrl)
})