feat(ai): image-preprocess mit sharp (Resize + JPEG + EXIF-Strip)

This commit is contained in:
hsiegeln
2026-04-21 10:39:22 +02:00
parent c284f4b85b
commit 0cca9a699c
2 changed files with 109 additions and 0 deletions

View File

@@ -0,0 +1,38 @@
import sharp from 'sharp';
const MAX_EDGE = 1600;
const JPEG_QUALITY = 85;
export type PreprocessedImage = {
buffer: Buffer;
mimeType: 'image/jpeg';
};
// Resize auf max 1600px lange Kante, JPEG re-encode, Metadata strippen.
// sharp liest HEIC/HEIF transparent, wenn libheif im libvips-Build enthalten ist
// (in Alpine's vips-dev + in den offiziellen sharp-Prebuilds).
export async function preprocessImage(input: Buffer): Promise<PreprocessedImage> {
const pipeline = sharp(input, { failOn: 'error' }).rotate(); // respect EXIF orientation
const meta = await pipeline.metadata();
if (!meta.width || !meta.height) {
throw new Error('Unable to read image dimensions');
}
const longEdge = Math.max(meta.width, meta.height);
const resized =
longEdge > MAX_EDGE
? pipeline.resize({
width: meta.width >= meta.height ? MAX_EDGE : undefined,
height: meta.height > meta.width ? MAX_EDGE : undefined,
withoutEnlargement: true
})
: pipeline;
// Default-Verhalten seit sharp 0.33: alle Metadata (EXIF/IPTC/XMP) werden
// gestripped. Nur `.keepMetadata()`/`.keepExif()` würde sie erhalten.
const buffer = await resized
.jpeg({ quality: JPEG_QUALITY, mozjpeg: true })
.toBuffer();
return { buffer, mimeType: 'image/jpeg' };
}