Во-первых, вообще не используйте FileReader.
Вместо этого для отображения любых данных из BLOB-объекта используйте метод URL.createObjectURL.
FileReader будет загружать двоичные данные трижды в память (один при чтении BLOB-объекта для преобразования, один как Base64 String и один при передаче как
источник вашего HTMLElement.)
В случае файла, сохраненного на пользовательском диске, blobURL загрузит данные только один раз в память из HTMLElement. BlobURL действительно является прямым указателем на данные BLOB-объекта.
Так что это уже освободит вам много памяти.
inp.onchange = e => {
for(let file of inp.files) {
let url = URL.createObjectURL(file);
let img = new Image(200);
img.src = url;
document.body.appendChild(img);
}
};
<input type="file" webkitdirectory accepts="image/*" id="inp">
Теперь, если этого недостаточно, для создания миниатюр вы можете нарисовать все эти изображения на холстах и при необходимости уменьшить их размер.
Но имейте в виду, что для этого вам все равно придется сначала загрузить данные исходного изображения, и вы не можете быть уверены, как браузер очистит эту использованную память. Так что, создавая эти версии миниатюр, может принести больше вреда, чем что-либо другое.
В любом случае, вот основной пример того, как это может быть реализовано:
inp.onchange = e => {
Promise.all([...inp.files].map(toThumbnail))
.then(imgs => document.body.append.apply(document.body, imgs.filter(v => v)))
.catch(console.error);
};
function toThumbnail(file) {
return loadImage(file)
.then(drawToCanvas)
.catch(_ => {});
}
function loadImage(file) {
const url = URL.createObjectURL(file);
const img = new Image();
return new Promise((res, rej) => {
img.onload = e => res(img);
img.onerror = rej;
img.src = url;
});
};
function drawToCanvas(img) {
const w = Math.min(img.naturalWidth, 200);
const r = w / img.naturalWidth;
const h = img.naturalHeight * r;
const canvas = Object.assign(
document.createElement('canvas'), {
width: w,
height: h
}
);
canvas.getContext('2d').drawImage(img, 0, 0, w, h);
return canvas;
}
<input type="file" webkitdirectory accepts="image/*" id="inp">