@pixerate/editor 0.96.0 → 0.98.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/THIRD_PARTY_NOTICES.md +4 -2
- package/dist/animation-editor/index.cjs +55 -53
- package/dist/animation-editor/index.cjs.map +1 -1
- package/dist/animation-editor/index.d.cts +3 -2
- package/dist/animation-editor/index.d.ts +3 -2
- package/dist/animation-editor/index.js +11 -9
- package/dist/animation-editor/index.js.map +1 -1
- package/dist/chunk-DWGZUSES.cjs +694 -0
- package/dist/chunk-DWGZUSES.cjs.map +1 -0
- package/dist/chunk-GX332W2C.js +181 -0
- package/dist/chunk-GX332W2C.js.map +1 -0
- package/dist/{chunk-7MD7C6XQ.cjs → chunk-JF5PXN7W.cjs} +96 -744
- package/dist/chunk-JF5PXN7W.cjs.map +1 -0
- package/dist/chunk-KKREERP2.js +694 -0
- package/dist/chunk-KKREERP2.js.map +1 -0
- package/dist/chunk-MUUXNRU4.cjs +181 -0
- package/dist/chunk-MUUXNRU4.cjs.map +1 -0
- package/dist/{chunk-KFTQ2PKP.js → chunk-WIR377F6.js} +1001 -61
- package/dist/chunk-WIR377F6.js.map +1 -0
- package/dist/{chunk-T422YCHR.cjs → chunk-WT6ZAWJP.cjs} +1023 -83
- package/dist/chunk-WT6ZAWJP.cjs.map +1 -0
- package/dist/{chunk-4JLB2USO.js → chunk-YGZNGDIT.js} +45 -693
- package/dist/chunk-YGZNGDIT.js.map +1 -0
- package/dist/image-editor/index.cjs +1519 -360
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.d.cts +378 -5
- package/dist/image-editor/index.d.ts +378 -5
- package/dist/image-editor/index.js +1244 -85
- package/dist/image-editor/index.js.map +1 -1
- package/dist/raster/index.cjs +25 -2
- package/dist/raster/index.cjs.map +1 -1
- package/dist/raster/index.d.cts +143 -4
- package/dist/raster/index.d.ts +143 -4
- package/dist/raster/index.js +25 -2
- package/dist/{svg-ymShkNtu.d.cts → svg-C9r284x8.d.cts} +6 -9
- package/dist/{svg-Dh17jCyA.d.ts → svg-MVKBqwD4.d.ts} +6 -9
- package/dist/types-CwMPoRMU.d.cts +40 -0
- package/dist/types-CwMPoRMU.d.ts +40 -0
- package/dist/vector/index.cjs +490 -554
- package/dist/vector/index.cjs.map +1 -1
- package/dist/vector/index.d.cts +154 -292
- package/dist/vector/index.d.ts +154 -292
- package/dist/vector/index.js +91 -155
- package/dist/vector/index.js.map +1 -1
- package/dist/warp-B8rAguzs.d.ts +165 -0
- package/dist/warp-nYs2DPrx.d.cts +165 -0
- package/package.json +1 -1
- package/skills/pixerate-image-editor/SKILL.md +49 -3
- package/dist/chunk-4JLB2USO.js.map +0 -1
- package/dist/chunk-7MD7C6XQ.cjs.map +0 -1
- package/dist/chunk-KFTQ2PKP.js.map +0 -1
- package/dist/chunk-T422YCHR.cjs.map +0 -1
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { H as Homography, V as Vec2, B as Box, Q as Quad, A as AffineMatrix, W as WarpStyle, a as WarpMesh } from './types-CwMPoRMU.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Perspective (projective) maps between quadrilaterals: Free Distort and Perspective in both the
|
|
5
|
+
* vector and the image editor. Pure maths; degenerate or non-finite input gives `null` instead of
|
|
6
|
+
* NaNs.
|
|
7
|
+
*
|
|
8
|
+
* Ported from ArtCraft (MIT OR Apache-2.0, © ArtCraft Team and contributors; see
|
|
9
|
+
* THIRD_PARTY_NOTICES.md): pdfcraft `crates/geom/src/perspective.rs` (`Homography::from_points`,
|
|
10
|
+
* `Homography::apply`, `solve8`, `order_quad`) and photocraft `crates/algo/src/transform.rs`
|
|
11
|
+
* (`Homography::square_to_quad`, `rect_to_quad`, `inverse`, `mul`, `local_scale`, `front_side`,
|
|
12
|
+
* `warp_output_bounds`, `convex_quad`).
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Gaussian elimination with partial pivoting on an 8×8 system (the 9th column of each row is the
|
|
17
|
+
* right-hand side). Null when the system is singular.
|
|
18
|
+
*/
|
|
19
|
+
declare function solve8(rows: readonly (readonly number[])[]): number[] | null;
|
|
20
|
+
/** The image of `p`, or null where the map sends it to infinity. */
|
|
21
|
+
declare function applyHomography(h: Homography, p: Vec2): Vec2 | null;
|
|
22
|
+
/**
|
|
23
|
+
* The projective map that takes each of `from` to the point at the same index of `to`. Null when
|
|
24
|
+
* three of either set are collinear or a coordinate is not finite.
|
|
25
|
+
*/
|
|
26
|
+
declare function homographyFromPoints(from: readonly Vec2[], to: readonly Vec2[]): Homography | null;
|
|
27
|
+
/**
|
|
28
|
+
* Whether `h` maps the whole convex quad `quad` without sending any of it through infinity (the
|
|
29
|
+
* denominator keeps one sign over it): what a usable distortion needs.
|
|
30
|
+
*/
|
|
31
|
+
declare function homographyKeepsQuad(h: Homography, quad: readonly Vec2[]): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* The four corners in reading order for a y-down space: top-left, top-right, bottom-right,
|
|
34
|
+
* bottom-left, whatever order they come in. Null unless they form a convex quadrilateral with a
|
|
35
|
+
* non-negligible area.
|
|
36
|
+
*/
|
|
37
|
+
declare function orderQuad(points: readonly Vec2[]): Vec2[] | null;
|
|
38
|
+
/** The inverse map, or null for a singular one. */
|
|
39
|
+
declare function invertHomography(m: Homography): Homography | null;
|
|
40
|
+
/** An affine matrix (SVG order) as a homography. */
|
|
41
|
+
declare function homographyFromAffine(m: AffineMatrix): Homography;
|
|
42
|
+
/**
|
|
43
|
+
* The map taking box `r`'s corners onto `quad` (TL, TR, BR, BL), exact for parallelograms (then
|
|
44
|
+
* affine). Null for an empty box, a non-finite or degenerate quad, or a singular result.
|
|
45
|
+
*/
|
|
46
|
+
declare function rectToQuad(r: Box, quad: readonly Vec2[]): Homography | null;
|
|
47
|
+
/** Box `r`'s corners as a quad (TL, TR, BR, BL). */
|
|
48
|
+
declare function boxQuad(r: Box): Quad;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Warp geometry shared by the vector editor's envelopes and the image editor's Free Transform
|
|
52
|
+
* warp: preset warp styles and editable Bézier meshes, both forward maps from a source box onto
|
|
53
|
+
* the plane.
|
|
54
|
+
*
|
|
55
|
+
* - **Presets** (`WarpStyle`, Photoshop's fifteen with bend and horizontal / vertical distortion
|
|
56
|
+
* in percent): each is one bicubic Bézier patch whose 4 × 4 control grid follows the bend
|
|
57
|
+
* (`warpPresetGrid`). Every preset is the identity at bend 0 and continuous in it.
|
|
58
|
+
* - **Meshes** (`WarpMesh`): a grid of bicubic patches. Splitting a mesh (`splitWarpMeshU` / `V`)
|
|
59
|
+
* is an exact de Casteljau subdivision, so it never changes the shape, and a preset turns into
|
|
60
|
+
* an editable mesh of any size exactly.
|
|
61
|
+
*
|
|
62
|
+
* Ported from ArtCraft (MIT OR Apache-2.0, © ArtCraft Team and contributors; see
|
|
63
|
+
* THIRD_PARTY_NOTICES.md): photocraft `crates/geom/src/warp.rs` (`WarpStyle`, `StyleWarp`,
|
|
64
|
+
* `rest_grid`, `edge_arc`, `arc_grid`, `blend_rows`, `preset_grid`, `bernstein`, `split_cubic`,
|
|
65
|
+
* `BERN_INV`, and `BezierMesh`: `identity`, `fit`, `eval`, `split_u`, `split_v`, `remove_split_u`,
|
|
66
|
+
* `transpose`, `map_points`, `param_at`, `pull`, `smooth_lines`, `drag_point`, `control_bounds`;
|
|
67
|
+
* `Warp::map` and `Warp::to_mesh`).
|
|
68
|
+
*/
|
|
69
|
+
|
|
70
|
+
/** The fifteen presets in Photoshop's menu order. */
|
|
71
|
+
declare const WARP_STYLES: readonly WarpStyle[];
|
|
72
|
+
declare const WARP_STYLE_LABELS: Readonly<Record<WarpStyle, string>>;
|
|
73
|
+
/**
|
|
74
|
+
* A preset as a Bézier control grid (rows of `[x, y]` in box units, y down). `b`, `hd`, `vd` are
|
|
75
|
+
* the bend and the horizontal / vertical distortion as fractions (−1…1); `aspect` is the box's
|
|
76
|
+
* height over its width. The arc family stays circular in pixels, the other offsets scale with the
|
|
77
|
+
* box, and a vertical warp is the horizontal one with the axes (and distortions) swapped.
|
|
78
|
+
*/
|
|
79
|
+
declare function warpPresetGrid(style: WarpStyle, b: number, hd: number, vd: number, vertical: boolean, aspect: number): [number, number][][];
|
|
80
|
+
/** A preset warp's settings (bend and distortions in percent, −100…100). */
|
|
81
|
+
interface WarpPreset {
|
|
82
|
+
style: WarpStyle;
|
|
83
|
+
bend: number;
|
|
84
|
+
horizontal?: number;
|
|
85
|
+
vertical?: number;
|
|
86
|
+
/** Bend along the vertical axis. */
|
|
87
|
+
orientation?: 'horizontal' | 'vertical';
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* A preset as one Bézier patch over `bounds` (points in the bounds' space), or null when it
|
|
91
|
+
* changes nothing (an unknown style, all-zero amounts, or an empty box).
|
|
92
|
+
*/
|
|
93
|
+
declare function warpPresetMesh(preset: WarpPreset, bounds: Box): WarpMesh | null;
|
|
94
|
+
/** Control points per row. */
|
|
95
|
+
declare const warpMeshColumns: (m: WarpMesh) => number;
|
|
96
|
+
/** Control point rows. */
|
|
97
|
+
declare const warpMeshRows: (m: WarpMesh) => number;
|
|
98
|
+
/** Whether a mesh is well formed: knots from 0 to 1 increasing, the right number of finite points. */
|
|
99
|
+
declare function isValidWarpMesh(m: unknown): m is WarpMesh;
|
|
100
|
+
/** Fits a mesh with patch boundaries `us` / `vs` to the map `f` (box fractions → output) by interpolating it at each patch's thirds. Exact for bicubic maps (affine maps included). */
|
|
101
|
+
declare function fitWarpMesh(f: (s: number, t: number) => Vec2, us: readonly number[], vs: readonly number[]): WarpMesh;
|
|
102
|
+
/** The identity mesh over `bounds` with `columns × rows` patches. */
|
|
103
|
+
declare function identityWarpMesh(bounds: Box, columns?: number, rows?: number): WarpMesh;
|
|
104
|
+
/** The surface at box fractions `(s, t)`. */
|
|
105
|
+
declare function evalWarpMesh(m: WarpMesh, s: number, t: number): Vec2;
|
|
106
|
+
/** The mesh with the patch column holding `s` split at `s` (exact). Null when `s` is on or too close to a boundary. */
|
|
107
|
+
declare function splitWarpMeshU(m: WarpMesh, s: number): WarpMesh | null;
|
|
108
|
+
/** The mesh with the patch row holding `t` split at `t` (exact). */
|
|
109
|
+
declare function splitWarpMeshV(m: WarpMesh, t: number): WarpMesh | null;
|
|
110
|
+
/**
|
|
111
|
+
* The mesh without interior vertical boundary `k` (1 … us.length − 2), its two patch columns
|
|
112
|
+
* merged: exact when they came from an unedited split; otherwise the outer control points stay and
|
|
113
|
+
* the inner handles are extrapolated.
|
|
114
|
+
*/
|
|
115
|
+
declare function removeWarpMeshSplitU(m: WarpMesh, k: number): WarpMesh | null;
|
|
116
|
+
/** Removes interior horizontal boundary `k`. */
|
|
117
|
+
declare function removeWarpMeshSplitV(m: WarpMesh, k: number): WarpMesh | null;
|
|
118
|
+
/** Every control point through `f` (exact for affine maps). */
|
|
119
|
+
declare function mapWarpMeshPoints(m: WarpMesh, f: (p: Vec2) => Vec2): WarpMesh;
|
|
120
|
+
/**
|
|
121
|
+
* The mesh with `columns × rows` patches over the same surface: split exactly when its knots are
|
|
122
|
+
* a subset of the new even ones (a one-patch mesh always is), otherwise refitted.
|
|
123
|
+
*/
|
|
124
|
+
declare function resizeWarpMesh(m: WarpMesh, columns: number, rows: number): WarpMesh;
|
|
125
|
+
/** Bounding box of the control points (the surface lies inside it). */
|
|
126
|
+
declare function warpMeshControlBounds(m: WarpMesh): Box;
|
|
127
|
+
/** Box fractions `(s, t)` whose surface point is nearest `p` (a coarse search, then Newton steps). */
|
|
128
|
+
declare function warpMeshParamAt(m: WarpMesh, p: Vec2): {
|
|
129
|
+
s: number;
|
|
130
|
+
t: number;
|
|
131
|
+
distance: number;
|
|
132
|
+
};
|
|
133
|
+
/**
|
|
134
|
+
* `base` with control point `index` dragged by `d`, keeping the surface smooth across the grid
|
|
135
|
+
* lines: an anchor moves with the eight points around it as one block; a handle moves with the two
|
|
136
|
+
* points beside it across its line, and the handle opposite it on the same anchor turns the other
|
|
137
|
+
* way (with its two neighbours), so the line keeps passing straight through the anchor. An inner
|
|
138
|
+
* point of a patch moves alone.
|
|
139
|
+
*/
|
|
140
|
+
declare function dragWarpMeshPoint(base: WarpMesh, index: number, d: Vec2): WarpMesh;
|
|
141
|
+
/**
|
|
142
|
+
* `base` with its surface point at box fractions `(s, t)` pulled by `d`, the way dragging inside a
|
|
143
|
+
* patch works: interior anchors within about two cells follow by a share of `d` that fades with
|
|
144
|
+
* distance (each with its block of handles, so grid lines stay smooth); the outer border stays
|
|
145
|
+
* pinned unless the grab is near it, and then it bows; the four corners never move. The grabbed
|
|
146
|
+
* patch's inner points (and, near the border, the border's handles) make up the rest, so the
|
|
147
|
+
* grabbed point lands exactly at its start + `d`.
|
|
148
|
+
*/
|
|
149
|
+
declare function pullWarpMesh(base: WarpMesh, s: number, t: number, d: Vec2): WarpMesh;
|
|
150
|
+
/**
|
|
151
|
+
* The control points an editor shows: the anchors (where grid lines cross) and the handles along
|
|
152
|
+
* the grid lines, each with the anchor it belongs to. Points inside a patch are left out (drag
|
|
153
|
+
* inside a patch to pull the surface instead).
|
|
154
|
+
*/
|
|
155
|
+
declare function warpMeshEditPoints(m: WarpMesh): {
|
|
156
|
+
anchors: number[];
|
|
157
|
+
handles: {
|
|
158
|
+
index: number;
|
|
159
|
+
anchor: number;
|
|
160
|
+
}[];
|
|
161
|
+
};
|
|
162
|
+
/** The mesh's grid lines (patch borders) as cubics `[p0, p1, p2, p3]`. */
|
|
163
|
+
declare function warpMeshGridCurves(m: WarpMesh): Vec2[][];
|
|
164
|
+
|
|
165
|
+
export { warpPresetMesh as A, boxQuad as B, homographyFromAffine as C, invertHomography as D, rectToQuad as E, WARP_STYLES as W, WARP_STYLE_LABELS as a, type WarpPreset as b, applyHomography as c, dragWarpMeshPoint as d, evalWarpMesh as e, fitWarpMesh as f, removeWarpMeshSplitV as g, resizeWarpMesh as h, isValidWarpMesh as i, splitWarpMeshU as j, splitWarpMeshV as k, homographyFromPoints as l, mapWarpMeshPoints as m, homographyKeepsQuad as n, orderQuad as o, pullWarpMesh as p, identityWarpMesh as q, removeWarpMeshSplitU as r, solve8 as s, warpMeshControlBounds as t, warpMeshEditPoints as u, warpMeshGridCurves as v, warpMeshColumns as w, warpMeshParamAt as x, warpMeshRows as y, warpPresetGrid as z };
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { H as Homography, V as Vec2, B as Box, Q as Quad, A as AffineMatrix, W as WarpStyle, a as WarpMesh } from './types-CwMPoRMU.cjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Perspective (projective) maps between quadrilaterals: Free Distort and Perspective in both the
|
|
5
|
+
* vector and the image editor. Pure maths; degenerate or non-finite input gives `null` instead of
|
|
6
|
+
* NaNs.
|
|
7
|
+
*
|
|
8
|
+
* Ported from ArtCraft (MIT OR Apache-2.0, © ArtCraft Team and contributors; see
|
|
9
|
+
* THIRD_PARTY_NOTICES.md): pdfcraft `crates/geom/src/perspective.rs` (`Homography::from_points`,
|
|
10
|
+
* `Homography::apply`, `solve8`, `order_quad`) and photocraft `crates/algo/src/transform.rs`
|
|
11
|
+
* (`Homography::square_to_quad`, `rect_to_quad`, `inverse`, `mul`, `local_scale`, `front_side`,
|
|
12
|
+
* `warp_output_bounds`, `convex_quad`).
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Gaussian elimination with partial pivoting on an 8×8 system (the 9th column of each row is the
|
|
17
|
+
* right-hand side). Null when the system is singular.
|
|
18
|
+
*/
|
|
19
|
+
declare function solve8(rows: readonly (readonly number[])[]): number[] | null;
|
|
20
|
+
/** The image of `p`, or null where the map sends it to infinity. */
|
|
21
|
+
declare function applyHomography(h: Homography, p: Vec2): Vec2 | null;
|
|
22
|
+
/**
|
|
23
|
+
* The projective map that takes each of `from` to the point at the same index of `to`. Null when
|
|
24
|
+
* three of either set are collinear or a coordinate is not finite.
|
|
25
|
+
*/
|
|
26
|
+
declare function homographyFromPoints(from: readonly Vec2[], to: readonly Vec2[]): Homography | null;
|
|
27
|
+
/**
|
|
28
|
+
* Whether `h` maps the whole convex quad `quad` without sending any of it through infinity (the
|
|
29
|
+
* denominator keeps one sign over it): what a usable distortion needs.
|
|
30
|
+
*/
|
|
31
|
+
declare function homographyKeepsQuad(h: Homography, quad: readonly Vec2[]): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* The four corners in reading order for a y-down space: top-left, top-right, bottom-right,
|
|
34
|
+
* bottom-left, whatever order they come in. Null unless they form a convex quadrilateral with a
|
|
35
|
+
* non-negligible area.
|
|
36
|
+
*/
|
|
37
|
+
declare function orderQuad(points: readonly Vec2[]): Vec2[] | null;
|
|
38
|
+
/** The inverse map, or null for a singular one. */
|
|
39
|
+
declare function invertHomography(m: Homography): Homography | null;
|
|
40
|
+
/** An affine matrix (SVG order) as a homography. */
|
|
41
|
+
declare function homographyFromAffine(m: AffineMatrix): Homography;
|
|
42
|
+
/**
|
|
43
|
+
* The map taking box `r`'s corners onto `quad` (TL, TR, BR, BL), exact for parallelograms (then
|
|
44
|
+
* affine). Null for an empty box, a non-finite or degenerate quad, or a singular result.
|
|
45
|
+
*/
|
|
46
|
+
declare function rectToQuad(r: Box, quad: readonly Vec2[]): Homography | null;
|
|
47
|
+
/** Box `r`'s corners as a quad (TL, TR, BR, BL). */
|
|
48
|
+
declare function boxQuad(r: Box): Quad;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Warp geometry shared by the vector editor's envelopes and the image editor's Free Transform
|
|
52
|
+
* warp: preset warp styles and editable Bézier meshes, both forward maps from a source box onto
|
|
53
|
+
* the plane.
|
|
54
|
+
*
|
|
55
|
+
* - **Presets** (`WarpStyle`, Photoshop's fifteen with bend and horizontal / vertical distortion
|
|
56
|
+
* in percent): each is one bicubic Bézier patch whose 4 × 4 control grid follows the bend
|
|
57
|
+
* (`warpPresetGrid`). Every preset is the identity at bend 0 and continuous in it.
|
|
58
|
+
* - **Meshes** (`WarpMesh`): a grid of bicubic patches. Splitting a mesh (`splitWarpMeshU` / `V`)
|
|
59
|
+
* is an exact de Casteljau subdivision, so it never changes the shape, and a preset turns into
|
|
60
|
+
* an editable mesh of any size exactly.
|
|
61
|
+
*
|
|
62
|
+
* Ported from ArtCraft (MIT OR Apache-2.0, © ArtCraft Team and contributors; see
|
|
63
|
+
* THIRD_PARTY_NOTICES.md): photocraft `crates/geom/src/warp.rs` (`WarpStyle`, `StyleWarp`,
|
|
64
|
+
* `rest_grid`, `edge_arc`, `arc_grid`, `blend_rows`, `preset_grid`, `bernstein`, `split_cubic`,
|
|
65
|
+
* `BERN_INV`, and `BezierMesh`: `identity`, `fit`, `eval`, `split_u`, `split_v`, `remove_split_u`,
|
|
66
|
+
* `transpose`, `map_points`, `param_at`, `pull`, `smooth_lines`, `drag_point`, `control_bounds`;
|
|
67
|
+
* `Warp::map` and `Warp::to_mesh`).
|
|
68
|
+
*/
|
|
69
|
+
|
|
70
|
+
/** The fifteen presets in Photoshop's menu order. */
|
|
71
|
+
declare const WARP_STYLES: readonly WarpStyle[];
|
|
72
|
+
declare const WARP_STYLE_LABELS: Readonly<Record<WarpStyle, string>>;
|
|
73
|
+
/**
|
|
74
|
+
* A preset as a Bézier control grid (rows of `[x, y]` in box units, y down). `b`, `hd`, `vd` are
|
|
75
|
+
* the bend and the horizontal / vertical distortion as fractions (−1…1); `aspect` is the box's
|
|
76
|
+
* height over its width. The arc family stays circular in pixels, the other offsets scale with the
|
|
77
|
+
* box, and a vertical warp is the horizontal one with the axes (and distortions) swapped.
|
|
78
|
+
*/
|
|
79
|
+
declare function warpPresetGrid(style: WarpStyle, b: number, hd: number, vd: number, vertical: boolean, aspect: number): [number, number][][];
|
|
80
|
+
/** A preset warp's settings (bend and distortions in percent, −100…100). */
|
|
81
|
+
interface WarpPreset {
|
|
82
|
+
style: WarpStyle;
|
|
83
|
+
bend: number;
|
|
84
|
+
horizontal?: number;
|
|
85
|
+
vertical?: number;
|
|
86
|
+
/** Bend along the vertical axis. */
|
|
87
|
+
orientation?: 'horizontal' | 'vertical';
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* A preset as one Bézier patch over `bounds` (points in the bounds' space), or null when it
|
|
91
|
+
* changes nothing (an unknown style, all-zero amounts, or an empty box).
|
|
92
|
+
*/
|
|
93
|
+
declare function warpPresetMesh(preset: WarpPreset, bounds: Box): WarpMesh | null;
|
|
94
|
+
/** Control points per row. */
|
|
95
|
+
declare const warpMeshColumns: (m: WarpMesh) => number;
|
|
96
|
+
/** Control point rows. */
|
|
97
|
+
declare const warpMeshRows: (m: WarpMesh) => number;
|
|
98
|
+
/** Whether a mesh is well formed: knots from 0 to 1 increasing, the right number of finite points. */
|
|
99
|
+
declare function isValidWarpMesh(m: unknown): m is WarpMesh;
|
|
100
|
+
/** Fits a mesh with patch boundaries `us` / `vs` to the map `f` (box fractions → output) by interpolating it at each patch's thirds. Exact for bicubic maps (affine maps included). */
|
|
101
|
+
declare function fitWarpMesh(f: (s: number, t: number) => Vec2, us: readonly number[], vs: readonly number[]): WarpMesh;
|
|
102
|
+
/** The identity mesh over `bounds` with `columns × rows` patches. */
|
|
103
|
+
declare function identityWarpMesh(bounds: Box, columns?: number, rows?: number): WarpMesh;
|
|
104
|
+
/** The surface at box fractions `(s, t)`. */
|
|
105
|
+
declare function evalWarpMesh(m: WarpMesh, s: number, t: number): Vec2;
|
|
106
|
+
/** The mesh with the patch column holding `s` split at `s` (exact). Null when `s` is on or too close to a boundary. */
|
|
107
|
+
declare function splitWarpMeshU(m: WarpMesh, s: number): WarpMesh | null;
|
|
108
|
+
/** The mesh with the patch row holding `t` split at `t` (exact). */
|
|
109
|
+
declare function splitWarpMeshV(m: WarpMesh, t: number): WarpMesh | null;
|
|
110
|
+
/**
|
|
111
|
+
* The mesh without interior vertical boundary `k` (1 … us.length − 2), its two patch columns
|
|
112
|
+
* merged: exact when they came from an unedited split; otherwise the outer control points stay and
|
|
113
|
+
* the inner handles are extrapolated.
|
|
114
|
+
*/
|
|
115
|
+
declare function removeWarpMeshSplitU(m: WarpMesh, k: number): WarpMesh | null;
|
|
116
|
+
/** Removes interior horizontal boundary `k`. */
|
|
117
|
+
declare function removeWarpMeshSplitV(m: WarpMesh, k: number): WarpMesh | null;
|
|
118
|
+
/** Every control point through `f` (exact for affine maps). */
|
|
119
|
+
declare function mapWarpMeshPoints(m: WarpMesh, f: (p: Vec2) => Vec2): WarpMesh;
|
|
120
|
+
/**
|
|
121
|
+
* The mesh with `columns × rows` patches over the same surface: split exactly when its knots are
|
|
122
|
+
* a subset of the new even ones (a one-patch mesh always is), otherwise refitted.
|
|
123
|
+
*/
|
|
124
|
+
declare function resizeWarpMesh(m: WarpMesh, columns: number, rows: number): WarpMesh;
|
|
125
|
+
/** Bounding box of the control points (the surface lies inside it). */
|
|
126
|
+
declare function warpMeshControlBounds(m: WarpMesh): Box;
|
|
127
|
+
/** Box fractions `(s, t)` whose surface point is nearest `p` (a coarse search, then Newton steps). */
|
|
128
|
+
declare function warpMeshParamAt(m: WarpMesh, p: Vec2): {
|
|
129
|
+
s: number;
|
|
130
|
+
t: number;
|
|
131
|
+
distance: number;
|
|
132
|
+
};
|
|
133
|
+
/**
|
|
134
|
+
* `base` with control point `index` dragged by `d`, keeping the surface smooth across the grid
|
|
135
|
+
* lines: an anchor moves with the eight points around it as one block; a handle moves with the two
|
|
136
|
+
* points beside it across its line, and the handle opposite it on the same anchor turns the other
|
|
137
|
+
* way (with its two neighbours), so the line keeps passing straight through the anchor. An inner
|
|
138
|
+
* point of a patch moves alone.
|
|
139
|
+
*/
|
|
140
|
+
declare function dragWarpMeshPoint(base: WarpMesh, index: number, d: Vec2): WarpMesh;
|
|
141
|
+
/**
|
|
142
|
+
* `base` with its surface point at box fractions `(s, t)` pulled by `d`, the way dragging inside a
|
|
143
|
+
* patch works: interior anchors within about two cells follow by a share of `d` that fades with
|
|
144
|
+
* distance (each with its block of handles, so grid lines stay smooth); the outer border stays
|
|
145
|
+
* pinned unless the grab is near it, and then it bows; the four corners never move. The grabbed
|
|
146
|
+
* patch's inner points (and, near the border, the border's handles) make up the rest, so the
|
|
147
|
+
* grabbed point lands exactly at its start + `d`.
|
|
148
|
+
*/
|
|
149
|
+
declare function pullWarpMesh(base: WarpMesh, s: number, t: number, d: Vec2): WarpMesh;
|
|
150
|
+
/**
|
|
151
|
+
* The control points an editor shows: the anchors (where grid lines cross) and the handles along
|
|
152
|
+
* the grid lines, each with the anchor it belongs to. Points inside a patch are left out (drag
|
|
153
|
+
* inside a patch to pull the surface instead).
|
|
154
|
+
*/
|
|
155
|
+
declare function warpMeshEditPoints(m: WarpMesh): {
|
|
156
|
+
anchors: number[];
|
|
157
|
+
handles: {
|
|
158
|
+
index: number;
|
|
159
|
+
anchor: number;
|
|
160
|
+
}[];
|
|
161
|
+
};
|
|
162
|
+
/** The mesh's grid lines (patch borders) as cubics `[p0, p1, p2, p3]`. */
|
|
163
|
+
declare function warpMeshGridCurves(m: WarpMesh): Vec2[][];
|
|
164
|
+
|
|
165
|
+
export { warpPresetMesh as A, boxQuad as B, homographyFromAffine as C, invertHomography as D, rectToQuad as E, WARP_STYLES as W, WARP_STYLE_LABELS as a, type WarpPreset as b, applyHomography as c, dragWarpMeshPoint as d, evalWarpMesh as e, fitWarpMesh as f, removeWarpMeshSplitV as g, resizeWarpMesh as h, isValidWarpMesh as i, splitWarpMeshU as j, splitWarpMeshV as k, homographyFromPoints as l, mapWarpMeshPoints as m, homographyKeepsQuad as n, orderQuad as o, pullWarpMesh as p, identityWarpMesh as q, removeWarpMeshSplitU as r, solve8 as s, warpMeshControlBounds as t, warpMeshEditPoints as u, warpMeshGridCurves as v, warpMeshColumns as w, warpMeshParamAt as x, warpMeshRows as y, warpPresetGrid as z };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: pixerate-image-editor
|
|
3
|
-
description: How to colour-correct, composite and retouch a photo in the Pixerate image editor through its agent tools - layers (pixel, adjustment, group and annotation layers with masks, clipping, blend modes, opacity and fill; merge, flatten, layer via copy, filters), live layer effects (shadows, glows,
|
|
3
|
+
description: How to colour-correct, composite and retouch a photo in the Pixerate image editor through its agent tools - layers (pixel, adjustment, group and annotation layers with masks, clipping, blend modes, opacity and fill; merge, flatten, layer via copy, filters), live layer effects (shadows, glows, bevels, satin, overlays, strokes), base adjustments (exposure, contrast, white balance, saturation, blur), adjustment layers (curves, levels, hue/saturation, vibrance, color balance, black and white and more), selections (wand, color range, modify, refine edge) and masks, Free Transform (scale, rotate, skew, distort, warp), crop, rotate, flip, Mixer Brush, undo, PSD, histogram and previews. Use when asked to edit, grade, correct, brighten, crop, straighten or mask an image, add a shadow, glow or outline, transform or warp a layer, or open or save a PSD, or when get_adjustments, set_adjustments, list_layers, add_layer_effect, transform_layer, paint_stroke, select_by_color, import_psd or render_preview are available.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Image editor
|
|
@@ -67,6 +67,27 @@ batching.
|
|
|
67
67
|
5. **Bake only when asked** (`merge_down`, `merge_visible`, `flatten_image`, `apply_layer_mask`):
|
|
68
68
|
they are destructive. `render_preview` with `layerId` shows one layer alone.
|
|
69
69
|
|
|
70
|
+
### Free Transform
|
|
71
|
+
|
|
72
|
+
1. **Read the frame first**: `get_transform_frame` says what a transform would move (`content`,
|
|
73
|
+
`moved`) and its `frame` (document bounds of the content) with its corners. Every transform
|
|
74
|
+
works on that frame: the numeric fields are percent of it and turn about one of its anchors.
|
|
75
|
+
2. **Pick what moves** with `content`: `layer` (all its pixels and a linked mask), `selection`
|
|
76
|
+
(only the selected pixels, committed back into the same layer; the hole they leave is
|
|
77
|
+
transparent and the outline moves with them), `selection-copy` (Layer via Copy, then the copy
|
|
78
|
+
is transformed on a new layer; the original stays) or `auto` (selection when something is
|
|
79
|
+
selected). `channel: "mask"` moves an unlinked mask alone; `transform_selection` moves only
|
|
80
|
+
the outline.
|
|
81
|
+
3. **Choose the tool by the change**: `transform_layer` with `scaleX` / `scaleY` (percent),
|
|
82
|
+
`rotate`, `skewX` / `skewY` (degrees), `dx` / `dy` and a `reference` anchor for scale, rotate
|
|
83
|
+
and skew; `corners` for Distort (each corner free) and Perspective (move two corners
|
|
84
|
+
symmetrically: the top pair in by the same amount narrows the top); `matrix` when you have one;
|
|
85
|
+
`warp_layer` for a preset bend (`style`, `bend`, `horizontal`, `vertical`) or a custom `mesh`;
|
|
86
|
+
`flip_layer` and `rotate_layer_90` for exact flips and quarter turns.
|
|
87
|
+
4. **Transform once.** Every call resamples the pixels, so chained calls soften them: put scale,
|
|
88
|
+
rotation and move into one `transform_layer` call (or one matrix) instead of several.
|
|
89
|
+
5. **Look**: `render_preview`, or `capture_view` at the edges; each call is one undo step.
|
|
90
|
+
|
|
70
91
|
### Layer effects
|
|
71
92
|
|
|
72
93
|
1. **Effects are live and per layer**: drop and inner shadows, outer and inner glows,
|
|
@@ -193,6 +214,16 @@ batching.
|
|
|
193
214
|
layer `opacity` fades the effects too.
|
|
194
215
|
- **Prefer an effect over painted pixels** for shadows, glows, outlines and colour fills of a
|
|
195
216
|
shape: it follows later edits and stays adjustable.
|
|
217
|
+
- **Transforms: one resample, bicubic, whole pixels when you can.** Combine a scale, rotation and
|
|
218
|
+
move into one `transform_layer` call; use `rotate_layer_90` / `flip_layer` (exact) instead of
|
|
219
|
+
`rotate: 90` or `scaleX: -100`. `interpolation: "nearest"` keeps hard pixel art crisp; bicubic
|
|
220
|
+
(default) is right for photos, bilinear is a little softer. Enlarging past about 200 % shows
|
|
221
|
+
softness: prefer a larger source.
|
|
222
|
+
- **Scale proportionally** unless asked to stretch: give `scaleX` and `scaleY` the same value.
|
|
223
|
+
Keep the subject in frame: after a scale about `center` the layer can run past the canvas,
|
|
224
|
+
which `bounds` in the result shows.
|
|
225
|
+
- **Unlink a mask** (`set_layer_mask_properties` `linked: false`) when the pixels should move
|
|
226
|
+
under a fixed mask (a picture inside a frame); link it again afterwards.
|
|
196
227
|
- **Merge Down only onto an opaque, 100 % lower layer** when the result must look the same:
|
|
197
228
|
the merged layer keeps the lower layer's opacity and blend, so a faded lower layer fades the
|
|
198
229
|
merged content too, and a blend mode on the upper layer stops seeing what was below the lower
|
|
@@ -214,6 +245,7 @@ batching.
|
|
|
214
245
|
| `render_preview` | See the edited image (crop, adjustments, layers, annotations) as a PNG, or with `layerId` one layer alone. `maxSide` 16..2048 px, default 512. Images cost tokens: render after a group of edits, use 512 for overall look and 1024+ to judge clipping, edges and masks. Fails in environments without rendering. |
|
|
215
246
|
| `inspect_psd` | Read a PSD / PSB (`data` base64) without opening it: size, `depth`, `colorMode`, `resolution`, every layer bottom first with `psdKind`, the `type` it would become and `status` (`mapped`, `approximated`, `dropped`) with `notes`, and the import `warnings`. Call before `import_psd`. |
|
|
216
247
|
| `export_psd` | Save the document as an 8-bit RGB PSD (PSB above 30000 px) with layers, groups, adjustment layers and masks. Returns `data` (base64), `size` in bytes, `psb` and `warnings` (crop or rotation not applied, filters and depth masks baked, annotations rasterized or left out, Pigment blends written as Normal). Changes nothing. |
|
|
248
|
+
| `get_transform_frame` | Before a transform: what it would move (`content`, `moved`: pixels, mask, selection), its `frame` (document bounds of the content), `corners` (top-left, top-right, bottom-right, bottom-left) and `center`. `meshColumns` / `meshRows` also return an identity warp `mesh` over the frame to edit for `warp_layer`. Changes nothing. |
|
|
217
249
|
| `capture_view` | Inspect detail in natural image pixels (the space of `get_selection` and `select_region`, before crop and rotation): `region` `content` (whole image, default), `selection` or `rect`; small regions are enlarged up to 8× with hard pixel edges, so a 64 px rect shows real pixels. `includeOverlays: true` shades unselected pixels and outlines the crop: use it to check a mask's edge before `apply_selection_as_mask`. Returns the `rect` and `scale`. Use `render_preview` for the final framed result. |
|
|
218
250
|
|
|
219
251
|
### Write
|
|
@@ -247,9 +279,14 @@ batching.
|
|
|
247
279
|
| `merge_down` | Composite a layer onto the pixel layer below it (masks, fill and filters baked). Destructive; see Best practices. Returns the merged layer. |
|
|
248
280
|
| `merge_visible` | Composite all visible top-level layers into one layer; hidden ones stay. Destructive. |
|
|
249
281
|
| `flatten_image` | Composite everything visible into one Background; hidden layers are discarded. Destructive; do it only when asked. |
|
|
250
|
-
| `offset_layer` | Move a pixel layer and its mask to `x`, `y` or by `dx`, `dy` (integers, document px). Refused when its position is locked. Returns the offset and bounds. |
|
|
282
|
+
| `offset_layer` | Move a pixel layer and its linked mask to `x`, `y` or by `dx`, `dy` (integers, document px; an unlinked mask stays put). Refused when its position is locked. Returns the offset and bounds. |
|
|
283
|
+
| `transform_layer` | Free Transform a pixel layer (with its linked mask), the selected pixels (`content` `selection`), a copy of them on a new layer (`selection-copy`) or an unlinked mask (`channel` `mask`). Give the transform one way: `scaleX` / `scaleY` (percent), `rotate`, `skewX` / `skewY` (degrees), `dx` / `dy` (px) about `reference` (an anchor or `{x, y}`, default `center`); or `matrix` `[a, b, c, d, e, f]`; or `corners` (the frame's new corners: distort / perspective, kept convex). `interpolation` nearest, bilinear or bicubic (default). One undo step. Returns `layerId` (the new layer for a copy), `moved`, `frame`, `corners` and the new `bounds`. |
|
|
284
|
+
| `warp_layer` | Warp the same targets as `transform_layer` through a preset (`style` arc … twist, `bend` −100..100 default 50, `horizontal` / `vertical` distortion, `orientation`) or a `mesh` (`columns`, `rows`, (3·columns + 1) × (3·rows + 1) `points` in document px; start from `get_transform_frame`'s identity mesh). One undo step. Returns the new `bounds`. |
|
|
285
|
+
| `transform_selection` | Transform only the selection outline (Transform Selection): the same numeric fields, `matrix` or `corners` as `transform_layer`, over the selection's bounds. Pixels do not change. Needs a selection. Returns the new selection `bounds`. |
|
|
286
|
+
| `flip_layer` | Mirror a pixel layer, its selected pixels or a copy (`content`) `horizontal` or `vertical` about the frame's centre, exactly. For the whole image use `flip_image`. Returns the new `bounds`. |
|
|
287
|
+
| `rotate_layer_90` | Turn a pixel layer, its selected pixels or a copy by `turn` 90 (clockwise), -90 or 180 about the frame's centre, landing on whole pixels (no resampling). For the whole image use `set_rotation`. Returns the new `bounds`. |
|
|
251
288
|
| `add_layer_mask` | Mask any layer `from` `reveal-all`, `hide-all` or `selection`, with optional `density` / `feather`. Replaces an existing mask. Returns the mask summary. |
|
|
252
|
-
| `set_layer_mask_properties` | Change any layer mask's `density`, `feather` or `
|
|
289
|
+
| `set_layer_mask_properties` | Change any layer mask's `density`, `feather`, `enabled` or `linked` (false: the mask stays put when the layer moves or transforms) without touching its pixels. |
|
|
253
290
|
| `apply_layer_mask` | Bake a pixel layer's mask into its alpha and remove it. Destructive. |
|
|
254
291
|
| `remove_layer_mask` | Delete a mask without applying it; disable it instead to keep it. |
|
|
255
292
|
| `layer_via_copy` | Copy the selected pixels of a pixel layer (default the active one) to a new layer above it; `cut: true` removes them from the source. Needs a selection. Returns the new layer. |
|
|
@@ -328,5 +365,14 @@ batching.
|
|
|
328
365
|
selection: start low (wand 20..40, range 30..60), check `percent`, and add with `mode: add`.
|
|
329
366
|
- `modify_selection`, `refine_selection` and `apply_selection_as_mask` fail with "Nothing is
|
|
330
367
|
selected." when the selection is empty; select first.
|
|
368
|
+
- Transforms refuse hidden layers, layers with `locks.position` or `locks.pixels`, and adjustment,
|
|
369
|
+
annotation and group layers (transform a layer's mask with `channel: "mask"` after unlinking
|
|
370
|
+
it). A result larger than about 11 600 × 11 600 px is refused.
|
|
371
|
+
- `transform_layer` scale fields are percent (100 = unchanged), not factors; `rotate` is degrees
|
|
372
|
+
clockwise. `corners` that cross or fold through the horizon are refused: keep the quad convex.
|
|
373
|
+
- With a selection, `content: "auto"` (the default) moves only the selected pixels, not the
|
|
374
|
+
whole layer. Pass `content: "layer"` to move everything regardless of the selection.
|
|
375
|
+
- A Background transformed smaller leaves transparent canvas around it; fill it with a layer
|
|
376
|
+
below or crop afterwards.
|
|
331
377
|
- Opacity values are 0..1, not percent. Curves and levels points are 0..255 levels; levels
|
|
332
378
|
`gamma` is 0.1..9.99 (1 = neutral); hue is degrees -180..180.
|