feat: add split to parts to geometry registry

This commit is contained in:
2026-09-12 15:24:11 +05:00
parent e1c3d0a95f
commit a7a42d0091
2 changed files with 56 additions and 4 deletions
+3 -3
View File
@@ -30,10 +30,10 @@ ZIP-архивом.
через `crop`.
4. **`web/src/lib/zip.ts` (новый):** `downloadZip(files, zipName)` через
`zipSync`.
5. **`core/errors.ts`:** ключ `errors.tooManyParts` (лимит cols·rows ≤ 1000).
5. **`core/errors.ts`:** ключ `errors.tooManyParts` (страховочный лимит
cols·rows ≤ 1000; при максимуме 6×6 недостижим).
6. **`registry/geometry.ts`:** схема (`columns`, `rows`, дефолт 2×2, min 1,
max 50)
- entry `split-into-parts-png` в `geometryEntries`.
max 6 — максимум 36 частей) + entry `split-into-parts-png` в `geometryEntries`.
7. **Executor:** сериализация/десериализация `FileResult` в `executor.worker.ts`
и тип ветки в `executor.ts`.
8. **UI:** `SchemaToolView.svelte` (`fileResult`, Download → zip),
+53 -1
View File
@@ -16,6 +16,7 @@ import {
padToRatio,
resize,
rotate90,
splitToParts,
symmetricCopy,
tile,
trimToContent,
@@ -23,7 +24,12 @@ import {
type FlipAxis,
} from "../core/geometry";
import { field, toolSchema, type Dimension } from "../registry-schema";
import { imgTool, type ToolEntry } from "./types";
import {
imgTool,
requireSource,
type ToolEntry,
type ToolImageFile,
} from "./types";
interface AddBorderParams {
thickness: number;
@@ -356,6 +362,51 @@ const tileTool: ToolEntry<TileParams> = {
run: imgTool((img, p) => tile(img, p.columns, p.rows)),
};
const MAX_SPLIT_PARTS = 1000;
interface SplitPartsParams {
columns: number;
rows: number;
}
export const splitPartsSchema = toolSchema<SplitPartsParams>({
columns: field.number({ min: 1, max: 6, step: 1, default: 2 }),
rows: field.number({ min: 1, max: 6, step: 1, default: 2 }),
});
const splitPartsTool: ToolEntry<SplitPartsParams> = {
id: "split-into-parts-png",
title: "Split PNG into parts",
description:
"Divides the image into a grid of equal-sized parts. The canvas is padded with transparency to keep every part the same size.",
category: "geometry",
schema: splitPartsSchema,
input: "image",
result: "files",
run: (ctx) => {
const img = requireSource(ctx);
const params = ctx.params as SplitPartsParams;
const cols = Math.max(1, Math.trunc(params.columns));
const rowsCount = Math.max(1, Math.trunc(params.rows));
const count = cols * rowsCount;
if (count > MAX_SPLIT_PARTS) {
throw new ToolError("errors.tooManyParts", { count });
}
const parts = splitToParts(img, cols, rowsCount);
const rowLen = String(rowsCount).length;
const colLen = String(cols).length;
const files: ToolImageFile[] = parts.map((image, index) => {
const col = (index % cols) + 1;
const row = Math.floor(index / cols) + 1;
return {
name: `part-${String(row).padStart(rowLen, "0")}-${String(col).padStart(colLen, "0")}.png`,
image,
};
});
return { files };
},
};
interface EmptyParams {}
export const centerByAlphaSchema = toolSchema<EmptyParams>({});
@@ -605,4 +656,5 @@ export const geometryEntries = [
swapOrientationTool,
symmetricCopyTool,
shiftTool,
splitPartsTool,
];