Авто-ресайз изображений перед загрузкой: HTML5 и JS
Быстрый ответ
Для масштабирования изображений до их загрузки используйте API HTML5, в том числе FileReader
и элемент <canvas>
. Вашей задачей будет преобразование файла изображения в data URL, его отображение на холсте, изменение размера с сохранением пропорций и конвертация результата в blob для последующей загрузки на сервер. Ниже приведён код, который иллюстрирует данный процесс:
function resizeImage(file, maxWidth, maxHeight, callback) {
let reader = new FileReader();
reader.onload = e => {
let img = new Image();
img.onload = () => {
let canvas = document.createElement('canvas');
let scale = Math.min(maxWidth / img.width, maxHeight / img.height);
canvas.width = img.width * scale;
canvas.height = img.height * scale;
let ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
canvas.toBlob(callback, 'image/jpeg', 0.9);
};
img.src = e.target.result;
};
reader.readAsDataURL(file);
};
document.querySelector('input[type=file]').onchange = e => {
const maxWidth = 800;
const maxHeight = 600;
resizeImage(e.target.files[0], maxWidth, maxHeight, resizedBlob => {
// Здесь можно выполнить дальнейшие операции с изображением resizedBlob
});
};
Данный код гарантирует быструю работу, сохраняя качество и пропорции изображения, обрабатывая его на стороне клиента.
Работа с разнообразными типами изображений и настройка качества
В реальной практике вам может понадобиться поддержка различных форматов изображений и возможность регулирования качества:
- Многоформатность: Чтобы обрабатывать изображения в форматах PNG, GIF или WebP, замените параметр
'image/png'
в методеcanvas.toBlob()
. - Качество: Этот же метод позволяет регулировать качество изображений в формате JPEG, изменяя его в диапазоне от 0 до 1.
Автоматический расчёт соотношения сторон для корректного масштабирования
Чтобы сохранить пропорции исходного изображения, используйте следующий подход:
const aspectRatio = img.width / img.height;
canvas.height = maxHeight;
canvas.width = canvas.height * aspectRatio;
if (canvas.width > maxWidth) {
canvas.width = maxWidth;
canvas.height = canvas.width / aspectRatio;
}
Эффективные методы обработки больших файлов
При работе с большими изображениями или их большим количеством становятся важными вопросы управления памятью и отзывчивости интерфейса:
- Последовательность: Обрабатывайте изображения последовательно или группами.
- Веб-воркеры: Для оптимизации производительности можно использовать веб-воркеры, чтобы перенести обработку на фоновый поток.
Визуализация
Масштабирование изображения перед загрузкой можно сравнить с упаковкой чемодана:
Оригинал изображения: [👕👖🧥] – Вещи для упаковки.
Происходящий процесс: **Складывайте и упаковывайте аккуратно** ✂️🧳.
Результат масштабирования: [👚🩳🥼] – Готовый чемодан.
Так же как аккуратно упакованный чемодан легче переносить:
До изменения размера: |💼🧱...| – Тяжелый чемодан.
После изменения размера: |💼✨...| – Легко переносимый чемодан.
Подобно упакованному чемодану, оптимизированные изображения лучше передавать по сети.
Загрузка через надежный метод AJAX без перезагрузки страницы
AJAX позволяет пересылать изображения на сервер без перезагрузки страницы, что существенно улучшает пользовательский опыт:
const xhr = new XMLHttpRequest();
xhr.open('POST', 'your_server_endpoint', true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send(`imageData=${encodeURIComponent(resizedBlob)}`);
Не забудьте указать processData: false
, чтобы blob-данные сохраняли свою бинарную структуру.
Учёт возможных проблем
Обратите внимание на:
- Утечки памяти: Освобождайте память от больших неиспользуемых переменных и blob-объектов.
- Совместимость с браузерами: Убедитесь, что применяемые API и методы поддерживаются в браузерах ваших пользователей.
- Ограничения на размер файлов: Соблюдайте установленные сервером ограничения на размер загружаемых файлов.
Полезные материалы
- Canvas API – Веб-API | MDN — Инструкции по работе с изображениями в HTML5 с помощью Canvas API.
- FileReader – Веб-API | MDN — Информация об использовании FileReader для обработки файлов на стороне клиента.
- Promise – JavaScript | MDN — Объяснение механизма работы асинхронных JavaScript-операций с использованием Promises.
- FormData – Веб-API | MDN — Детали использования FormData в AJAX-запросах.
- HTML5 Предварительное масштабирование изображений перед загрузкой – Stack Overflow — Обсуждение и решения проблемы предварительной подготовки изображений.
- Как создать перетаскиваемый загрузчик файлов на чистом JavaScript — Smashing Magazine — Руководство по созданию загрузчика файлов с функцией drag-and-drop на чистом JS.
- GitHub – nodeca/pica: Масштабирование изображений в браузере с высокой производительностью и качеством — Библиотека Pica для масштабирования изображений.