mirror of
https://github.com/Lapikud/tipilan.git
synced 2026-03-23 13:24:21 +00:00
Prod ready, heavily optimized images with automatic scripts
This commit is contained in:
27
scripts/convert-images.mjs
Normal file
27
scripts/convert-images.mjs
Normal file
@@ -0,0 +1,27 @@
|
||||
import sharp from 'sharp';
|
||||
import { readdir, unlink } from 'fs/promises';
|
||||
import { join, extname, basename } from 'path';
|
||||
|
||||
const INPUT_DIR = 'public/images';
|
||||
const QUALITY = 85;
|
||||
|
||||
const files = await readdir(INPUT_DIR);
|
||||
const pngs = files.filter(f => extname(f).toLowerCase() === '.png');
|
||||
|
||||
console.log(`Converting ${pngs.length} PNG(s) to WebP at quality ${QUALITY}...\n`);
|
||||
|
||||
for (const file of pngs) {
|
||||
const input = join(INPUT_DIR, file);
|
||||
const output = join(INPUT_DIR, basename(file, '.png') + '.webp');
|
||||
|
||||
const { width, height, size: inSize } = await sharp(input).metadata();
|
||||
await sharp(input).webp({ quality: QUALITY }).toFile(output);
|
||||
|
||||
const { size: outSize } = await sharp(output).metadata();
|
||||
const saved = (((inSize - outSize) / inSize) * 100).toFixed(1);
|
||||
|
||||
console.log(`${file} (${width}x${height})`);
|
||||
console.log(` ${(inSize/1024).toFixed(0)} KB → ${(outSize/1024).toFixed(0)} KB (${saved}% smaller)\n`);
|
||||
}
|
||||
|
||||
console.log('Done.');
|
||||
43
scripts/gen-blur-placeholders.mjs
Normal file
43
scripts/gen-blur-placeholders.mjs
Normal file
@@ -0,0 +1,43 @@
|
||||
import sharp from 'sharp';
|
||||
import { readdir, writeFile } from 'fs/promises';
|
||||
import { join, extname, basename } from 'path';
|
||||
|
||||
const INPUT_DIR = 'public/images';
|
||||
const OUTPUT_FILE = 'src/lib/blurPlaceholders.ts';
|
||||
const THUMB_WIDTH = 20;
|
||||
|
||||
async function processDir(dir, prefix = '') {
|
||||
const entries = await readdir(dir, { withFileTypes: true });
|
||||
const result = {};
|
||||
|
||||
for (const entry of entries) {
|
||||
if (entry.name === 'original') continue;
|
||||
const fullPath = join(dir, entry.name);
|
||||
if (entry.isDirectory()) {
|
||||
const sub = await processDir(fullPath, prefix + entry.name + '/');
|
||||
Object.assign(result, sub);
|
||||
} else if (['.webp', '.png', '.jpg'].includes(extname(entry.name).toLowerCase())) {
|
||||
const buffer = await sharp(fullPath)
|
||||
.resize(THUMB_WIDTH)
|
||||
.webp({ quality: 30 })
|
||||
.toBuffer();
|
||||
const b64 = `data:image/webp;base64,${buffer.toString('base64')}`;
|
||||
const key = prefix + basename(entry.name, extname(entry.name));
|
||||
result[key] = b64;
|
||||
console.log(` ${key} → ${b64.length} chars`);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
console.log('Generating blur placeholders...\n');
|
||||
const placeholders = await processDir(INPUT_DIR);
|
||||
|
||||
const lines = Object.entries(placeholders)
|
||||
.map(([k, v]) => ` "${k}": "${v}",`)
|
||||
.join('\n');
|
||||
|
||||
const output = `// Auto-generated by scripts/gen-blur-placeholders.mjs — do not edit manually\nexport const BLUR_PLACEHOLDERS: Record<string, string> = {\n${lines}\n};\n`;
|
||||
|
||||
await writeFile(OUTPUT_FILE, output, 'utf8');
|
||||
console.log(`\nWrote ${Object.keys(placeholders).length} placeholders to ${OUTPUT_FILE}`);
|
||||
Reference in New Issue
Block a user