36 lines
1.7 KiB
TypeScript
36 lines
1.7 KiB
TypeScript
import sharp from 'sharp';
|
|
import { describe, expect, it } from 'vitest';
|
|
import { ImageReplacementInputError, replaceGreenScreen } from '../src/services/image-replacement.js';
|
|
|
|
describe('replaceGreenScreen', () => {
|
|
it('warps a replacement into the detected green region and preserves the surrounding source', async () => {
|
|
const source = await sharp({
|
|
create: { width: 200, height: 160, channels: 3, background: '#20252a' },
|
|
}).composite([{ input: Buffer.from(
|
|
'<svg width="200" height="160"><polygon points="45,30 165,42 150,135 35,120" fill="#00ff00"/></svg>',
|
|
) }]).png().toBuffer();
|
|
const target = await sharp({
|
|
create: { width: 80, height: 120, channels: 3, background: '#ee2233' },
|
|
}).png().toBuffer();
|
|
|
|
const result = await replaceGreenScreen(source, target);
|
|
const decoded = await sharp(result.bytes).raw().toBuffer({ resolveWithObject: true });
|
|
const pixel = (x: number, y: number) => {
|
|
const offset = (y * decoded.info.width + x) * decoded.info.channels;
|
|
return [...decoded.data.subarray(offset, offset + 3)];
|
|
};
|
|
|
|
expect(result).toMatchObject({ mimeType: 'image/jpeg', width: 200, height: 160 });
|
|
expect(pixel(100, 80)[0]).toBeGreaterThan(150);
|
|
expect(pixel(100, 80)[1]).toBeLessThan(100);
|
|
expect(pixel(10, 10)[0]).toBeLessThan(70);
|
|
});
|
|
|
|
it('rejects a source without a usable green-screen area', async () => {
|
|
const source = await sharp({ create: { width: 100, height: 100, channels: 3, background: '#223344' } }).png().toBuffer();
|
|
const target = await sharp({ create: { width: 20, height: 20, channels: 3, background: '#ffffff' } }).png().toBuffer();
|
|
|
|
await expect(replaceGreenScreen(source, target)).rejects.toThrow(ImageReplacementInputError);
|
|
});
|
|
});
|