Files
Portfolio/scripts/optimize-images.mjs
damjan_savicandClaude Opus 4.5 87c7ebc5e3 feat: Add professional portfolio images and Hero redesign
- Add 15 optimized WebP images for portfolio (21-53KB each)
- Redesign Hero section with full-width background image
- Add SSR support for Hero component
- Update About section with new portrait image
- Update Contact page with professional headshot
- Add images to Services/Leistungen page
- Add image optimization script (sharp)
- Update translations for gallery section

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 23:33:28 +01:00

54 lines
1.9 KiB
JavaScript

import sharp from 'sharp';
import { readdir, mkdir } from 'fs/promises';
import path from 'path';
const SOURCE_DIR = './photos';
const OUTPUT_DIR = './public/images/gallery';
const imageMapping = {
'0c477daf-538e-42b8-9171-3be0f32b052b.jpg': 'thinker-dark.webp',
'8f1df0fa-ff21-4d10-8f4e-67807405405d.jpg': 'studio-seated.webp',
'11da5e53-100b-406f-9ca7-1c84ff193a0a.jpg': 'profile-white.webp',
'e1af9b8e-f857-4df3-8e05-8f51966677f9.jpg': 'editorial-dark.webp',
'Gemini_Generated_Image_4y9h4z4y9h4z4y9h.png': 'walking-phone.webp',
'Gemini_Generated_Image_6i8jtc6i8jtc6i8j.png': 'handshake.webp',
'Gemini_Generated_Image_8x4pc88x4pc88x4p.png': 'speaking-dark.webp',
'Gemini_Generated_Image_b79h3hb79h3hb79h.png': 'meeting-boardroom.webp',
'Gemini_Generated_Image_bhiyhrbhiyhrbhiy.png': 'editorial-side.webp',
'Gemini_Generated_Image_d7l8ihd7l8ihd7l8.png': 'over-shoulder-smile.webp',
'Gemini_Generated_Image_dn15mrdn15mrdn15.png': 'frontal-smile.webp',
'Gemini_Generated_Image_kri03okri03okri0.png': 'phone-skyline.webp',
'Gemini_Generated_Image_lxg2aplxg2aplxg2.png': 'gesturing-dark.webp',
'Gemini_Generated_Image_vz86wsvz86wsvz86.png': 'video-call.webp',
'Gemini_Generated_Image_x4fuuix4fuuix4fu.png': 'studio-seated-white.webp',
};
async function optimizeImages() {
try {
await mkdir(OUTPUT_DIR, { recursive: true });
for (const [source, target] of Object.entries(imageMapping)) {
const sourcePath = path.join(SOURCE_DIR, source);
const targetPath = path.join(OUTPUT_DIR, target);
console.log(`Processing: ${source} -> ${target}`);
await sharp(sourcePath)
.resize(1200, null, {
withoutEnlargement: true,
fit: 'inside'
})
.webp({ quality: 80 })
.toFile(targetPath);
console.log(`✓ Saved: ${target}`);
}
console.log('\n✅ All images optimized successfully!');
} catch (error) {
console.error('Error:', error);
}
}
optimizeImages();