42 lines
1.4 KiB
TypeScript
42 lines
1.4 KiB
TypeScript
import fs from 'fs';
|
|
import path from 'path';
|
|
import sharp from 'sharp';
|
|
|
|
const PHOTOS_DIR = path.join(process.cwd(), 'public', 'assets', 'photos');
|
|
|
|
async function optimizeImages() {
|
|
const files = fs.readdirSync(PHOTOS_DIR);
|
|
let optimized = 0;
|
|
|
|
for (const file of files) {
|
|
if (!file.match(/\.(jpg|jpeg|png)$/i)) continue;
|
|
|
|
const filePath = path.join(PHOTOS_DIR, file);
|
|
const metadata = await sharp(filePath).metadata();
|
|
|
|
// If image is larger than 1920px wide, or is a massive file
|
|
if ((metadata.width && metadata.width > 1920) || fs.statSync(filePath).size > 1024 * 1024) {
|
|
console.log(`Optimizing ${file} (Width: ${metadata.width}, Size: ${Math.round(fs.statSync(filePath).size / 1024)}KB)`);
|
|
|
|
const tmpPath = `${filePath}.tmp`;
|
|
try {
|
|
await sharp(filePath)
|
|
.resize({ width: 1920, withoutEnlargement: true })
|
|
.jpeg({ quality: 80, progressive: true })
|
|
.toFile(tmpPath);
|
|
|
|
fs.renameSync(tmpPath, filePath);
|
|
console.log(`✅ Optimized ${file} (New Size: ${Math.round(fs.statSync(filePath).size / 1024)}KB)`);
|
|
optimized++;
|
|
} catch (err) {
|
|
console.error(`Failed to optimize ${file}`, err);
|
|
if (fs.existsSync(tmpPath)) fs.unlinkSync(tmpPath);
|
|
}
|
|
}
|
|
}
|
|
|
|
console.log(`Finished optimizing ${optimized} images.`);
|
|
}
|
|
|
|
optimizeImages();
|