import fs from 'node:fs/promises'; import path from 'node:path'; import sharp from 'sharp'; const dirIn = 'tools/in'; const dirOut = 'tools/out'; const thresholdBytes = 2 * 1024 * 1024; const quality = [100, 99, 97, 95, 90, 80, 75, 70, 60, 50, 40]; async function makedir(dir) { try { await fs.stat(dir); } catch (err) { if (err.code !== 'ENOENT') throw err; await fs.mkdir(dir); } } async function main() { await makedir(dirIn); await makedir(dirOut); for (const base of await fs.readdir(dirIn)) { if (base === '.gitkeep') continue; const fileIn = `${dirIn}/${base}`; const { name } = path.parse(fileIn); const { size } = await fs.stat(fileIn); if (size <= thresholdBytes) { const fileOut = `${dirOut}/${base}`; console.log(`${fileIn} -> ${fileOut} (no changes)`); fs.copyFile(fileIn, fileOut); continue; } const fileOut = `${dirOut}/${name}.jpg`; for (let i = 0; i < quality.length; i += 1) { const newStats = await (sharp(fileIn) .withMetadata() .jpeg({ mozjpeg: true, quality: quality[i] }) .toFile(fileOut) ); if (i == quality.length || newStats.size <= thresholdBytes) { console.log(`${fileIn} -> ${fileOut} (quality: ${quality[i]})`); break; } } } } main();