diff --git a/public/js/upload_queue.js b/public/js/upload_queue.js
index dcec335..75b237d 100644
--- a/public/js/upload_queue.js
+++ b/public/js/upload_queue.js
@@ -45,9 +45,8 @@ UploadQueue.prototype.addPreviewForFile = function(file, index, callback) {
 		return false;
 	}
 
-	var preview = document.createElement('img');
+	var preview = document.createElement('canvas');
 	preview.title = file.name;
-	preview.style.maxHeight = '150px';
 
 	var preview_box = document.getElementById('upload_preview_' + index);
 	preview_box.appendChild(preview);
@@ -55,12 +54,34 @@ UploadQueue.prototype.addPreviewForFile = function(file, index, callback) {
 	var reader = new FileReader();
 	var that = this;
 	reader.addEventListener('load', function() {
-		preview.src = reader.result;
-		if (callback) {
-			preview.addEventListener('load', function() {
+		var original = document.createElement('img');
+		original.src = reader.result;
+
+		original.addEventListener('load', function() {
+			// Preparation: make canvas size proportional to the original image.
+			preview.height = 150;
+			preview.width = preview.height * (original.width / original.height);
+
+			// First pass: resize to 50% on temp canvas.
+			var temp = document.createElement('canvas'),
+				tempCtx = temp.getContext('2d');
+
+			temp.width = original.width * 0.5;
+			temp.height = original.height * 0.5;
+			tempCtx.drawImage(original, 0, 0, temp.width, temp.height);
+
+			// Second pass: resize again on temp canvas.
+			tempCtx.drawImage(temp, 0, 0, temp.width * 0.5, temp.height * 0.5);
+
+			// Final pass: resize to desired size on preview canvas.
+			var context = preview.getContext('2d');
+			context.drawImage(temp, 0, 0, temp.width * 0.5, temp.height * 0.5,
+				0, 0, preview.width, preview.height);
+
+			if (callback) {
 				callback();
-			});
-		}
+			}
+		});
 	}, false);
 	reader.readAsDataURL(file);
 };