feat: add tools into registry, add icons

This commit is contained in:
2026-08-24 13:01:06 +05:00
parent cb5ccf6da8
commit a2dd288851
3 changed files with 101 additions and 61 deletions
-58
View File
@@ -11,65 +11,7 @@ import {
type ToolEntry
} from './registry';
const PLAN_TOOL_IDS = [
'resize-png',
'crop-png',
'rotate-png',
'flip-png',
'add-padding-png',
'add-border-png',
'fit-on-background-png',
'tile-png',
'center-by-alpha-png',
'grayscale-png',
'invert-colors-png',
'adjust-brightness-contrast-png',
'convert-png-to-jpg',
'convert-png-to-webp',
'remove-color-from-png',
'png-info',
'invert-alpha-png',
'jpg-to-png',
'webp-to-png',
'gif-to-png',
'bmp-to-png',
'ico-to-png',
'png-to-bmp',
'png-to-base64',
'base64-to-png',
'png-to-data-uri',
'data-uri-to-png',
'png-to-hex',
'hex-to-png',
'change-png-opacity',
'sepia-png',
'change-png-hue',
'extract-channel-png',
'swap-channels-png',
'black-and-white-png',
'posterize-png',
'two-colors-png',
'remove-alpha-channel-png',
'set-alpha-channel-png',
'extract-alpha-mask-png',
'round-corners-png',
'create-empty-png',
'single-color-png',
'random-noise-png',
'linear-gradient-png',
'png-is-grayscale',
'png-is-transparent',
'png-orientation',
'remove-background-png',
'blur-png',
'sharpen-png'
];
describe('реестр инструментов', () => {
it('содержит ровно 51 инструмент из плана', () => {
expect(TOOLS.map((t) => t.id).sort()).toEqual([...PLAN_TOOL_IDS].sort());
});
it('id уникальны и в kebab-case', () => {
const ids = TOOLS.map((t) => t.id);
expect(new Set(ids).size).toBe(ids.length);
+88 -1
View File
@@ -3,6 +3,7 @@ import {
colorMask,
extractAlphaMask,
flattenOntoColor,
hardenAlpha,
invertAlpha,
removeColorToAlpha,
roundCorners,
@@ -13,7 +14,18 @@ import {
isGrayscale,
orientationOf
} from './core/analyze';
import { backgroundMaskPreview, removeBackground } from './core/background';
import {
backgroundMaskPreview,
removeBackground
} from './core/background';
import {
closingImage,
contourImage,
dilateImage,
erodeImage,
openingImage,
strokeImage
} from './core/morphology';
import { gaussianBlur, sharpen as sharpenImage } from './core/convolution';
import { gradientImage, noiseImage, solidImage } from './core/generate';
import {
@@ -654,6 +666,81 @@ export const TOOLS: ToolEntry[] = [
smoothPasses: num(p, 'smooth')
})
},
{
id: 'add-stroke-png',
title: 'Обвести PNG',
description:
'Добавляет цветную обводку-кольцо вокруг непрозрачного содержимого заданной толщины.',
category: 'alpha',
params: [
{ id: 'color', label: 'Цвет обводки', type: 'color', default: '#ff0000' },
{ id: 'thickness', label: 'Толщина, px', type: 'slider', min: 1, max: 10, step: 1, default: 3 }
],
run: (img, p) => strokeImage(img, num(p, 'thickness'), str(p, 'color'))
},
{
id: 'find-contour-png',
title: 'Найти контур PNG',
description:
'Оставляет только линию по границе непрозрачных областей выбранного цвета и толщины.',
category: 'alpha',
params: [
{ id: 'color', label: 'Цвет линии', type: 'color', default: '#000000' },
{ id: 'thickness', label: 'Толщина линии, px', type: 'slider', min: 1, max: 5, step: 1, default: 1 }
],
run: (img, p) => contourImage(img, num(p, 'thickness'), str(p, 'color'))
},
{
id: 'make-thicker-png',
title: 'Утолщить PNG',
description: 'Расширяет непрозрачные области на заданное число пикселей.',
category: 'alpha',
params: [
{ id: 'radius', label: 'На сколько px', type: 'slider', min: 1, max: 10, step: 1, default: 2 }
],
run: (img, p) => dilateImage(img, num(p, 'radius'))
},
{
id: 'make-thinner-png',
title: 'Утончить PNG',
description: 'Сужает непрозрачные области — утоньшает штрихи надписей и деталей.',
category: 'alpha',
params: [
{ id: 'radius', label: 'На сколько px', type: 'slider', min: 1, max: 10, step: 1, default: 1 }
],
run: (img, p) => erodeImage(img, num(p, 'radius'))
},
{
id: 'harden-alpha-png',
title: 'Жёсткие края PNG',
description:
'Бинаризует альфа-канал по порогу: полупрозрачные пиксели становятся либо полностью прозрачными, либо непрозрачными.',
category: 'alpha',
params: [
{ id: 'threshold', label: 'Порог альфы, %', type: 'slider', min: 0, max: 100, step: 1, default: 50 }
],
run: (img, p) => hardenAlpha(img, num(p, 'threshold'))
},
{
id: 'despeckle-alpha-png',
title: 'Убрать мусор PNG',
description: 'Открытие: убирает одиночные полупрозрачные пиксели и мелкие крапинки.',
category: 'alpha',
params: [
{ id: 'radius', label: 'Радиус очистки, px', type: 'slider', min: 1, max: 3, step: 1, default: 1 }
],
run: (img, p) => openingImage(img, num(p, 'radius'))
},
{
id: 'close-holes-png',
title: 'Закрыть дыры PNG',
description: 'Закрытие: заполняет одиночные прозрачные точки внутри объекта.',
category: 'alpha',
params: [
{ id: 'radius', label: 'Радиус закрытия, px', type: 'slider', min: 1, max: 3, step: 1, default: 1 }
],
run: (img, p) => closingImage(img, num(p, 'radius'))
},
{
id: 'remove-color-from-png',
title: 'Удалить цвет из PNG (прозрачность)',
+13 -2
View File
@@ -18,6 +18,7 @@ import {
Focus,
Frame,
Grid3x3,
Hammer,
Hash,
Image as ImageIcon,
Info,
@@ -31,10 +32,13 @@ import {
RotateCw,
Ruler,
Scaling,
Scan,
Scissors,
SearchCheck,
Square,
Sun
Sun,
ZoomIn,
ZoomOut
} from '@lucide/svelte';
export const TOOL_ICONS: Record<string, typeof AppWindow> = {
@@ -88,5 +92,12 @@ export const TOOL_ICONS: Record<string, typeof AppWindow> = {
'png-orientation': Ruler,
'blur-png': Droplets,
'sharpen-png': Focus,
'remove-background-png': Scissors
'remove-background-png': Scissors,
'add-stroke-png': Square,
'find-contour-png': Scan,
'make-thicker-png': ZoomIn,
'make-thinner-png': ZoomOut,
'harden-alpha-png': Sun,
'despeckle-alpha-png': SearchCheck,
'close-holes-png': Hammer
};