Resize image using Javascript (fit area, smooth)

Resize an image using a HTML5 canvas. The image is resized proportionally to fit inisde a specific area (box). The image is resized in steps, to make the result look smooth.

by Arjan Haverkamp

HTML

<input type="file" id="uploadFile">
<button type="button" onclick="$('#uploadFile').click()">
Select file to resize&hellip;
</button>

CSS

input[type='file'] {
	display: none;
}

button {
	padding: 10px;
	background: #0084ff;
	color: white;
	border: 0;
	font: 12pt Arial, Helvetica;
}

JavaScript

// Area to fit image into, in pixels.
// The image will be proportionally resized to fit within this area.
var areaWidth = 400, areaHeight = 300;

$('#uploadFile').on('change', function(e) {
	if ('' === this.value) { return; }
	var file = e.target.files[0], reader = new FileReader();
	reader.onload = function() {
		var $img = $('<img>', {src:this.result})
		.on('load', function() {
			var srcWidth = this.naturalWidth, srcHeight = this.naturalHeight;
			var ratio = Math.min(areaWidth / srcWidth, areaHeight / srcHeight);
			var width = srcWidth*ratio, height = srcHeight*ratio;
			var canvas = document.createElement('canvas');
			canvas.width = width; canvas.height = height;
			var ctx = canvas.getContext('2d');

			if (srcWidth < width && srcHeight < height) {
				// Enlarge the image: no inbetween-steps needed:
				ctx.drawImage(this, 0, 0, width, height);			
			}
			else {
				// Shrink the image: inbetween-steps make ik look smooth:
				var oc = document.createElement('canvas');
				var octx = oc.getContext('2d');
				var cur = {
					width: Math.round(srcWidth/2), height: Math.round(srcHeight/2)
				};
				oc.width = cur.width;
				oc.height = cur.height;
				octx.drawImage(this, 0, 0, cur.width, cur.height);

				while (cur.width / 2 > width) {
					octx.drawImage(oc, 0, 0, cur.width, cur.height, 0, 0, cur.width/2, cur.height/2);
					cur = {
						width: Math.round(cur.width/2), height: Math.round(cur.height/2)
					};
				}
				ctx.drawImage(oc, 0, 0, cur.width, cur.height, 0, 0, canvas.width, canvas.height);
			}
		
			var dataUrl = canvas.toDataURL(file.type);
			$('<img>', {src:dataUrl}).appendTo('body');
		});
	};
	reader.readAsDataURL(file);
	this.value = '';
});