51 lines
2.9 KiB
TypeScript
51 lines
2.9 KiB
TypeScript
import { expect, test } from "bun:test";
|
||
import { imageLayerAlphaBounds, suggestImageLayerRegion } from "../src/lib/canvas/canvas-image-layer-region";
|
||
import { ensureMediaNodeMinimumSize, fitImageMaterialNodeSize } from "../src/lib/canvas/canvas-node-size";
|
||
import { CanvasNodeType } from "../src/types/canvas";
|
||
|
||
test("extreme material ratios use bounded preview frames and remain stable after reload", () => {
|
||
for (const [width, height] of [
|
||
[1408, 79],
|
||
[12, 1400],
|
||
[701, 626],
|
||
[10, 8],
|
||
]) {
|
||
const size = fitImageMaterialNodeSize(width, height);
|
||
expect(size.width).toBeLessThanOrEqual(720);
|
||
expect(size.height).toBeLessThanOrEqual(520);
|
||
const node = { id: "material", type: CanvasNodeType.Image, title: "素材", position: { x: 10, y: 20 }, ...size, metadata: { content: "/material.png", naturalWidth: width, naturalHeight: height } };
|
||
expect(ensureMediaNodeMinimumSize(node)).toEqual(node);
|
||
}
|
||
});
|
||
|
||
test("alpha bounds keep soft edges and reject empty/invalid rasters", () => {
|
||
const pixels = new Uint8ClampedArray(12 * 8 * 4);
|
||
pixels[(2 * 12 + 3) * 4 + 3] = 1;
|
||
pixels[(5 * 12 + 8) * 4 + 3] = 255;
|
||
expect(imageLayerAlphaBounds(12, 8, pixels)).toEqual({ left: 3, top: 2, width: 6, height: 4 });
|
||
expect(() => imageLayerAlphaBounds(12, 8, new Uint8ClampedArray(pixels.length))).toThrow("完全透明");
|
||
expect(() => imageLayerAlphaBounds(12, 9, pixels)).toThrow("尺寸无效");
|
||
});
|
||
|
||
for (const [width, height, background, foreground] of [
|
||
[400, 260, [20, 150, 220], [230, 80, 40]],
|
||
[260, 400, [220, 210, 190], [30, 70, 100]],
|
||
[500, 200, [40, 30, 30], [130, 200, 90]],
|
||
] as const) {
|
||
test(`regular panel correction uses pixels, independent of subject/ratio/colors ${width}×${height}`, () => {
|
||
const pixels = new Uint8ClampedArray(width * height * 4);
|
||
const bounds = [Math.round(width * 0.2), Math.round(height * 0.2), Math.round(width * 0.8), Math.round(height * 0.8)];
|
||
for (let y = 0; y < height; y++) for (let x = 0; x < width; x++) pixels.set([...(x >= bounds[0] && x < bounds[2] && y >= bounds[1] && y < bounds[3] ? foreground : background), 255], (y * width + x) * 4);
|
||
const suggestion = suggestImageLayerRegion(width, height, pixels, { bbox: [210, 210, 790, 740], shape: "rect" });
|
||
expect(suggestion?.bbox).toEqual([200, 200, 800, 800]);
|
||
});
|
||
}
|
||
|
||
test("ambiguous uniform image, transparent exterior and ellipse keep the original region", () => {
|
||
const pixels = new Uint8ClampedArray(100 * 100 * 4).fill(255);
|
||
const region = { bbox: [200, 200, 800, 800] as [number, number, number, number], shape: "rect" as const };
|
||
expect(suggestImageLayerRegion(100, 100, pixels, region)).toBeUndefined();
|
||
expect(suggestImageLayerRegion(100, 100, pixels.fill(0), region)).toBeUndefined();
|
||
expect(suggestImageLayerRegion(100, 100, pixels, { ...region, shape: "ellipse" })).toBeUndefined();
|
||
});
|