Files
e-tib.com/scripts/compress-photos.mjs

47 lines
1.3 KiB
JavaScript

/**
* Aggressively compresses all photos in public/assets/photos/ to max 1280px
* and quality 70 using sharp. Target: all files under 200KB.
*/
import sharp from 'sharp';
import { readdir, stat } from 'fs/promises';
import { join } from 'path';
const PHOTOS_DIR = 'public/assets/photos';
const MAX_WIDTH = 1280;
const QUALITY = 70;
const MAX_BYTES = 200_000;
const files = await readdir(PHOTOS_DIR);
const imageFiles = files.filter(f => /\.(jpg|jpeg|JPG|JPEG)$/i.test(f));
let compressed = 0;
let skipped = 0;
for (const file of imageFiles) {
const fullPath = join(PHOTOS_DIR, file);
const { size } = await stat(fullPath);
if (size <= MAX_BYTES) {
skipped++;
continue;
}
console.log(`Compressing: ${file} (${Math.round(size / 1024)}KB)`);
try {
const buf = await sharp(fullPath)
.rotate() // auto-orient from EXIF
.resize({ width: MAX_WIDTH, withoutEnlargement: true })
.jpeg({ quality: QUALITY, progressive: true, mozjpeg: true })
.toBuffer();
await sharp(buf).toFile(fullPath);
const afterSize = (await stat(fullPath)).size;
console.log(`${Math.round(afterSize / 1024)}KB (saved ${Math.round((size - afterSize) / 1024)}KB)`);
compressed++;
} catch (err) {
console.error(` ✗ Failed: ${err.message}`);
}
}
console.log(`\nDone: ${compressed} compressed, ${skipped} already small.`);