Resize image before sending to BASE64 (without using img element)

EDIT: I don't want to show the image on the client, the goal is to reduce the image and scale ...

I have some problems with resizing an image that is selected using file input on a form before it has to be uploaded to the server.

I have the following code controlling my file input:

// monitor file inputs and trigger event
$(document).on('change', '.btn-file :file', function() {

    var F = this.files;
    if(!isImage( F[0] ))
    {
        alert("Not an image file"); 
    }

    var fileurl = resizeImage(F[0]);
    console.log(fileurl);               

    var input = $(this),label = input.val().replace(/\\/g, '/').replace(/.*\//, '');
    input.trigger('fileselect', [label]);
});

      

This function will call resizeImage, which looks like this:

function resizeImage(file)
{
    var MAX_WIDTH = 800;
    var MAX_HEIGHT = 600;

    var img = document.createElement("img");
    img.src = window.URL.createObjectURL(file);
    console.log(img.width);         

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

    var width = img.width;
    var height = img.height;

    if (width > height) {
      if (width > MAX_WIDTH) {
        height *= MAX_WIDTH / width;
        width = MAX_WIDTH;
      }
    } else {
      if (height > MAX_HEIGHT) {
        width *= MAX_HEIGHT / height;
        height = MAX_HEIGHT;
      }
    }
    canvas.width = width;
    canvas.height = height;

    var ctx = canvas.getContext("2d");

    ctx.drawImage(img, 0, 0, width, height);
    console.log(ctx);       
    var dataurl = canvas.toDataURL("image/png");
    return dataurl;
}

      

The problem is that my console log tells me that the return value from my resize function is "data:". I then began to console my way out of it to narrow down where the problem was hiding. In my resizeImage function I registered the WIDTH of my img element which gave me a width of 0, which shouldn't be correct? .. I can't figure out what I did wrong.

+3


source to share


1 answer


If your target browser supports the input attribute file

, you can use URL.createObjectURL

to create an image source that you can manipulate on the canvas element.

Given the maximum size maxW x maxH

you want, you can calculate a scaling factor that will resize the image while maintaining the original aspect ratio:

var scale=Math.min((maxW/img.width),(maxH/img.height));

      

Here is a sample code and demo.



Note that the demo draws the image to the canvas, but you can simply replace the content in memory with document.createElement('canvas')

.

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;

// limit the image to 150x100 maximum size
var maxW=150;
var maxH=100;

var input = document.getElementById('input');
input.addEventListener('change', handleFiles);

function handleFiles(e) {
  var img = new Image;
  img.onload = function() {
    var iw=img.width;
    var ih=img.height;
    var scale=Math.min((maxW/iw),(maxH/ih));
    var iwScaled=iw*scale;
    var ihScaled=ih*scale;
    canvas.width=iwScaled;
    canvas.height=ihScaled;
    ctx.drawImage(img,0,0,iwScaled,ihScaled);
    alert(canvas.toDataURL());
  }
  img.src = URL.createObjectURL(e.target.files[0]);
}
      

body{ background-color: ivory; }
#canvas{border:1px solid red;}
      

<input type="file" id="input"/>
<br>
<canvas id="canvas" width=300 height=300></canvas>
      

Run code


+9


source







All Articles