@pixerate/editor 0.213.0 → 0.215.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-UOGKSVRQ.cjs → chunk-B46UQUDC.cjs} +770 -733
- package/dist/{chunk-W3TOZTL7.js → chunk-F7Z2MKY2.js} +115 -4
- package/dist/{chunk-YBJXCQTR.js → chunk-QXY4YTRI.js} +738 -701
- package/dist/{chunk-H65IBXFI.cjs → chunk-S55JFWDA.cjs} +350 -239
- package/dist/{chunk-QYLWG22N.cjs → chunk-SS53NNZO.cjs} +304 -1
- package/dist/{chunk-LQ5SALHK.js → chunk-U7C655AM.js} +5 -311
- package/dist/{chunk-L52VMQZS.cjs → chunk-UC3PWFM3.cjs} +68 -374
- package/dist/{chunk-L3G23N5Y.js → chunk-ZNA3IQZF.js} +304 -1
- package/dist/image-editor/controller.d.cts +44 -0
- package/dist/image-editor/controller.d.ts +44 -0
- package/dist/image-editor/index.cjs +1768 -1140
- package/dist/image-editor/index.d.cts +1 -0
- package/dist/image-editor/index.d.ts +1 -0
- package/dist/image-editor/index.js +660 -32
- package/dist/image-editor/layers/edge-color.d.cts +27 -0
- package/dist/image-editor/layers/edge-color.d.ts +27 -0
- package/dist/image-editor/layers/serialize.d.cts +13 -0
- package/dist/image-editor/layers/serialize.d.ts +13 -0
- package/dist/image-editor/selection/index.d.cts +1 -0
- package/dist/image-editor/selection/index.d.ts +1 -0
- package/dist/image-editor/selection/inspect.d.cts +70 -0
- package/dist/image-editor/selection/inspect.d.ts +70 -0
- package/dist/image-editor/selection-worker.cjs +4 -4
- package/dist/image-editor/selection-worker.js +2 -2
- package/dist/paint-editor/index.cjs +79 -79
- package/dist/paint-editor/index.js +3 -3
- package/dist/raster/compositor.d.cts +10 -1
- package/dist/raster/compositor.d.ts +10 -1
- package/dist/raster/deep-compositor.d.cts +1 -1
- package/dist/raster/deep-compositor.d.ts +1 -1
- package/dist/raster/index.cjs +4 -2
- package/dist/raster/index.js +3 -1
- package/dist/raster/layers.d.cts +16 -0
- package/dist/raster/layers.d.ts +16 -0
- package/package.json +1 -1
- package/skills/pixerate-image-editor/SKILL.md +9 -6
- package/skills/pixerate-image-editor/references/paths.md +12 -0
- package/skills/pixerate-image-selection-masking/SKILL.md +17 -17
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Edge colour on a layer's soft edge (`LayerEdgeColor`): decontamination and despill, run over the
|
|
3
|
+
* canvas by the compositor from the layer's own pixels and its mask, so nothing is baked. The live
|
|
4
|
+
* edge cast (`ambient`) needs what is behind the layer and runs in the compositor's blend step.
|
|
5
|
+
*/
|
|
6
|
+
import type { LayerEdgeColor, RasterMask } from '../../raster/layers.cjs';
|
|
7
|
+
/** How far (px) the old background's colour is looked for around the edge. */
|
|
8
|
+
export declare const EDGE_COLOR_RADIUS = 8;
|
|
9
|
+
/** True when decontamination or despill is on (they need the layer's mask). */
|
|
10
|
+
export declare function hasEdgeUnmix(edge: LayerEdgeColor | undefined): boolean;
|
|
11
|
+
/**
|
|
12
|
+
* A mask's coverage (0..255) over the canvas, `width × height`, for a layer at `offset`: the
|
|
13
|
+
* painted mask with its feather (density only changes how much shows, not the matte).
|
|
14
|
+
*/
|
|
15
|
+
export declare function maskCoverageOverCanvas(mask: RasterMask, ox: number, oy: number, width: number, height: number): Uint8ClampedArray;
|
|
16
|
+
/** True when a coverage has a soft band (some pixels partly covered). */
|
|
17
|
+
export declare function hasSoftBand(coverage: ArrayLike<number>): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Despill: along a soft edge, takes out (by `amount`, 0..1) the part of each pixel's colour that
|
|
20
|
+
* points the way of the old background's hue (its local mean, from what is fully outside within
|
|
21
|
+
* `radius`). Luminance is kept, pixels fully in or out are unchanged, and the outer edge (more
|
|
22
|
+
* background) gets the most. It does not remove light that bounced onto the subject itself.
|
|
23
|
+
* Works in place on RGBA `rgba` with `coverage` (0..255) over the same `w × h`.
|
|
24
|
+
*/
|
|
25
|
+
export declare function despillEdge(rgba: Uint8ClampedArray, coverage: ArrayLike<number>, w: number, h: number, amount: number, radius?: number): void;
|
|
26
|
+
/** Decontamination, then despill, of canvas RGBA `rgba` (`w × h`) in place, given the mask's coverage. */
|
|
27
|
+
export declare function applyEdgeUnmix(rgba: Uint8ClampedArray, coverage: ArrayLike<number>, w: number, h: number, edge: LayerEdgeColor): void;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Edge colour on a layer's soft edge (`LayerEdgeColor`): decontamination and despill, run over the
|
|
3
|
+
* canvas by the compositor from the layer's own pixels and its mask, so nothing is baked. The live
|
|
4
|
+
* edge cast (`ambient`) needs what is behind the layer and runs in the compositor's blend step.
|
|
5
|
+
*/
|
|
6
|
+
import type { LayerEdgeColor, RasterMask } from '../../raster/layers.js';
|
|
7
|
+
/** How far (px) the old background's colour is looked for around the edge. */
|
|
8
|
+
export declare const EDGE_COLOR_RADIUS = 8;
|
|
9
|
+
/** True when decontamination or despill is on (they need the layer's mask). */
|
|
10
|
+
export declare function hasEdgeUnmix(edge: LayerEdgeColor | undefined): boolean;
|
|
11
|
+
/**
|
|
12
|
+
* A mask's coverage (0..255) over the canvas, `width × height`, for a layer at `offset`: the
|
|
13
|
+
* painted mask with its feather (density only changes how much shows, not the matte).
|
|
14
|
+
*/
|
|
15
|
+
export declare function maskCoverageOverCanvas(mask: RasterMask, ox: number, oy: number, width: number, height: number): Uint8ClampedArray;
|
|
16
|
+
/** True when a coverage has a soft band (some pixels partly covered). */
|
|
17
|
+
export declare function hasSoftBand(coverage: ArrayLike<number>): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Despill: along a soft edge, takes out (by `amount`, 0..1) the part of each pixel's colour that
|
|
20
|
+
* points the way of the old background's hue (its local mean, from what is fully outside within
|
|
21
|
+
* `radius`). Luminance is kept, pixels fully in or out are unchanged, and the outer edge (more
|
|
22
|
+
* background) gets the most. It does not remove light that bounced onto the subject itself.
|
|
23
|
+
* Works in place on RGBA `rgba` with `coverage` (0..255) over the same `w × h`.
|
|
24
|
+
*/
|
|
25
|
+
export declare function despillEdge(rgba: Uint8ClampedArray, coverage: ArrayLike<number>, w: number, h: number, amount: number, radius?: number): void;
|
|
26
|
+
/** Decontamination, then despill, of canvas RGBA `rgba` (`w × h`) in place, given the mask's coverage. */
|
|
27
|
+
export declare function applyEdgeUnmix(rgba: Uint8ClampedArray, coverage: ArrayLike<number>, w: number, h: number, edge: LayerEdgeColor): void;
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema version 3 of the image editor document: the layer tree, with pixel layers and painted
|
|
3
|
+
* masks stored as PNG assets (cropped to their content and placed by position), plus the
|
|
4
|
+
* document-level crop, transform, output opacity, migrated blur and selection.
|
|
5
|
+
*
|
|
6
|
+
* Encoding is synchronous and exact (see `png.ts`). Each surface's encoding is memoised, so
|
|
7
|
+
* saving an unchanged layer again costs nothing.
|
|
8
|
+
*/
|
|
9
|
+
import type { LayerEdgeColor } from '../../raster/layers.cjs';
|
|
1
10
|
import type { SerializedDocumentPath } from '../paths.cjs';
|
|
2
11
|
import type { Annotation, CropBox, DepthMaskOptions, ImageTransform } from '../types.cjs';
|
|
3
12
|
import type { SerializedSelection } from '../selection/mask.cjs';
|
|
@@ -36,6 +45,8 @@ interface SerializedLayerBase {
|
|
|
36
45
|
vectorMask?: SerializedVectorMask;
|
|
37
46
|
locks?: LayerLocks;
|
|
38
47
|
effects?: SerializedLayerEffects;
|
|
48
|
+
/** Edge colour amounts 0..1 and the cast colour (see `LayerEdgeColor`). */
|
|
49
|
+
edge?: LayerEdgeColor;
|
|
39
50
|
}
|
|
40
51
|
/** A stored vector mask: its components as JSON (document pixels) and its properties. */
|
|
41
52
|
export interface SerializedVectorMask {
|
|
@@ -271,6 +282,8 @@ export interface SerializeContext {
|
|
|
271
282
|
/** Stores a smart object's contents (once per id). Without it, smart objects cannot be written. */
|
|
272
283
|
addContents?(contents: SmartContents): void;
|
|
273
284
|
}
|
|
285
|
+
/** Stored edge colour, with amounts clamped to 0..1 (none when nothing is on). */
|
|
286
|
+
export declare function readEdgeColor(raw: unknown): LayerEdgeColor | undefined;
|
|
274
287
|
export declare function serializeEffects(effects: LayerEffects): SerializedLayerEffects;
|
|
275
288
|
/** Reads stored effects (leniently: broken effects are dropped), or `undefined`. */
|
|
276
289
|
export declare function deserializeEffects(raw: unknown): LayerEffects | undefined;
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema version 3 of the image editor document: the layer tree, with pixel layers and painted
|
|
3
|
+
* masks stored as PNG assets (cropped to their content and placed by position), plus the
|
|
4
|
+
* document-level crop, transform, output opacity, migrated blur and selection.
|
|
5
|
+
*
|
|
6
|
+
* Encoding is synchronous and exact (see `png.ts`). Each surface's encoding is memoised, so
|
|
7
|
+
* saving an unchanged layer again costs nothing.
|
|
8
|
+
*/
|
|
9
|
+
import type { LayerEdgeColor } from '../../raster/layers.js';
|
|
1
10
|
import type { SerializedDocumentPath } from '../paths.js';
|
|
2
11
|
import type { Annotation, CropBox, DepthMaskOptions, ImageTransform } from '../types.js';
|
|
3
12
|
import type { SerializedSelection } from '../selection/mask.js';
|
|
@@ -36,6 +45,8 @@ interface SerializedLayerBase {
|
|
|
36
45
|
vectorMask?: SerializedVectorMask;
|
|
37
46
|
locks?: LayerLocks;
|
|
38
47
|
effects?: SerializedLayerEffects;
|
|
48
|
+
/** Edge colour amounts 0..1 and the cast colour (see `LayerEdgeColor`). */
|
|
49
|
+
edge?: LayerEdgeColor;
|
|
39
50
|
}
|
|
40
51
|
/** A stored vector mask: its components as JSON (document pixels) and its properties. */
|
|
41
52
|
export interface SerializedVectorMask {
|
|
@@ -271,6 +282,8 @@ export interface SerializeContext {
|
|
|
271
282
|
/** Stores a smart object's contents (once per id). Without it, smart objects cannot be written. */
|
|
272
283
|
addContents?(contents: SmartContents): void;
|
|
273
284
|
}
|
|
285
|
+
/** Stored edge colour, with amounts clamped to 0..1 (none when nothing is on). */
|
|
286
|
+
export declare function readEdgeColor(raw: unknown): LayerEdgeColor | undefined;
|
|
274
287
|
export declare function serializeEffects(effects: LayerEffects): SerializedLayerEffects;
|
|
275
288
|
/** Reads stored effects (leniently: broken effects are dropped), or `undefined`. */
|
|
276
289
|
export declare function deserializeEffects(raw: unknown): LayerEffects | undefined;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A measured report on a mask's edge (`inspect_mask_edge`), so an agent can check a selection or
|
|
3
|
+
* a mask without looking at it: halo (old background left just inside the edge), how much of the
|
|
4
|
+
* edge sits on the image's own edges, how jagged the outline is, how soft it is, holes and stray
|
|
5
|
+
* islands, and the worst places to look at. Read-only; works in the mask's bounds.
|
|
6
|
+
*/
|
|
7
|
+
import type { CropBox } from '../types.cjs';
|
|
8
|
+
import type { PixelBuffer, SelectionMask } from './mask.cjs';
|
|
9
|
+
export interface InspectMaskEdgeOptions {
|
|
10
|
+
/** Holes and islands smaller than this many pixels are left out (default 16). */
|
|
11
|
+
minArea?: number;
|
|
12
|
+
}
|
|
13
|
+
/** A hole or island: its area in pixels and bounds. */
|
|
14
|
+
export interface MaskRegion {
|
|
15
|
+
area: number;
|
|
16
|
+
bounds: CropBox;
|
|
17
|
+
}
|
|
18
|
+
export interface MaskEdgeReport {
|
|
19
|
+
/** Pixels at least half covered. */
|
|
20
|
+
area: number;
|
|
21
|
+
bounds: CropBox;
|
|
22
|
+
/** Pixels along the edge (inside, at least half covered, beside one less than half). */
|
|
23
|
+
edgeLength: number;
|
|
24
|
+
/**
|
|
25
|
+
* 0–1: how close the colour just inside the edge is to the colour just outside it, relative to
|
|
26
|
+
* the colour further in (0: the edge ring looks like the subject; 1: it looks like the
|
|
27
|
+
* background). Measured only where the inside and outside differ.
|
|
28
|
+
*/
|
|
29
|
+
haloScore: number;
|
|
30
|
+
/** 0–1: the share of the edge within 2 px of a strong image edge. */
|
|
31
|
+
edgeAlignment: number;
|
|
32
|
+
/** Turning of the outline beyond what closing it needs, in radians per 100 px of outline (0: smooth). */
|
|
33
|
+
jaggedness: number;
|
|
34
|
+
/** 0–1: the share of edge pixels that are partly covered (0 < α < 1). */
|
|
35
|
+
softFraction: number;
|
|
36
|
+
/** Unselected areas enclosed by the selection, largest first (at most 10 listed). */
|
|
37
|
+
holes: {
|
|
38
|
+
count: number;
|
|
39
|
+
totalArea: number;
|
|
40
|
+
largest: MaskRegion[];
|
|
41
|
+
};
|
|
42
|
+
/** Selected pieces apart from the largest one, largest first (at most 10 listed). */
|
|
43
|
+
islands: {
|
|
44
|
+
count: number;
|
|
45
|
+
totalArea: number;
|
|
46
|
+
largest: MaskRegion[];
|
|
47
|
+
};
|
|
48
|
+
/** Up to 5 places to look at first (for `capture_view`), worst first. */
|
|
49
|
+
worst: Array<{
|
|
50
|
+
bounds: CropBox;
|
|
51
|
+
reason: string;
|
|
52
|
+
}>;
|
|
53
|
+
/** Plain-language findings with a suggested fix, empty when the edge looks clean. */
|
|
54
|
+
issues: string[];
|
|
55
|
+
}
|
|
56
|
+
/** Report thresholds (also in the masking skill). */
|
|
57
|
+
export declare const MASK_EDGE_THRESHOLDS: {
|
|
58
|
+
readonly halo: 0.35;
|
|
59
|
+
readonly alignment: 0.5;
|
|
60
|
+
readonly jaggedness: 15;
|
|
61
|
+
readonly soft: 0.9;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Inspects `mask`'s edge against `image` (RGBA, straight alpha, covering document pixels from
|
|
65
|
+
* `image.x`, `image.y`; outside it counts as transparent). Throws for an empty mask.
|
|
66
|
+
*/
|
|
67
|
+
export declare function inspectMaskEdge(mask: SelectionMask, image: PixelBuffer & {
|
|
68
|
+
x: number;
|
|
69
|
+
y: number;
|
|
70
|
+
}, options?: InspectMaskEdgeOptions): MaskEdgeReport;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A measured report on a mask's edge (`inspect_mask_edge`), so an agent can check a selection or
|
|
3
|
+
* a mask without looking at it: halo (old background left just inside the edge), how much of the
|
|
4
|
+
* edge sits on the image's own edges, how jagged the outline is, how soft it is, holes and stray
|
|
5
|
+
* islands, and the worst places to look at. Read-only; works in the mask's bounds.
|
|
6
|
+
*/
|
|
7
|
+
import type { CropBox } from '../types.js';
|
|
8
|
+
import type { PixelBuffer, SelectionMask } from './mask.js';
|
|
9
|
+
export interface InspectMaskEdgeOptions {
|
|
10
|
+
/** Holes and islands smaller than this many pixels are left out (default 16). */
|
|
11
|
+
minArea?: number;
|
|
12
|
+
}
|
|
13
|
+
/** A hole or island: its area in pixels and bounds. */
|
|
14
|
+
export interface MaskRegion {
|
|
15
|
+
area: number;
|
|
16
|
+
bounds: CropBox;
|
|
17
|
+
}
|
|
18
|
+
export interface MaskEdgeReport {
|
|
19
|
+
/** Pixels at least half covered. */
|
|
20
|
+
area: number;
|
|
21
|
+
bounds: CropBox;
|
|
22
|
+
/** Pixels along the edge (inside, at least half covered, beside one less than half). */
|
|
23
|
+
edgeLength: number;
|
|
24
|
+
/**
|
|
25
|
+
* 0–1: how close the colour just inside the edge is to the colour just outside it, relative to
|
|
26
|
+
* the colour further in (0: the edge ring looks like the subject; 1: it looks like the
|
|
27
|
+
* background). Measured only where the inside and outside differ.
|
|
28
|
+
*/
|
|
29
|
+
haloScore: number;
|
|
30
|
+
/** 0–1: the share of the edge within 2 px of a strong image edge. */
|
|
31
|
+
edgeAlignment: number;
|
|
32
|
+
/** Turning of the outline beyond what closing it needs, in radians per 100 px of outline (0: smooth). */
|
|
33
|
+
jaggedness: number;
|
|
34
|
+
/** 0–1: the share of edge pixels that are partly covered (0 < α < 1). */
|
|
35
|
+
softFraction: number;
|
|
36
|
+
/** Unselected areas enclosed by the selection, largest first (at most 10 listed). */
|
|
37
|
+
holes: {
|
|
38
|
+
count: number;
|
|
39
|
+
totalArea: number;
|
|
40
|
+
largest: MaskRegion[];
|
|
41
|
+
};
|
|
42
|
+
/** Selected pieces apart from the largest one, largest first (at most 10 listed). */
|
|
43
|
+
islands: {
|
|
44
|
+
count: number;
|
|
45
|
+
totalArea: number;
|
|
46
|
+
largest: MaskRegion[];
|
|
47
|
+
};
|
|
48
|
+
/** Up to 5 places to look at first (for `capture_view`), worst first. */
|
|
49
|
+
worst: Array<{
|
|
50
|
+
bounds: CropBox;
|
|
51
|
+
reason: string;
|
|
52
|
+
}>;
|
|
53
|
+
/** Plain-language findings with a suggested fix, empty when the edge looks clean. */
|
|
54
|
+
issues: string[];
|
|
55
|
+
}
|
|
56
|
+
/** Report thresholds (also in the masking skill). */
|
|
57
|
+
export declare const MASK_EDGE_THRESHOLDS: {
|
|
58
|
+
readonly halo: 0.35;
|
|
59
|
+
readonly alignment: 0.5;
|
|
60
|
+
readonly jaggedness: 15;
|
|
61
|
+
readonly soft: 0.9;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Inspects `mask`'s edge against `image` (RGBA, straight alpha, covering document pixels from
|
|
65
|
+
* `image.x`, `image.y`; outside it counts as transparent). Throws for an empty mask.
|
|
66
|
+
*/
|
|
67
|
+
export declare function inspectMaskEdge(mask: SelectionMask, image: PixelBuffer & {
|
|
68
|
+
x: number;
|
|
69
|
+
y: number;
|
|
70
|
+
}, options?: InspectMaskEdgeOptions): MaskEdgeReport;
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
require('../chunk-
|
|
3
|
+
var _chunkUC3PWFM3cjs = require('../chunk-UC3PWFM3.cjs');
|
|
4
|
+
require('../chunk-SS53NNZO.cjs');
|
|
5
5
|
require('../chunk-K6PXS6DO.cjs');
|
|
6
6
|
require('../chunk-MQDIP4CF.cjs');
|
|
7
7
|
require('../chunk-474IQG74.cjs');
|
|
8
8
|
|
|
9
9
|
// src/image-editor/selection-worker.ts
|
|
10
10
|
if (typeof self !== "undefined" && typeof window === "undefined" && typeof self.postMessage === "function") {
|
|
11
|
-
|
|
11
|
+
_chunkUC3PWFM3cjs.startSelectionWorker.call(void 0, self);
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
exports.startSelectionWorker =
|
|
15
|
+
exports.startSelectionWorker = _chunkUC3PWFM3cjs.startSelectionWorker;
|