I\'m having a hard time to understand how to work with canvas
elements in JavaScript.
I\'m implementing a resize feature where user can resize image ins
You can resize an image also at the client-side. The example code below uses an image loaded from the user's local system, to run the example without need to worry about CORS issues. The snippet also stores the image as a Blob object, which can be posted to the server if needed.
// Creates a canvas containing a resized image
function resizeImage(img) {
var canvas = document.createElement('canvas'),
ctx = canvas.getContext('2d'),
oWidth = img.naturalWidth,
oHeight = img.naturalHeight,
ratio = oWidth / oHeight,
width = (ratio > 1) ? Math.min(200, oWidth) : Math.min(100, oWidth),
height = Math.round(width / ratio);
canvas.width = width;
canvas.height = height;
canvas.className = 'temp-cnv';
document.body.appendChild(canvas);
ctx.drawImage(img, 0, 0, width, height);
return canvas;
}
// Define UI elements
var img = document.getElementById('img'),
loadBut = document.getElementById('load'),
resizeBut = document.getElementById('resize'),
resizedImage; // This will be sent to the server
// Creates a blob and attaches it to an image element
resizeBut.addEventListener('click', function() {
var canvas;
if (img.src === 'https://stacksnippets.net/js') {
return; // Quit, no image loaded
}
canvas = resizeImage(img);
canvas.toBlob(function(blob) {
img.src = URL.createObjectURL(blob);
resizedImage = blob;
canvas.parentElement.removeChild(canvas);
}, 'image/jpeg', 0.99);
});
// Reads an image from the user's local system
loadBut.addEventListener('change', function(e) {
var file = new FileReader();
file.addEventListener('load', function() {
img.src = file.result;
});
file.readAsDataURL(e.target.files[0]);
});
.temp-cnv {
display: none;
}
<input type="file" id="load">
<button id="resize">Resize</button>
<br>
<img src="" id="img">
resizeImage
function creates a temporary canvas element, and calculates the dimensions for that canvas. Here the image is always shrinked, but you can implement your own resizing algorithms. img.naturalWidth/Height
properties contain the original size of the image.
When the size of the canvas has been correctly set, the image is drawn into the canvas, at this point the actual resizing happens. Then the canvas is returned to the caller, and assigned to the local canvas
variable.
Then a Blob object is created from the newly-created canvas. toBlob
function takes a callback function, mime-type and an optional quality parameter (for JPEGs only) as arguments. The callback function attaches the canvas into the image, and stores the created Blob object to resizedImage
variable for the further use, and finally removes the temporary canvas element.
Good to read at MDN:
ctx.drawImage method
Blob object
Canvas.toBlob method
CORS enabled images
If you're going to send the resized image to the server, you can create a FormData object, and append the image to that object. Then post the object to the server with AJAX. Something like this:
var xhr = new XMLHttpRequest(),
form = new FormData();
form.append('imageBlob', resizedImage); // resizedImage is the Blob object created in the first snippet
form.append('imageName', 'THE_NAME_OF_THE_IMAGE');
xhr.addEventListener('load', function (data) {
// AJAX response handler code
});
xhr.open('POST', 'THE_URL_TO_POST_TO');
xhr.send(form);
Notice, that the POST parameters (the FormData object in this case) are attached as an argument of xhr.send
call.