feat(ai): image-preprocess mit sharp (Resize + JPEG + EXIF-Strip)
This commit is contained in:
38
src/lib/server/ai/image-preprocess.ts
Normal file
38
src/lib/server/ai/image-preprocess.ts
Normal 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' };
|
||||
}
|
||||
Reference in New Issue
Block a user