Files
ForbiddenStarsApp/frontend/src/lib/image.ts
T

38 lines
1.5 KiB
TypeScript

/**
* Уменьшение изображения на клиенте перед загрузкой (canvas → JPEG).
* Ограничивает большую сторону до `max` px, чтобы не грузить тяжёлые файлы.
* При любой ошибке возвращает исходный файл — сервер всё равно проверит тип/размер.
*/
export async function resizeImage(file: File, max = 1600): Promise<Blob> {
try {
const dataUrl = await new Promise<string>((res, rej) => {
const fr = new FileReader();
fr.onload = () => res(fr.result as string);
fr.onerror = () => rej(fr.error);
fr.readAsDataURL(file);
});
const img = await new Promise<HTMLImageElement>((res, rej) => {
const i = new Image();
i.onload = () => res(i);
i.onerror = () => rej(new Error("image load failed"));
i.src = dataUrl;
});
let { width, height } = img;
if (width > max || height > max) {
const scale = Math.min(max / width, max / height);
width = Math.round(width * scale);
height = Math.round(height * scale);
}
const canvas = document.createElement("canvas");
canvas.width = width;
canvas.height = height;
const ctx = canvas.getContext("2d");
if (!ctx) return file;
ctx.drawImage(img, 0, 0, width, height);
const blob = await new Promise<Blob | null>((res) => canvas.toBlob(res, "image/jpeg", 0.85));
return blob ?? file;
} catch {
return file;
}
}