You can use the HTML5 Canvas element to blit your image on it and then resize it appropriately
You create a canvas
on-the-fly and perform pixel operations on it - so don't worry it's not visible anywhere on the DOM - think of it like a virtual canvas
Here is a little script I've written a while ago(with some help from another S.O question which I don't really remember) - that allows you to do this - whilst keeping the aspect ratios of the image:
Arguments
- You provide an
image
directly into it
- You provide a
maxWidth
/maxHeight
and it will preserve at least one of the 2
- It allows you to also rotate the image by defining the
degrees
parameter(which would be really useful on mobile devices since different devices provide arbitrarily rotated images - you will find out about this the hard way soon if you are dealing with mobile devices)
Returns
- It returns a Base64 string of the resized image
function resizeImg(img, maxWidth, maxHeight, degrees) {
var imgWidth = img.width,
imgHeight = img.height;
var ratio = 1,
ratio1 = 1,
ratio2 = 1;
ratio1 = maxWidth / imgWidth;
ratio2 = maxHeight / imgHeight;
// Use the smallest ratio that the image best fit into the maxWidth x maxHeight box.
if (ratio1 < ratio2) {
ratio = ratio1;
} else {
ratio = ratio2;
}
var canvas = document.createElement("canvas");
var canvasContext = canvas.getContext("2d");
var canvasCopy = document.createElement("canvas");
var copyContext = canvasCopy.getContext("2d");
var canvasCopy2 = document.createElement("canvas");
var copyContext2 = canvasCopy2.getContext("2d");
canvasCopy.width = imgWidth;
canvasCopy.height = imgHeight;
copyContext.drawImage(img, 0, 0);
// init
canvasCopy2.width = imgWidth;
canvasCopy2.height = imgHeight;
copyContext2.drawImage(canvasCopy, 0, 0, canvasCopy.width, canvasCopy.height, 0, 0, canvasCopy2.width, canvasCopy2.height);
var rounds = 1;
var roundRatio = ratio * rounds;
for (var i = 1; i <= rounds; i++) {
// tmp
canvasCopy.width = imgWidth * roundRatio / i;
canvasCopy.height = imgHeight * roundRatio / i;
copyContext.drawImage(canvasCopy2, 0, 0, canvasCopy2.width, canvasCopy2.height, 0, 0, canvasCopy.width, canvasCopy.height);
// copy back
canvasCopy2.width = imgWidth * roundRatio / i;
canvasCopy2.height = imgHeight * roundRatio / i;
copyContext2.drawImage(canvasCopy, 0, 0, canvasCopy.width, canvasCopy.height, 0, 0, canvasCopy2.width, canvasCopy2.height);
} // end for
canvas.width = imgWidth * roundRatio / rounds;
canvas.height = imgHeight * roundRatio / rounds;
canvasContext.drawImage(canvasCopy2, 0, 0, canvasCopy2.width, canvasCopy2.height, 0, 0, canvas.width, canvas.height);
if (degrees == 90 || degrees == 270) {
canvas.width = canvasCopy2.height;
canvas.height = canvasCopy2.width;
} else {
canvas.width = canvasCopy2.width;
canvas.height = canvasCopy2.height;
}
canvasContext.clearRect(0, 0, canvas.width, canvas.height);
if (degrees == 90 || degrees == 270) {
canvasContext.translate(canvasCopy2.height / 2, canvasCopy2.width / 2);
} else {
canvasContext.translate(canvasCopy2.width / 2, canvasCopy2.height / 2);
}
canvasContext.rotate(degrees * Math.PI / 180);
canvasContext.drawImage(canvasCopy2, -canvasCopy2.width / 2, -canvasCopy2.height / 2);
var dataURL = canvas.toDataURL();
return dataURL;
}
And here's a working code snippet that allows you to upload from your filesystem and resize on the fly:
/*
-------------------------------
-------HANDLE FILE UPLOAD------
-------------------------------
*/
var input = document.getElementById('input');
input.addEventListener('change', handleFiles);
function handleFiles(e) {
var img = new Image;
img.src = URL.createObjectURL(e.target.files[0]);
img.onload = function() {
var base64String = resizeImg(img, 300, 300, 0); //HERE IS WHERE THE FUNCTION RESIZE IS CALLED!!!!
alert(base64String);
document.getElementById('previewImg').src = base64String;
}
}
/*
-------------------------------
-------RESIZING FUNCTION-------
-------------------------------
*/
function resizeImg(img, maxWidth, maxHeight, degrees) {
var imgWidth = img.width,
imgHeight = img.height;
var ratio = 1,
ratio1 = 1,
ratio2 = 1;
ratio1 = maxWidth / imgWidth;
ratio2 = maxHeight / imgHeight;
// Use the smallest ratio that the image best fit into the maxWidth x maxHeight box.
if (ratio1 < ratio2) {
ratio = ratio1;
} else {
ratio = ratio2;
}
var canvas = document.createElement("canvas");
var canvasContext = canvas.getContext("2d");
var canvasCopy = document.createElement("canvas");
var copyContext = canvasCopy.getContext("2d");
var canvasCopy2 = document.createElement("canvas");
var copyContext2 = canvasCopy2.getContext("2d");
canvasCopy.width = imgWidth;
canvasCopy.height = imgHeight;
copyContext.drawImage(img, 0, 0);
// init
canvasCopy2.width = imgWidth;
canvasCopy2.height = imgHeight;
copyContext2.drawImage(canvasCopy, 0, 0, canvasCopy.width, canvasCopy.height, 0, 0, canvasCopy2.width, canvasCopy2.height);
var rounds = 1;
var roundRatio = ratio * rounds;
for (var i = 1; i <= rounds; i++) {
// tmp
canvasCopy.width = imgWidth * roundRatio / i;
canvasCopy.height = imgHeight * roundRatio / i;
copyContext.drawImage(canvasCopy2, 0, 0, canvasCopy2.width, canvasCopy2.height, 0, 0, canvasCopy.width, canvasCopy.height);
// copy back
canvasCopy2.width = imgWidth * roundRatio / i;
canvasCopy2.height = imgHeight * roundRatio / i;
copyContext2.drawImage(canvasCopy, 0, 0, canvasCopy.width, canvasCopy.height, 0, 0, canvasCopy2.width, canvasCopy2.height);
} // end for
canvas.width = imgWidth * roundRatio / rounds;
canvas.height = imgHeight * roundRatio / rounds;
canvasContext.drawImage(canvasCopy2, 0, 0, canvasCopy2.width, canvasCopy2.height, 0, 0, canvas.width, canvas.height);
if (degrees == 90 || degrees == 270) {
canvas.width = canvasCopy2.height;
canvas.height = canvasCopy2.width;
} else {
canvas.width = canvasCopy2.width;
canvas.height = canvasCopy2.height;
}
canvasContext.clearRect(0, 0, canvas.width, canvas.height);
if (degrees == 90 || degrees == 270) {
canvasContext.translate(canvasCopy2.height / 2, canvasCopy2.width / 2);
} else {
canvasContext.translate(canvasCopy2.width / 2, canvasCopy2.height / 2);
}
canvasContext.rotate(degrees * Math.PI / 180);
canvasContext.drawImage(canvasCopy2, -canvasCopy2.width / 2, -canvasCopy2.height / 2);
var dataURL = canvas.toDataURL();
return dataURL;
}
/*
-------------------------------
-------UNNECESSARY CSS---------
-------------------------------
*/
@import url(http://fonts.googleapis.com/css?family=Lato);
.container {
margin: 0 auto;
width: 400px;
height: 400px;
box-shadow: 1px 1px 1px 1px gray;
}
h3,
h4,
h5,
h6 {
margin: 4px !important;
}
.container,
.container * {
display: block;
margin: 12px auto;
font-family: 'Lato';
}
.header {
background-color: #2196F3;
padding: 12px;
color: #fff;
}
.container input {
width: 128px;
height: 32px;
cursor: pointer;
}
.container img {
display: block;
margin: 12px auto;
}
<div class="container">
<div class="header">
<h3>Choose a file</h3>
<h6>and I will alert back to you the base64 string of it's resized version</h6>
</div>
<input type="file" id="input" />
<hr>
<h5>Image Preview:</h5>
<img id="previewImg" src="" />
</div>