feat(ai): image-preprocess mit sharp (Resize + JPEG + EXIF-Strip)
This commit is contained in:
71
tests/unit/image-preprocess.test.ts
Normal file
71
tests/unit/image-preprocess.test.ts
Normal file
@@ -0,0 +1,71 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import sharp from 'sharp';
|
||||
import { preprocessImage } from '../../src/lib/server/ai/image-preprocess';
|
||||
|
||||
async function makeTestImage(
|
||||
width: number,
|
||||
height: number,
|
||||
format: 'jpeg' | 'png' | 'webp' = 'jpeg'
|
||||
): Promise<Buffer> {
|
||||
return sharp({
|
||||
create: {
|
||||
width,
|
||||
height,
|
||||
channels: 3,
|
||||
background: { r: 128, g: 128, b: 128 }
|
||||
}
|
||||
})
|
||||
.toFormat(format)
|
||||
.toBuffer();
|
||||
}
|
||||
|
||||
describe('preprocessImage', () => {
|
||||
it('resizes a landscape image so long edge <= 1600px', async () => {
|
||||
const input = await makeTestImage(4000, 2000);
|
||||
const { buffer, mimeType } = await preprocessImage(input);
|
||||
const meta = await sharp(buffer).metadata();
|
||||
expect(Math.max(meta.width ?? 0, meta.height ?? 0)).toBeLessThanOrEqual(1600);
|
||||
expect(Math.max(meta.width ?? 0, meta.height ?? 0)).toBeGreaterThan(1000);
|
||||
expect(mimeType).toBe('image/jpeg');
|
||||
});
|
||||
|
||||
it('resizes a portrait image so long edge <= 1600px', async () => {
|
||||
const input = await makeTestImage(2000, 4000);
|
||||
const { buffer } = await preprocessImage(input);
|
||||
const meta = await sharp(buffer).metadata();
|
||||
expect(Math.max(meta.width ?? 0, meta.height ?? 0)).toBeLessThanOrEqual(1600);
|
||||
});
|
||||
|
||||
it('does not upscale smaller images', async () => {
|
||||
const input = await makeTestImage(800, 600);
|
||||
const { buffer } = await preprocessImage(input);
|
||||
const meta = await sharp(buffer).metadata();
|
||||
expect(meta.width).toBe(800);
|
||||
expect(meta.height).toBe(600);
|
||||
});
|
||||
|
||||
it('converts PNG input to JPEG output', async () => {
|
||||
const input = await makeTestImage(1000, 1000, 'png');
|
||||
const { buffer, mimeType } = await preprocessImage(input);
|
||||
const meta = await sharp(buffer).metadata();
|
||||
expect(meta.format).toBe('jpeg');
|
||||
expect(mimeType).toBe('image/jpeg');
|
||||
});
|
||||
|
||||
it('strips EXIF metadata', async () => {
|
||||
const input = await sharp({
|
||||
create: { width: 100, height: 100, channels: 3, background: '#888' }
|
||||
})
|
||||
.withMetadata({ exif: { IFD0: { Copyright: 'test' } } })
|
||||
.jpeg()
|
||||
.toBuffer();
|
||||
const { buffer } = await preprocessImage(input);
|
||||
const meta = await sharp(buffer).metadata();
|
||||
expect(meta.exif).toBeUndefined();
|
||||
});
|
||||
|
||||
it('rejects non-image buffers', async () => {
|
||||
const notAnImage = Buffer.from('hello world');
|
||||
await expect(preprocessImage(notAnImage)).rejects.toThrow();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user