feat: add sharp-backed image rendering
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
import sharp from 'sharp';
|
||||
|
||||
export function createSharpImageRenderer() {
|
||||
return async function renderDerivative({ data, maxWidth }) {
|
||||
if (!Buffer.isBuffer(data)) {
|
||||
throw new TypeError('Image data must be provided as a Buffer.');
|
||||
}
|
||||
|
||||
if (!Number.isInteger(maxWidth) || maxWidth <= 0) {
|
||||
throw new TypeError('maxWidth must be a positive integer.');
|
||||
}
|
||||
|
||||
const image = sharp(data);
|
||||
const metadata = await image.metadata();
|
||||
|
||||
const targetWidth = metadata.width && metadata.width > maxWidth ? maxWidth : metadata.width ?? maxWidth;
|
||||
const resized = targetWidth === metadata.width ? image : image.resize({ width: targetWidth, withoutEnlargement: true });
|
||||
|
||||
return resized.webp().toBuffer();
|
||||
};
|
||||
}
|
||||
@@ -2,6 +2,7 @@ import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
|
||||
import { createImageDerivativeProcessor } from '../../src/infrastructure/images/image-derivative-processor.js';
|
||||
import { createSharpImageRenderer } from '../../src/infrastructure/images/sharp-image-renderer.js';
|
||||
|
||||
test('renders and stores thumbnail, medium, and large derivatives in order', async () => {
|
||||
const renderedWidths = [];
|
||||
@@ -36,4 +37,17 @@ test('requires a renderer implementation', () => {
|
||||
() => createImageDerivativeProcessor({ imageStorage: {} }),
|
||||
/renderer is required/,
|
||||
);
|
||||
});
|
||||
|
||||
test('creates a sharp-backed WebP renderer that resizes to the requested maximum width', async () => {
|
||||
const renderer = createSharpImageRenderer();
|
||||
const data = Buffer.from(
|
||||
'<svg xmlns="http://www.w3.org/2000/svg" width="1024" height="1024" viewBox="0 0 1024 1024"><rect width="1024" height="1024" fill="#ff0000"/></svg>',
|
||||
);
|
||||
const output = await renderer({ data, maxWidth: 320 });
|
||||
|
||||
assert.ok(output instanceof Buffer);
|
||||
assert.ok(output.length > 0);
|
||||
assert.equal(output.subarray(0, 4).toString('ascii'), 'RIFF');
|
||||
assert.equal(output.subarray(8, 12).toString('ascii'), 'WEBP');
|
||||
});
|
||||
Reference in New Issue
Block a user