Files
atlas-seller-kit/apps/worker/test/media-watermark.test.mjs

63 lines
3.5 KiB
JavaScript

import assert from 'node:assert/strict';
import { test } from 'node:test';
import sharp from 'sharp';
import { renderWatermark } from '../src/media-watermark.ts';
const template = {
kind: 'image', opacity: '1', image_size_px: 40, border_radius_px: 0,
position_x: 1, position_y: 1, position: 'bottom_right',
};
const pixel = async (buffer, x, y) => {
const { data, info } = await sharp(buffer).raw().toBuffer({ resolveWithObject: true });
return [...data.subarray((y * info.width + x) * info.channels,
(y * info.width + x) * info.channels + 3)];
};
test('图片水印按坐标贴近右下边,并保持源图尺寸', async () => {
const source = await sharp({ create: { width: 120, height: 100, channels: 3, background: '#ffffff' } }).png().toBuffer();
const mark = await sharp({ create: { width: 40, height: 40, channels: 4, background: '#ff0000ff' } }).png().toBuffer();
const output = await renderWatermark(source, template, mark);
assert.equal(output.width, 120);
assert.equal(output.height, 100);
assert.ok((await pixel(output.bytes, 90, 70))[0] > 200);
assert.ok((await pixel(output.bytes, 90, 70))[1] < 60);
assert.ok((await pixel(output.bytes, 15, 15))[1] > 240);
});
test('大图中的水印大小和底边距与 240×320 管理预览等比一致', async () => {
const source = await sharp({ create: { width: 1200, height: 1600, channels: 3, background: '#ffffff' } }).png().toBuffer();
const mark = await sharp({ create: { width: 80, height: 80, channels: 4, background: '#ff0000ff' } }).png().toBuffer();
const output = await renderWatermark(source, { ...template, image_size_px: 80 }, mark);
assert.ok((await pixel(output.bytes, 800, 1200))[1] < 60);
assert.ok((await pixel(output.bytes, 700, 1200))[1] > 240);
assert.ok((await pixel(output.bytes, 1100, 1500))[1] < 60);
assert.ok((await pixel(output.bytes, 1100, 1585))[1] > 240);
});
test('图片水印允许 10px 最小尺寸', async () => {
const source = await sharp({ create: { width: 240, height: 320, channels: 3, background: '#ffffff' } }).png().toBuffer();
const mark = await sharp({ create: { width: 20, height: 20, channels: 4, background: '#ff0000ff' } }).png().toBuffer();
const output = await renderWatermark(source, { ...template, image_size_px: 10 }, mark);
assert.ok((await pixel(output.bytes, 227, 307))[1] < 80);
assert.ok((await pixel(output.bytes, 217, 297))[1] > 220);
});
test('圆角使图片水印角落保持底图颜色', async () => {
const source = await sharp({ create: { width: 120, height: 100, channels: 3, background: '#ffffff' } }).png().toBuffer();
const mark = await sharp({ create: { width: 40, height: 40, channels: 4, background: '#ff0000ff' } }).png().toBuffer();
const output = await renderWatermark(source, { ...template, border_radius_px: 18 }, mark);
assert.ok((await pixel(output.bytes, 76, 56))[1] > 200);
assert.ok((await pixel(output.bytes, 95, 75))[1] < 60);
});
test('文字水印支持 XML 特殊字符,不会把内容当成 SVG', async () => {
const source = await sharp({ create: { width: 200, height: 100, channels: 3, background: '#ffffff' } }).png().toBuffer();
const output = await renderWatermark(source, {
...template, kind: 'text', text_content: '<ATLAS & 1>', font_code: 'NotoSans', font_size_px: 24,
position_x: 0, position_y: 0,
});
const { data } = await sharp(output.bytes).raw().toBuffer({ resolveWithObject: true });
assert.ok(data.some((value) => value < 100));
});