Photo uploader: reduce client memory usage.

To create inline thumbnails locally, the previous version of the photo uploader
used base64 representations of the local files to be uploaded. While this is
effective, it is a little wasteful. When uploading several photos at once, this
could even lead to the page becoming less responsive.

This commit changes the process such that the photos are actually resized on a
canvas, only using the local original as a buffer. Hence, only the resized
photo is retained in memory.
This commit is contained in:
Aaron van Geffen 2020-02-08 20:35:26 +01:00
parent 62900e7f81
commit 12ea378b02

View File

@ -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;
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) {
preview.addEventListener('load', function() {
callback();
});
}
});
}, false);
reader.readAsDataURL(file);
};