@pixerate/editor 0.23.0 → 0.25.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/README.md +167 -2
- package/THIRD_PARTY_NOTICES.md +80 -0
- package/dist/agent/index.cjs +10 -8
- package/dist/agent/index.cjs.map +1 -1
- package/dist/agent/index.d.cts +4 -3
- package/dist/agent/index.d.ts +4 -3
- package/dist/agent/index.js +4 -2
- package/dist/agent/index.js.map +1 -1
- package/dist/canvas/index.cjs +4437 -411
- package/dist/canvas/index.cjs.map +1 -1
- package/dist/canvas/index.d.cts +934 -4
- package/dist/canvas/index.d.ts +934 -4
- package/dist/canvas/index.js +4309 -283
- package/dist/canvas/index.js.map +1 -1
- package/dist/chunk-4BVP64JJ.cjs +1406 -0
- package/dist/chunk-4BVP64JJ.cjs.map +1 -0
- package/dist/chunk-664LQYFJ.js +115 -0
- package/dist/chunk-664LQYFJ.js.map +1 -0
- package/dist/chunk-7WISYZFO.cjs +740 -0
- package/dist/chunk-7WISYZFO.cjs.map +1 -0
- package/dist/chunk-AL6JMGWW.cjs +783 -0
- package/dist/chunk-AL6JMGWW.cjs.map +1 -0
- package/dist/chunk-BVP3TSLH.cjs +69 -0
- package/dist/chunk-BVP3TSLH.cjs.map +1 -0
- package/dist/{chunk-RIKBJLS2.cjs → chunk-C7P22VIP.cjs} +2001 -279
- package/dist/chunk-C7P22VIP.cjs.map +1 -0
- package/dist/chunk-D6FH2YAX.cjs +131 -0
- package/dist/chunk-D6FH2YAX.cjs.map +1 -0
- package/dist/chunk-ECCCYKGL.js +740 -0
- package/dist/chunk-ECCCYKGL.js.map +1 -0
- package/dist/{chunk-4SUNJZWB.cjs → chunk-FD4LPFAE.cjs} +48 -200
- package/dist/chunk-FD4LPFAE.cjs.map +1 -0
- package/dist/{chunk-QBJ22YZR.js → chunk-FH6F67DN.js} +1999 -277
- package/dist/chunk-FH6F67DN.js.map +1 -0
- package/dist/{chunk-OYXSKQFR.js → chunk-FPENXAEJ.js} +35 -187
- package/dist/chunk-FPENXAEJ.js.map +1 -0
- package/dist/chunk-HLIMTC6N.js +1 -0
- package/dist/chunk-HLIMTC6N.js.map +1 -0
- package/dist/chunk-HRMEDT2L.js +1406 -0
- package/dist/chunk-HRMEDT2L.js.map +1 -0
- package/dist/{chunk-QGHGJ56O.js → chunk-IXHSYOVY.js} +2518 -122
- package/dist/chunk-IXHSYOVY.js.map +1 -0
- package/dist/chunk-MKA3AHLV.cjs +256 -0
- package/dist/chunk-MKA3AHLV.cjs.map +1 -0
- package/dist/chunk-NAXVVS5I.js +783 -0
- package/dist/chunk-NAXVVS5I.js.map +1 -0
- package/dist/chunk-O5RYH2PG.js +69 -0
- package/dist/chunk-O5RYH2PG.js.map +1 -0
- package/dist/chunk-OXSV64JX.js +689 -0
- package/dist/chunk-OXSV64JX.js.map +1 -0
- package/dist/chunk-P3RQ5UJE.cjs +689 -0
- package/dist/chunk-P3RQ5UJE.cjs.map +1 -0
- package/dist/chunk-P6ODPZ4W.js +256 -0
- package/dist/chunk-P6ODPZ4W.js.map +1 -0
- package/dist/chunk-PL4JB3BF.cjs +1 -0
- package/dist/chunk-PL4JB3BF.cjs.map +1 -0
- package/dist/{chunk-GVSMRPHB.cjs → chunk-PO6A6QQH.cjs} +2607 -211
- package/dist/chunk-PO6A6QQH.cjs.map +1 -0
- package/dist/{chunk-JJDLPEWL.js → chunk-QGYDWPRM.js} +2 -2
- package/dist/chunk-RR7F5GUM.js +5726 -0
- package/dist/chunk-RR7F5GUM.js.map +1 -0
- package/dist/chunk-TNNJXF46.cjs +115 -0
- package/dist/chunk-TNNJXF46.cjs.map +1 -0
- package/dist/chunk-U5HZSFCS.js +131 -0
- package/dist/chunk-U5HZSFCS.js.map +1 -0
- package/dist/{chunk-MJZBNWG7.js → chunk-UAKDG62Z.js} +309 -581
- package/dist/chunk-UAKDG62Z.js.map +1 -0
- package/dist/{chunk-CL37JGFW.cjs → chunk-V3CHHWOE.cjs} +4 -4
- package/dist/{chunk-CL37JGFW.cjs.map → chunk-V3CHHWOE.cjs.map} +1 -1
- package/dist/chunk-WSQKHXW7.cjs +5726 -0
- package/dist/chunk-WSQKHXW7.cjs.map +1 -0
- package/dist/{chunk-AA4ZEVCC.cjs → chunk-X4N4WUKB.cjs} +336 -608
- package/dist/chunk-X4N4WUKB.cjs.map +1 -0
- package/dist/commands/index.cjs +74 -1
- package/dist/commands/index.cjs.map +1 -1
- package/dist/commands/index.d.cts +38 -353
- package/dist/commands/index.d.ts +38 -353
- package/dist/commands/index.js +73 -0
- package/dist/commands/index.js.map +1 -1
- package/dist/comment-store-BEMgVlAA.d.cts +135 -0
- package/dist/comment-store-BEMgVlAA.d.ts +135 -0
- package/dist/compare/index.cjs +15 -0
- package/dist/compare/index.cjs.map +1 -0
- package/dist/compare/index.d.cts +58 -0
- package/dist/compare/index.d.ts +58 -0
- package/dist/compare/index.js +15 -0
- package/dist/compare/index.js.map +1 -0
- package/dist/controller-BIJiNoVs.d.cts +1842 -0
- package/dist/controller-BIJiNoVs.d.ts +1842 -0
- package/dist/documents-CHT1U5Vs.d.ts +86 -0
- package/dist/documents-Gp7wb0Me.d.cts +86 -0
- package/dist/extensions/index.cjs +100 -5
- package/dist/extensions/index.cjs.map +1 -1
- package/dist/extensions/index.d.cts +16 -4
- package/dist/extensions/index.d.ts +16 -4
- package/dist/extensions/index.js +100 -5
- package/dist/generation/index.cjs +2317 -0
- package/dist/generation/index.cjs.map +1 -0
- package/dist/generation/index.d.cts +1015 -0
- package/dist/generation/index.d.ts +1015 -0
- package/dist/generation/index.js +2317 -0
- package/dist/generation/index.js.map +1 -0
- package/dist/grammar/index.cjs +48 -3
- package/dist/grammar/index.cjs.map +1 -1
- package/dist/grammar/index.d.cts +322 -100
- package/dist/grammar/index.d.ts +322 -100
- package/dist/grammar/index.js +54 -9
- package/dist/image-editor/index.cjs +4392 -481
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.d.cts +1249 -97
- package/dist/image-editor/index.d.ts +1249 -97
- package/dist/image-editor/index.js +4281 -370
- package/dist/image-editor/index.js.map +1 -1
- package/dist/index-7a6bHTLy.d.ts +1754 -0
- package/dist/index-Csd5qI8u.d.cts +1754 -0
- package/dist/index.cjs +1682 -99
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +118 -21
- package/dist/index.d.ts +118 -21
- package/dist/index.js +1630 -47
- package/dist/index.js.map +1 -1
- package/dist/mention-text-CDnCFd3c.d.cts +53 -0
- package/dist/mention-text-CDnCFd3c.d.ts +53 -0
- package/dist/migrate-iTlm3a8h.d.cts +112 -0
- package/dist/migrate-iTlm3a8h.d.ts +112 -0
- package/dist/model-C1zApQM8.d.cts +219 -0
- package/dist/model-C1zApQM8.d.ts +219 -0
- package/dist/persistence/index.cjs +676 -0
- package/dist/persistence/index.cjs.map +1 -0
- package/dist/persistence/index.d.cts +230 -0
- package/dist/persistence/index.d.ts +230 -0
- package/dist/persistence/index.js +676 -0
- package/dist/persistence/index.js.map +1 -0
- package/dist/{registry-D5-R90p0.d.cts → registry-BDe-vlv3.d.ts} +2 -40
- package/dist/{registry-GJI4gToU.d.ts → registry-CEgwXED1.d.cts} +12 -1
- package/dist/{registry-GJI4gToU.d.cts → registry-CEgwXED1.d.ts} +12 -1
- package/dist/registry-D32LpIc4.d.cts +354 -0
- package/dist/{registry-D5-R90p0.d.ts → registry-DnzpgY27.d.cts} +2 -40
- package/dist/registry-evKTP4ls.d.ts +354 -0
- package/dist/schema-DYDGdYL9.d.cts +41 -0
- package/dist/schema-DYDGdYL9.d.ts +41 -0
- package/dist/serializers/index.cjs +12 -3
- package/dist/serializers/index.cjs.map +1 -1
- package/dist/serializers/index.d.cts +40 -12
- package/dist/serializers/index.d.ts +40 -12
- package/dist/serializers/index.js +12 -3
- package/dist/sourcemap-C8AH3MBQ.d.cts +91 -0
- package/dist/sourcemap-DA1Evhrv.d.ts +91 -0
- package/dist/spreadsheet/index.cjs +161 -3
- package/dist/spreadsheet/index.cjs.map +1 -1
- package/dist/spreadsheet/index.d.cts +611 -20
- package/dist/spreadsheet/index.d.ts +611 -20
- package/dist/spreadsheet/index.js +168 -10
- package/dist/storage-BpFfspHm.d.cts +120 -0
- package/dist/storage-BpFfspHm.d.ts +120 -0
- package/dist/tokens/index.cjs +115 -0
- package/dist/tokens/index.cjs.map +1 -0
- package/dist/tokens/index.d.cts +212 -0
- package/dist/tokens/index.d.ts +212 -0
- package/dist/tokens/index.js +115 -0
- package/dist/tokens/index.js.map +1 -0
- package/dist/{tokens-CyLZmIei.d.cts → tokens-D7yXvUU6.d.cts} +15 -2
- package/dist/{tokens-CyLZmIei.d.ts → tokens-D7yXvUU6.d.ts} +15 -2
- package/dist/{track-changes-BSF58RK0.d.cts → track-changes-D_VAPELi.d.cts} +110 -144
- package/dist/{track-changes-BSF58RK0.d.ts → track-changes-Db_fGEvx.d.ts} +110 -144
- package/package.json +21 -1
- package/dist/chunk-4SUNJZWB.cjs.map +0 -1
- package/dist/chunk-AA4ZEVCC.cjs.map +0 -1
- package/dist/chunk-AXV2ZW34.cjs +0 -118
- package/dist/chunk-AXV2ZW34.cjs.map +0 -1
- package/dist/chunk-B2ZRLN4S.js +0 -118
- package/dist/chunk-B2ZRLN4S.js.map +0 -1
- package/dist/chunk-GVSMRPHB.cjs.map +0 -1
- package/dist/chunk-K3R5NG2D.js +0 -3100
- package/dist/chunk-K3R5NG2D.js.map +0 -1
- package/dist/chunk-MJZBNWG7.js.map +0 -1
- package/dist/chunk-OYXSKQFR.js.map +0 -1
- package/dist/chunk-QBJ22YZR.js.map +0 -1
- package/dist/chunk-QGHGJ56O.js.map +0 -1
- package/dist/chunk-RIKBJLS2.cjs.map +0 -1
- package/dist/chunk-XDMXXC4Z.cjs +0 -3100
- package/dist/chunk-XDMXXC4Z.cjs.map +0 -1
- package/dist/controller-pePCJLT1.d.cts +0 -959
- package/dist/controller-pePCJLT1.d.ts +0 -959
- package/dist/index-CCr_z9kF.d.cts +0 -899
- package/dist/index-Ck6ajwXh.d.ts +0 -899
- /package/dist/{chunk-JJDLPEWL.js.map → chunk-QGYDWPRM.js.map} +0 -0
|
@@ -1,3 +1,143 @@
|
|
|
1
|
+
import { b as LoadReport, J as JsonObject, f as MigrationStep } from '../migrate-iTlm3a8h.js';
|
|
2
|
+
import { A as AgentToolProvider, a as AgentTool } from '../registry-BDe-vlv3.js';
|
|
3
|
+
import '../schema-DYDGdYL9.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Photoshop blend modes on straight (non-premultiplied) 0..1 colours.
|
|
7
|
+
*
|
|
8
|
+
* Formulas follow the W3C Compositing / ISO 32000 definitions, with Photoshop's variants where
|
|
9
|
+
* they differ (Soft Light, Vivid / Linear / Pin Light, Hard Mix, Linear Burn / Dodge, Subtract,
|
|
10
|
+
* Divide, Darker / Lighter Color), and the hardened `ClipColor` for the non-separable modes.
|
|
11
|
+
*/
|
|
12
|
+
type BlendMode = 'normal' | 'darken' | 'multiply' | 'color-burn' | 'linear-burn' | 'darker-color' | 'lighten' | 'screen' | 'color-dodge' | 'linear-dodge' | 'lighter-color' | 'overlay' | 'soft-light' | 'hard-light' | 'vivid-light' | 'linear-light' | 'pin-light' | 'hard-mix' | 'difference' | 'exclusion' | 'subtract' | 'divide' | 'hue' | 'saturation' | 'color' | 'luminosity';
|
|
13
|
+
interface BlendModeInfo {
|
|
14
|
+
id: BlendMode;
|
|
15
|
+
label: string;
|
|
16
|
+
/** Canvas `globalCompositeOperation` with the same maths, when there is one. */
|
|
17
|
+
canvas: GlobalCompositeOperation | null;
|
|
18
|
+
}
|
|
19
|
+
/** Every blend mode, in Photoshop's menu order. */
|
|
20
|
+
declare const BLEND_MODES: readonly BlendModeInfo[];
|
|
21
|
+
declare function isBlendMode(value: unknown): value is BlendMode;
|
|
22
|
+
/** A stored blend mode, or `normal` for a missing / unknown value. */
|
|
23
|
+
declare function normalizeBlendMode(value: unknown): BlendMode;
|
|
24
|
+
/**
|
|
25
|
+
* The canvas composite operation that implements `mode` exactly, or `null` when the canvas has
|
|
26
|
+
* none (draw through {@link blendImageData} instead).
|
|
27
|
+
*/
|
|
28
|
+
declare function canvasCompositeOperation(mode: BlendMode | undefined): GlobalCompositeOperation | null;
|
|
29
|
+
/** Whether a mode works on whole colours (hue, saturation, colour, luminosity, darker / lighter colour). */
|
|
30
|
+
declare function isSeparableBlendMode(mode: BlendMode): boolean;
|
|
31
|
+
/** Separable blend function `B(cb, cs)` of one channel. Non-separable modes return `cs`. */
|
|
32
|
+
declare function blendChannel(mode: BlendMode, cb: number, cs: number): number;
|
|
33
|
+
type Rgb$1 = [number, number, number];
|
|
34
|
+
type Rgba = [number, number, number, number];
|
|
35
|
+
/** Luminosity of the non-separable modes (W3C / ISO 32000 weights). */
|
|
36
|
+
declare function blendLum(c: readonly number[]): number;
|
|
37
|
+
/** `c` with its luminosity moved to `l`, clipped back into gamut towards grey (SetLum + ClipColor). */
|
|
38
|
+
declare function setLum(c: readonly number[], l: number): Rgb$1;
|
|
39
|
+
/** `B(Cb, Cs)` of a whole colour, including the non-separable modes. */
|
|
40
|
+
declare function blendRgb(mode: BlendMode, cb: readonly number[], cs: readonly number[]): Rgb$1;
|
|
41
|
+
/**
|
|
42
|
+
* Composites a straight-alpha `source` over a straight-alpha `backdrop` (both RGBA in 0..1) with a
|
|
43
|
+
* blend mode and an extra `alpha` (opacity), using the W3C general formula:
|
|
44
|
+
* `αo = αs + αb(1 − αs)`, `αo·Co = (1 − αs)·αb·Cb + (1 − αb)·αs·Cs + αs·αb·B(Cb, Cs)`.
|
|
45
|
+
*/
|
|
46
|
+
declare function blendPixel(mode: BlendMode, backdrop: readonly number[], source: readonly number[], alpha?: number): Rgba;
|
|
47
|
+
/**
|
|
48
|
+
* Blends `source` into `backdrop` in place (8-bit straight RGBA of the same size) with
|
|
49
|
+
* {@link blendPixel}. The scalar fallback for modes the canvas cannot composite.
|
|
50
|
+
*/
|
|
51
|
+
declare function blendImageData(backdrop: ImageData, source: ImageData, mode: BlendMode, alpha?: number): void;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* A selection: one 8-bit coverage value per image pixel (0 = not selected, 255 = fully
|
|
55
|
+
* selected), row-major over the whole source image in natural pixels — the same space as the
|
|
56
|
+
* crop box and annotations. Soft values are partial selection (feathered or anti-aliased edges).
|
|
57
|
+
*
|
|
58
|
+
* Treat a mask as immutable: every operation returns a new one, so history entries can share
|
|
59
|
+
* them without copying.
|
|
60
|
+
*/
|
|
61
|
+
interface SelectionMask {
|
|
62
|
+
readonly width: number;
|
|
63
|
+
readonly height: number;
|
|
64
|
+
readonly data: Uint8Array;
|
|
65
|
+
/** Bounding box of the non-zero coverage, or `null` when nothing is selected. */
|
|
66
|
+
readonly bounds: CropBox | null;
|
|
67
|
+
}
|
|
68
|
+
/** How a new selection combines with the current one. */
|
|
69
|
+
type SelectionMode = 'replace' | 'add' | 'subtract' | 'intersect';
|
|
70
|
+
declare const SELECTION_MODES: readonly SelectionMode[];
|
|
71
|
+
declare function isSelectionMode(value: unknown): value is SelectionMode;
|
|
72
|
+
/** Parses `replace|add|subtract|intersect`; anything else is `replace`. */
|
|
73
|
+
declare function parseSelectionMode(value: unknown): SelectionMode;
|
|
74
|
+
/** RGBA pixels, 8 bits per channel, straight alpha (an `ImageData` qualifies). */
|
|
75
|
+
interface PixelBuffer {
|
|
76
|
+
width: number;
|
|
77
|
+
height: number;
|
|
78
|
+
data: ArrayLike<number>;
|
|
79
|
+
}
|
|
80
|
+
/** Serialized selection: a run-length encoding of the 8-bit coverage. */
|
|
81
|
+
interface SerializedSelection {
|
|
82
|
+
width: number;
|
|
83
|
+
height: number;
|
|
84
|
+
/** `r1:` + base64 of (value byte, LEB128 run length) pairs. */
|
|
85
|
+
rle: string;
|
|
86
|
+
}
|
|
87
|
+
/** Bounding box of non-zero bytes. */
|
|
88
|
+
declare function computeSelectionBounds(width: number, height: number, data: ArrayLike<number>): CropBox | null;
|
|
89
|
+
/** Wraps coverage bytes (taken over, not copied) as a selection, computing its bounds. */
|
|
90
|
+
declare function createSelectionMask(width: number, height: number, data?: Uint8Array): SelectionMask;
|
|
91
|
+
/** Select › All. */
|
|
92
|
+
declare function fullSelection(width: number, height: number): SelectionMask;
|
|
93
|
+
declare function isSelectionEmpty(mask: SelectionMask | null | undefined): boolean;
|
|
94
|
+
/** Coverage at a pixel, 0..1 (0 outside the image). */
|
|
95
|
+
declare function selectionValueAt(mask: SelectionMask, x: number, y: number): number;
|
|
96
|
+
/** 8-bit value of a coverage (clamped and rounded; NaN → 0). */
|
|
97
|
+
declare function coverageToByte(v: number): number;
|
|
98
|
+
/** A selection from 0..1 coverage. */
|
|
99
|
+
declare function selectionFromCoverage(width: number, height: number, coverage: ArrayLike<number>): SelectionMask;
|
|
100
|
+
/** The selection's coverage as 0..1 floats. */
|
|
101
|
+
declare function selectionToCoverage(mask: SelectionMask): Float32Array;
|
|
102
|
+
/** Number of fully-or-partly selected pixels, weighted by coverage (Σ coverage). */
|
|
103
|
+
declare function selectionArea(mask: SelectionMask | null | undefined): number;
|
|
104
|
+
/**
|
|
105
|
+
* Combines `next` with `prev` by `mode` (8-bit, exact: combining a mask with itself is a no-op).
|
|
106
|
+
* Add is the maximum, Subtract `max(prev − next, 0)`, Intersect the minimum. A missing `prev`
|
|
107
|
+
* reads as nothing selected. Returns `null` when nothing remains selected.
|
|
108
|
+
*/
|
|
109
|
+
declare function combineSelections(prev: SelectionMask | null | undefined, next: SelectionMask, mode: SelectionMode): SelectionMask | null;
|
|
110
|
+
/** Select › Inverse. */
|
|
111
|
+
declare function invertSelection(mask: SelectionMask): SelectionMask;
|
|
112
|
+
/** Bilinear resample to another size (e.g. an AI mask returned at a different resolution). */
|
|
113
|
+
declare function resizeSelection(mask: SelectionMask, width: number, height: number): SelectionMask;
|
|
114
|
+
type SelectionChannel = 'alpha' | 'luminance' | 'red' | 'green' | 'blue';
|
|
115
|
+
/**
|
|
116
|
+
* A selection from an image: by default its luminance (white = selected, the usual convention
|
|
117
|
+
* of segmentation masks), or one channel. Partly transparent pixels count as black for
|
|
118
|
+
* luminance, so a mask PNG with transparency works either way.
|
|
119
|
+
*/
|
|
120
|
+
declare function selectionFromPixels(pixels: PixelBuffer, options?: {
|
|
121
|
+
channel?: SelectionChannel;
|
|
122
|
+
invert?: boolean;
|
|
123
|
+
threshold?: number;
|
|
124
|
+
}): SelectionMask;
|
|
125
|
+
/** The selection as RGBA pixels: grey (white = selected, opaque) or white with coverage as alpha. */
|
|
126
|
+
declare function selectionToPixels(mask: SelectionMask, as?: 'gray' | 'alpha'): {
|
|
127
|
+
width: number;
|
|
128
|
+
height: number;
|
|
129
|
+
data: Uint8ClampedArray;
|
|
130
|
+
};
|
|
131
|
+
/** Run-length encodes coverage bytes: `r1:` + base64 of (value, LEB128 run length) pairs. */
|
|
132
|
+
declare function encodeSelectionRle(data: Uint8Array): string;
|
|
133
|
+
/** Decodes {@link encodeSelectionRle}; throws unless the runs cover exactly `length` bytes. */
|
|
134
|
+
declare function decodeSelectionRle(rle: string, length: number): Uint8Array;
|
|
135
|
+
declare function serializeSelection(mask: SelectionMask): SerializedSelection;
|
|
136
|
+
/** Restores a {@link SerializedSelection}; throws on damaged data. */
|
|
137
|
+
declare function deserializeSelection(value: unknown): SelectionMask;
|
|
138
|
+
/** A short, stable hash of a string or bytes (FNV-1a, 32-bit, hex) for cache keys. */
|
|
139
|
+
declare function hashMaskContent(content: string | Uint8Array): string;
|
|
140
|
+
|
|
1
141
|
interface ImageDimensions {
|
|
2
142
|
width: number;
|
|
3
143
|
height: number;
|
|
@@ -38,7 +178,157 @@ interface ImageAdjustments {
|
|
|
38
178
|
* versions existed look exactly as they did. See `normalizeProcessVersion`.
|
|
39
179
|
*/
|
|
40
180
|
process?: 1 | 2;
|
|
181
|
+
/**
|
|
182
|
+
* Non-destructive adjustment layers, evaluated bottom (first) to top (last) after the base
|
|
183
|
+
* adjustments above, on the encoded sRGB result. Missing or empty: no layers (edits saved
|
|
184
|
+
* before layers existed render exactly as before).
|
|
185
|
+
*/
|
|
186
|
+
layers?: AdjustmentLayer[];
|
|
187
|
+
}
|
|
188
|
+
type AdjustmentKind = 'curves' | 'levels' | 'hueSaturation' | 'vibrance' | 'colorBalance' | 'blackWhite' | 'invert' | 'posterize' | 'threshold' | 'photoFilter';
|
|
189
|
+
/** A Curves point; `input` and `output` are levels, 0..255. */
|
|
190
|
+
interface CurvePoint {
|
|
191
|
+
input: number;
|
|
192
|
+
output: number;
|
|
193
|
+
}
|
|
194
|
+
/** Curves: each channel's curve first, then the master (composite) curve, as in Photoshop. */
|
|
195
|
+
interface CurvesParams {
|
|
196
|
+
master: CurvePoint[];
|
|
197
|
+
red: CurvePoint[];
|
|
198
|
+
green: CurvePoint[];
|
|
199
|
+
blue: CurvePoint[];
|
|
200
|
+
}
|
|
201
|
+
/** One Levels record. Black / white points are levels (0..255); `gamma` is the midtone slider (0.1..9.99). */
|
|
202
|
+
interface LevelsChannel {
|
|
203
|
+
inBlack: number;
|
|
204
|
+
inWhite: number;
|
|
205
|
+
gamma: number;
|
|
206
|
+
outBlack: number;
|
|
207
|
+
outWhite: number;
|
|
208
|
+
}
|
|
209
|
+
/** Levels: each channel's record first, then the master record, as in Photoshop. */
|
|
210
|
+
interface LevelsParams {
|
|
211
|
+
master: LevelsChannel;
|
|
212
|
+
red: LevelsChannel;
|
|
213
|
+
green: LevelsChannel;
|
|
214
|
+
blue: LevelsChannel;
|
|
215
|
+
}
|
|
216
|
+
/** One of Hue/Saturation's six colour ranges (reds, yellows, greens, cyans, blues, magentas). */
|
|
217
|
+
interface HueRange {
|
|
218
|
+
/** Hue shift in degrees (-180..180). */
|
|
219
|
+
hue: number;
|
|
220
|
+
/** Saturation change in percent (-100..100). */
|
|
221
|
+
saturation: number;
|
|
222
|
+
/** Lightness change in percent (-100..100). */
|
|
223
|
+
lightness: number;
|
|
224
|
+
/** Hue degrees where the range starts fading in, is fully on, starts fading out and ends (may wrap). */
|
|
225
|
+
bounds: [number, number, number, number];
|
|
226
|
+
}
|
|
227
|
+
interface HueSaturationParams {
|
|
228
|
+
/** Master hue shift in degrees (-180..180), or the hue when colorizing (0..360). */
|
|
229
|
+
hue: number;
|
|
230
|
+
/** Percent, -100..100 (0..100 when colorizing). */
|
|
231
|
+
saturation: number;
|
|
232
|
+
/** Percent, -100..100. */
|
|
233
|
+
lightness: number;
|
|
234
|
+
colorize: boolean;
|
|
235
|
+
/** Six ranges: reds, yellows, greens, cyans, blues, magentas. */
|
|
236
|
+
ranges: HueRange[];
|
|
237
|
+
}
|
|
238
|
+
interface VibranceParams {
|
|
239
|
+
/** -100..100 */
|
|
240
|
+
vibrance: number;
|
|
241
|
+
/** -100..100 */
|
|
242
|
+
saturation: number;
|
|
243
|
+
}
|
|
244
|
+
/** Cyan–red, magenta–green, yellow–blue sliders, -100..100 each. */
|
|
245
|
+
type ColorBalanceTone = [number, number, number];
|
|
246
|
+
interface ColorBalanceParams {
|
|
247
|
+
shadows: ColorBalanceTone;
|
|
248
|
+
midtones: ColorBalanceTone;
|
|
249
|
+
highlights: ColorBalanceTone;
|
|
250
|
+
preserveLuminosity: boolean;
|
|
251
|
+
}
|
|
252
|
+
/** Black & White: percent weights of the six colours (Photoshop defaults 40 60 40 60 20 80). */
|
|
253
|
+
interface BlackWhiteParams {
|
|
254
|
+
reds: number;
|
|
255
|
+
yellows: number;
|
|
256
|
+
greens: number;
|
|
257
|
+
cyans: number;
|
|
258
|
+
blues: number;
|
|
259
|
+
magentas: number;
|
|
260
|
+
/** Tint colour (`#rrggbb`), applied like the Color blend mode, or `null` for none. */
|
|
261
|
+
tint: string | null;
|
|
262
|
+
}
|
|
263
|
+
interface PhotoFilterParams {
|
|
264
|
+
/** Filter colour, `#rrggbb`. */
|
|
265
|
+
color: string;
|
|
266
|
+
/** Percent, 0..100. */
|
|
267
|
+
density: number;
|
|
268
|
+
preserveLuminosity: boolean;
|
|
269
|
+
}
|
|
270
|
+
interface PosterizeParams {
|
|
271
|
+
/** 2..255 */
|
|
272
|
+
levels: number;
|
|
273
|
+
}
|
|
274
|
+
interface ThresholdParams {
|
|
275
|
+
/** 1..255: luma at or above it becomes white. */
|
|
276
|
+
level: number;
|
|
277
|
+
}
|
|
278
|
+
type InvertParams = Record<string, never>;
|
|
279
|
+
interface AdjustmentParamsMap {
|
|
280
|
+
curves: CurvesParams;
|
|
281
|
+
levels: LevelsParams;
|
|
282
|
+
hueSaturation: HueSaturationParams;
|
|
283
|
+
vibrance: VibranceParams;
|
|
284
|
+
colorBalance: ColorBalanceParams;
|
|
285
|
+
blackWhite: BlackWhiteParams;
|
|
286
|
+
invert: InvertParams;
|
|
287
|
+
posterize: PosterizeParams;
|
|
288
|
+
threshold: ThresholdParams;
|
|
289
|
+
photoFilter: PhotoFilterParams;
|
|
290
|
+
}
|
|
291
|
+
interface AdjustmentLayerBase {
|
|
292
|
+
id: string;
|
|
293
|
+
/** Optional display name. */
|
|
294
|
+
name?: string;
|
|
295
|
+
enabled: boolean;
|
|
296
|
+
/** 0..1 */
|
|
297
|
+
opacity: number;
|
|
298
|
+
/** How the adjusted colour is blended over the layers below. */
|
|
299
|
+
blend: BlendMode;
|
|
300
|
+
/**
|
|
301
|
+
* Optional layer mask (natural image pixels): where it is 0 the layer has no effect. Missing:
|
|
302
|
+
* the layer applies everywhere (layers saved before masks existed are unchanged).
|
|
303
|
+
*/
|
|
304
|
+
mask?: AdjustmentLayerMask;
|
|
41
305
|
}
|
|
306
|
+
/**
|
|
307
|
+
* A layer mask: 8-bit coverage of the source image, run-length encoded (see
|
|
308
|
+
* `encodeSelectionRle`), plus non-destructive density and feather.
|
|
309
|
+
*/
|
|
310
|
+
interface AdjustmentLayerMask {
|
|
311
|
+
width: number;
|
|
312
|
+
height: number;
|
|
313
|
+
/** `r1:` run-length encoding of the mask bytes. */
|
|
314
|
+
rle: string;
|
|
315
|
+
/** 0..1 (missing = 1). */
|
|
316
|
+
density?: number;
|
|
317
|
+
/** Gaussian σ in pixels (missing = 0). */
|
|
318
|
+
feather?: number;
|
|
319
|
+
/** `false` keeps the mask but ignores it. */
|
|
320
|
+
enabled?: boolean;
|
|
321
|
+
}
|
|
322
|
+
/** A non-destructive adjustment layer (Photoshop's Layer › New Adjustment Layer). */
|
|
323
|
+
type AdjustmentLayer = {
|
|
324
|
+
[K in AdjustmentKind]: AdjustmentLayerBase & {
|
|
325
|
+
kind: K;
|
|
326
|
+
params: AdjustmentParamsMap[K];
|
|
327
|
+
};
|
|
328
|
+
}[AdjustmentKind];
|
|
329
|
+
type AdjustmentLayerOf<K extends AdjustmentKind> = Extract<AdjustmentLayer, {
|
|
330
|
+
kind: K;
|
|
331
|
+
}>;
|
|
42
332
|
interface DepthMaskOptions {
|
|
43
333
|
enabled: boolean;
|
|
44
334
|
maskSource: string | null;
|
|
@@ -55,6 +345,8 @@ interface BaseAnnotation {
|
|
|
55
345
|
y: number;
|
|
56
346
|
rotation?: number;
|
|
57
347
|
opacity?: number;
|
|
348
|
+
/** Blend mode the annotation is drawn with (default `normal`). */
|
|
349
|
+
blend?: BlendMode;
|
|
58
350
|
}
|
|
59
351
|
interface PenAnnotation extends BaseAnnotation {
|
|
60
352
|
type: 'pen';
|
|
@@ -123,14 +415,27 @@ interface ImageEditorState {
|
|
|
123
415
|
zoom: number;
|
|
124
416
|
pan: ImagePoint;
|
|
125
417
|
isOriginalCompared: boolean;
|
|
418
|
+
/**
|
|
419
|
+
* The active selection (8-bit coverage over the source image), or null/missing when nothing is
|
|
420
|
+
* selected. Recorded in undo history and saved as `selection` in `toJSON()`.
|
|
421
|
+
*/
|
|
422
|
+
selection?: SelectionMask | null;
|
|
423
|
+
/** Quick Mask view: tint the unselected area instead of drawing marching ants (view state). */
|
|
424
|
+
quickMask?: boolean;
|
|
126
425
|
}
|
|
127
426
|
interface SerializedImageEditorState {
|
|
128
|
-
|
|
427
|
+
/**
|
|
428
|
+
* Schema version. `2` adds `adjustments.layers`; states without layers are still written as
|
|
429
|
+
* `1` so they round-trip unchanged. See `migrateSerializedImageEditorState`.
|
|
430
|
+
*/
|
|
431
|
+
version: 1 | 2;
|
|
129
432
|
crop: CropBox | null;
|
|
130
433
|
transform: ImageTransform;
|
|
131
434
|
adjustments: ImageAdjustments;
|
|
132
435
|
depthMask: DepthMaskOptions;
|
|
133
436
|
annotations: Annotation[];
|
|
437
|
+
/** The active selection, run-length encoded. Missing when nothing is selected. */
|
|
438
|
+
selection?: SerializedSelection;
|
|
134
439
|
}
|
|
135
440
|
interface ExportOptions {
|
|
136
441
|
format?: 'image/png' | 'image/jpeg' | 'image/webp';
|
|
@@ -163,13 +468,15 @@ interface ImageEditorAIHooks {
|
|
|
163
468
|
|
|
164
469
|
/**
|
|
165
470
|
* Applies color and tone adjustments (brightness, contrast, saturation, exposure, temperature, tint,
|
|
166
|
-
* opacity, blur) directly to the pixel data of an ImageData buffer.
|
|
471
|
+
* opacity, then any adjustment `layers`, then blur) directly to the pixel data of an ImageData buffer.
|
|
167
472
|
*
|
|
168
473
|
* `adjustments.process` selects the rendering: `2` is the linear-light pipeline
|
|
169
474
|
* ({@link applyProcess2Adjustments}); anything else (including a missing value, as in edits saved
|
|
170
475
|
* before process versions existed) is the frozen legacy rendering ({@link applyLegacyAdjustments}).
|
|
171
476
|
*/
|
|
172
|
-
declare function applyAdjustments(imageData: ImageData, adjustments: ImageAdjustments
|
|
477
|
+
declare function applyAdjustments(imageData: ImageData, adjustments: ImageAdjustments, options?: {
|
|
478
|
+
layerMasks?: ReadonlyMap<string, ArrayLike<number>>;
|
|
479
|
+
}): void;
|
|
173
480
|
/**
|
|
174
481
|
* Process 1: the original 8-bit gamma-space rendering, clamping after every step. Frozen so
|
|
175
482
|
* that edits saved without a `process` look exactly as they always have. `tint` is ignored.
|
|
@@ -304,6 +611,47 @@ declare function buildToneLut(contrast: number, brightness: number, headroom?: n
|
|
|
304
611
|
/** Linearly interpolated lookup into a LUT from {@link buildToneLut}. */
|
|
305
612
|
declare function sampleToneLut(lut: Float32Array, headroom: number, y: number): number;
|
|
306
613
|
|
|
614
|
+
/** Display bins of a histogram. */
|
|
615
|
+
declare const HISTOGRAM_BINS = 256;
|
|
616
|
+
interface ImageHistogram {
|
|
617
|
+
/** 256-bin counts per channel. */
|
|
618
|
+
red: Uint32Array;
|
|
619
|
+
green: Uint32Array;
|
|
620
|
+
blue: Uint32Array;
|
|
621
|
+
/** 256-bin counts of Rec.709 luma `round(0.2126 R + 0.7152 G + 0.0722 B)` of the encoded values. */
|
|
622
|
+
luminance: Uint32Array;
|
|
623
|
+
/** Visible pixels counted (alpha > 0). Each counts once, partially transparent ones included. */
|
|
624
|
+
samples: number;
|
|
625
|
+
/** Fully transparent pixels, excluded from every bin. */
|
|
626
|
+
transparent: number;
|
|
627
|
+
/** Per channel (R, G, B): visible pixels at exactly 0. */
|
|
628
|
+
shadows: [number, number, number];
|
|
629
|
+
/** Per channel (R, G, B): visible pixels at exactly 255. */
|
|
630
|
+
highlights: [number, number, number];
|
|
631
|
+
/** Largest bin count over R, G, B and luminance (for scaling a plot). */
|
|
632
|
+
max: number;
|
|
633
|
+
}
|
|
634
|
+
interface PixelSource {
|
|
635
|
+
data: ArrayLike<number>;
|
|
636
|
+
width?: number;
|
|
637
|
+
height?: number;
|
|
638
|
+
}
|
|
639
|
+
/**
|
|
640
|
+
* Per-channel and luminance histograms of straight 8-bit RGBA pixels (an `ImageData` or anything
|
|
641
|
+
* with `data`), with clipping counts at the exact endpoints. Transparent pixels cannot add
|
|
642
|
+
* phantom peaks: they are counted separately and excluded.
|
|
643
|
+
*/
|
|
644
|
+
declare function computeHistogram(imageData: PixelSource): ImageHistogram;
|
|
645
|
+
type HistogramChannel = 'red' | 'green' | 'blue' | 'luminance';
|
|
646
|
+
/**
|
|
647
|
+
* An SVG path (`M … Z`) of one channel scaled into a `width` × `height` box, bins left to right,
|
|
648
|
+
* counts up from the bottom. `scale: 'sqrt'` (default) keeps small populations visible.
|
|
649
|
+
*/
|
|
650
|
+
declare function histogramPath(histogram: ImageHistogram, channel: HistogramChannel, width: number, height: number, options?: {
|
|
651
|
+
scale?: 'linear' | 'sqrt';
|
|
652
|
+
max?: number;
|
|
653
|
+
}): string;
|
|
654
|
+
|
|
307
655
|
interface RenderOptions {
|
|
308
656
|
viewportWidth?: number;
|
|
309
657
|
viewportHeight?: number;
|
|
@@ -312,6 +660,15 @@ interface RenderOptions {
|
|
|
312
660
|
interactive?: boolean;
|
|
313
661
|
draftAnnotation?: Annotation | null;
|
|
314
662
|
draftCrop?: CropBox | null;
|
|
663
|
+
/**
|
|
664
|
+
* How the active selection is shown: marching ants (default when there is a selection),
|
|
665
|
+
* a Quick Mask tint over the unselected area (default when `state.quickMask`), or not at all.
|
|
666
|
+
*/
|
|
667
|
+
selectionDisplay?: 'ants' | 'quickMask' | 'none';
|
|
668
|
+
/** Dash offset of the marching ants in screen pixels (animate it to make them march). */
|
|
669
|
+
antsOffset?: number;
|
|
670
|
+
/** A selection being drawn (e.g. a lasso), shown as a dashed outline in natural pixels. */
|
|
671
|
+
draftSelectionPath?: ImagePoint[] | null;
|
|
315
672
|
}
|
|
316
673
|
/**
|
|
317
674
|
* Image Cache to avoid refetching HTMLImageElement objects repeatedly during re-renders.
|
|
@@ -331,6 +688,13 @@ declare class ImageEditorRenderer {
|
|
|
331
688
|
imageCache: ImageCache;
|
|
332
689
|
private cachedBaseCanvas;
|
|
333
690
|
private cachedBaseKey;
|
|
691
|
+
/**
|
|
692
|
+
* Histogram of the last viewport base render (after adjustments and layers, before
|
|
693
|
+
* annotations); `null` until a render with pixel access has happened.
|
|
694
|
+
*/
|
|
695
|
+
previewHistogram: ImageHistogram | null;
|
|
696
|
+
/** Called whenever the viewport base image is re-rendered with the new histogram. */
|
|
697
|
+
onPreviewHistogram?: (histogram: ImageHistogram | null) => void;
|
|
334
698
|
private sourceIds;
|
|
335
699
|
private nextSourceId;
|
|
336
700
|
/**
|
|
@@ -346,11 +710,26 @@ declare class ImageEditorRenderer {
|
|
|
346
710
|
* and the depth mask (which receives the identical transform so it stays aligned).
|
|
347
711
|
*/
|
|
348
712
|
private renderBaseImage;
|
|
713
|
+
private quickMaskCache;
|
|
714
|
+
private outlineCache;
|
|
715
|
+
/** Rubylith over the unselected area, drawn in natural image space. */
|
|
716
|
+
private drawQuickMask;
|
|
717
|
+
/** Marching ants: a white line under a black dashed one, one screen pixel wide. */
|
|
718
|
+
private drawAnts;
|
|
719
|
+
private drawDraftPath;
|
|
349
720
|
private getSourceId;
|
|
350
721
|
/**
|
|
351
722
|
* Draws an individual annotation onto the canvas.
|
|
352
723
|
*/
|
|
353
724
|
drawAnnotation(ctx: CanvasRenderingContext2D, ann: Annotation): Promise<void>;
|
|
725
|
+
/**
|
|
726
|
+
* Scalar fallback for blend modes the canvas cannot composite (Photoshop soft light, linear /
|
|
727
|
+
* vivid / pin light, hard mix, subtract, divide, darker / lighter colour, linear burn / dodge):
|
|
728
|
+
* draws the annotation on a same-size layer with the same transform, blends it into a copy of
|
|
729
|
+
* the target's pixels with `blendImageData`, and copies the result back inside the current clip.
|
|
730
|
+
*/
|
|
731
|
+
private drawAnnotationBlended;
|
|
732
|
+
private drawAnnotationContent;
|
|
354
733
|
/**
|
|
355
734
|
* Draws selection box around active annotation.
|
|
356
735
|
*/
|
|
@@ -380,16 +759,400 @@ declare class ImageEditorRenderer {
|
|
|
380
759
|
renderMask(state: ImageEditorState, options?: {
|
|
381
760
|
useAnnotations?: boolean;
|
|
382
761
|
useCrop?: boolean;
|
|
762
|
+
useSelection?: boolean;
|
|
383
763
|
}): Promise<HTMLCanvasElement>;
|
|
384
764
|
private drawAnnotationMask;
|
|
385
765
|
}
|
|
386
766
|
|
|
767
|
+
interface ShapeSelectionOptions {
|
|
768
|
+
/** Partial coverage along the edge (default true). */
|
|
769
|
+
antiAlias?: boolean;
|
|
770
|
+
}
|
|
771
|
+
/**
|
|
772
|
+
* Even-odd polygon coverage over a `width × height` image: exact horizontal coverage on 4
|
|
773
|
+
* sub-rows per pixel row (1 without anti-aliasing, where a pixel is in when its centre is).
|
|
774
|
+
* Each sub-row only tests the edges that cross it (an active edge list over edges sorted by
|
|
775
|
+
* their top), so the cost is about pixels + edges × rows they span.
|
|
776
|
+
*/
|
|
777
|
+
declare function polygonCoverage(points: readonly ImagePoint[], width: number, height: number, antiAlias?: boolean): Float32Array;
|
|
778
|
+
/** Lasso / polygonal lasso: an even-odd polygon in natural image pixels. */
|
|
779
|
+
declare function polygonSelection(width: number, height: number, points: readonly ImagePoint[], options?: ShapeSelectionOptions): SelectionMask;
|
|
780
|
+
/** Normalises a rectangle with a negative width or height. */
|
|
781
|
+
declare function normalizeRect(rect: CropBox): CropBox;
|
|
782
|
+
/** Rectangular marquee. Fractional edges get partial coverage when anti-aliased. */
|
|
783
|
+
declare function rectSelection(width: number, height: number, rect: CropBox, options?: ShapeSelectionOptions): SelectionMask;
|
|
784
|
+
/** The ellipse inscribed in `rect` as a polygon fine enough that its chords stay within 0.05 px. */
|
|
785
|
+
declare function ellipsePoints(rect: CropBox): ImagePoint[];
|
|
786
|
+
/** Elliptical marquee inscribed in `rect`. */
|
|
787
|
+
declare function ellipseSelection(width: number, height: number, rect: CropBox, options?: ShapeSelectionOptions): SelectionMask;
|
|
788
|
+
|
|
789
|
+
/** How the magic wand measures colour difference. */
|
|
790
|
+
type ColorDistance = 'rgb' | 'perceptual';
|
|
791
|
+
interface MagicWandOptions {
|
|
792
|
+
/**
|
|
793
|
+
* 0..255. `rgb`: the largest per-channel difference in levels (alpha included), as
|
|
794
|
+
* Photoshop's wand. `perceptual`: CIE76 ΔE*ab, with 255 ≙ ΔE 100. Default 32.
|
|
795
|
+
*/
|
|
796
|
+
tolerance?: number;
|
|
797
|
+
/** Only the 4-connected region around the seed (default true); otherwise every similar pixel. */
|
|
798
|
+
contiguous?: boolean;
|
|
799
|
+
/** Soft one-pixel fringe on the edge (default true). */
|
|
800
|
+
antiAlias?: boolean;
|
|
801
|
+
/** Default `rgb`. */
|
|
802
|
+
distance?: ColorDistance;
|
|
803
|
+
}
|
|
804
|
+
/** CIE Lab (D65) of an 8-bit sRGB colour. */
|
|
805
|
+
declare function srgb8ToLab(r: number, g: number, b: number): [number, number, number];
|
|
806
|
+
/**
|
|
807
|
+
* Magic wand: pixels similar to the seed pixel. Contiguous mode is a scanline span fill with an
|
|
808
|
+
* explicit stack (fill a run, then scan the rows above and below it for new runs), so it is
|
|
809
|
+
* linear in the pixels visited and never recurses. An empty selection when the seed is outside.
|
|
810
|
+
*/
|
|
811
|
+
declare function magicWand(pixels: PixelBuffer, seed: ImagePoint, options?: MagicWandOptions): SelectionMask;
|
|
812
|
+
/** One Color Range sample: a colour (0..255 levels or `#rrggbb`) and, optionally, where it was picked. */
|
|
813
|
+
interface ColorRangeSample {
|
|
814
|
+
color: readonly [number, number, number] | string;
|
|
815
|
+
at?: ImagePoint;
|
|
816
|
+
}
|
|
817
|
+
interface ColorRangeOptions {
|
|
818
|
+
/** 0..200 levels (default 40): coverage falls off linearly to 0 at `fuzziness + 1` levels. */
|
|
819
|
+
fuzziness?: number;
|
|
820
|
+
/**
|
|
821
|
+
* Localized Color Clusters: a sample with a position also fades with distance from it,
|
|
822
|
+
* reaching 0 at this many pixels.
|
|
823
|
+
*/
|
|
824
|
+
localized?: number;
|
|
825
|
+
}
|
|
826
|
+
/**
|
|
827
|
+
* Select › Color Range › Sampled Colors: each pixel takes its best match over the samples; a
|
|
828
|
+
* match falls off linearly with the largest per-channel difference, `1 − d / (fuzziness + 1)`.
|
|
829
|
+
* Transparent pixels are never selected.
|
|
830
|
+
*/
|
|
831
|
+
declare function colorRange(pixels: PixelBuffer, samples: readonly ColorRangeSample[], options?: ColorRangeOptions): SelectionMask;
|
|
832
|
+
type ToneRangePreset = 'shadows' | 'midtones' | 'highlights';
|
|
833
|
+
/** Luma bounds (0..255, Rec. 601) of the tonal presets. */
|
|
834
|
+
declare const TONE_RANGE_PRESETS: Record<ToneRangePreset, [number, number]>;
|
|
835
|
+
/**
|
|
836
|
+
* Select › Color Range › Shadows / Midtones / Highlights: pixels whose luma lies in `lo..hi` are
|
|
837
|
+
* selected; outside, selection falls off linearly to 0 over `falloff` levels.
|
|
838
|
+
*/
|
|
839
|
+
declare function toneRange(pixels: PixelBuffer, range: ToneRangePreset | readonly [number, number], falloff?: number): SelectionMask;
|
|
840
|
+
/**
|
|
841
|
+
* Select › Color Range › Reds … Magentas (`center` 0, 60, …, 300°): closeness of hue (full at
|
|
842
|
+
* the centre, none 60° away) × chroma × (2 − max), so neutrals are never selected.
|
|
843
|
+
*/
|
|
844
|
+
declare function hueRange(pixels: PixelBuffer, center: number): SelectionMask;
|
|
845
|
+
|
|
846
|
+
/** Distance reported for every pixel when there is no seed at all. */
|
|
847
|
+
declare const EMPTY_DISTANCE = 10000000000;
|
|
848
|
+
/**
|
|
849
|
+
* Exact Euclidean distance from every pixel centre to the nearest seed pixel centre (row-major
|
|
850
|
+
* `inside`, non-zero = seed): nearest seeds along columns, then the lower envelope of parabolas
|
|
851
|
+
* along rows (Felzenszwalb & Huttenlocher). Linear in the pixel count.
|
|
852
|
+
*/
|
|
853
|
+
declare function distanceTransform(inside: ArrayLike<number | boolean>, width: number, height: number): Float32Array;
|
|
854
|
+
/** Grows coverage (0..1) by `r` pixels: covered when the nearest selected centre is ≤ r away (fractional r → partial). */
|
|
855
|
+
declare function expandCoverage(m: ArrayLike<number>, w: number, h: number, r: number): Float32Array;
|
|
856
|
+
/** Shrinks coverage by `r` pixels (expands the inverse). */
|
|
857
|
+
declare function contractCoverage(m: ArrayLike<number>, w: number, h: number, r: number): Float32Array;
|
|
858
|
+
/**
|
|
859
|
+
* Select › Modify › Border: a soft band `2r` wide centred on the edge. A pixel `D` away (centre
|
|
860
|
+
* to centre) from the nearest pixel on the other side of the edge is selected `1 − (D − 1) / r`.
|
|
861
|
+
*/
|
|
862
|
+
declare function borderCoverage(m: ArrayLike<number>, w: number, h: number, r: number): Float32Array;
|
|
863
|
+
/**
|
|
864
|
+
* Select › Modify › Smooth: box average of radius `round(r)` with replicated edges, then
|
|
865
|
+
* re-thresholded at ½ — specks drop, corners round, straight edges stay hard.
|
|
866
|
+
*/
|
|
867
|
+
declare function smoothCoverage(m: ArrayLike<number>, w: number, h: number, r: number): Float32Array;
|
|
868
|
+
/** Above this σ a Gaussian is approximated by three box passes (cost independent of σ). */
|
|
869
|
+
declare const DIRECT_GAUSSIAN_MAX_SIGMA = 8;
|
|
870
|
+
type Edge = 'zero' | 'clamp';
|
|
871
|
+
/**
|
|
872
|
+
* Separable Gaussian blur of a single-channel float image. `edge` `zero` treats pixels beyond
|
|
873
|
+
* the image as 0 (selection feather), `clamp` replicates the border (mask refinement). σ up to
|
|
874
|
+
* {@link DIRECT_GAUSSIAN_MAX_SIGMA} is convolved directly; wider blurs use three box passes, so
|
|
875
|
+
* the cost per pixel never grows with σ.
|
|
876
|
+
*/
|
|
877
|
+
declare function gaussianBlur(src: ArrayLike<number>, w: number, h: number, sigma: number, edge?: Edge): Float32Array;
|
|
878
|
+
/** Select › Modify › Feather: Gaussian blur with σ = radius (as Photoshop), zero beyond the image. */
|
|
879
|
+
declare function featherCoverage(m: ArrayLike<number>, w: number, h: number, radius: number): Float32Array;
|
|
880
|
+
/** Grey dilation (`grow`) or erosion with a square of radius `r`, separable, O(1) per pixel. */
|
|
881
|
+
declare function greyMorphology(src: ArrayLike<number>, w: number, h: number, r: number, grow: boolean): Float32Array;
|
|
882
|
+
/**
|
|
883
|
+
* Grows (positive) or shrinks (negative) soft coverage by a fractional distance: whole pixels
|
|
884
|
+
* use one morphology, the remainder blends with the next pixel, so 0.3 px differs from 1 px.
|
|
885
|
+
*/
|
|
886
|
+
declare function shiftCoverage(src: ArrayLike<number>, w: number, h: number, amount: number): Float32Array;
|
|
887
|
+
type SelectionModifyOp = 'grow' | 'shrink' | 'feather' | 'border' | 'smooth';
|
|
888
|
+
declare const SELECTION_MODIFY_OPS: readonly SelectionModifyOp[];
|
|
889
|
+
/** Select › Modify (grow = Expand, shrink = Contract, feather, border, smooth) by `radius` pixels. */
|
|
890
|
+
declare function modifySelection(mask: SelectionMask, op: SelectionModifyOp, radius: number): SelectionMask;
|
|
891
|
+
|
|
892
|
+
/**
|
|
893
|
+
* Refine Edge / Select and Mask parameters (Photoshop's units). Refinement is edge-aware: within
|
|
894
|
+
* `radius` pixels of the mask's edge the coverage is re-estimated from the image with a colour
|
|
895
|
+
* guided filter (He et al.), so a coarse or misaligned mask (e.g. an AI segmentation) follows
|
|
896
|
+
* the real edges of the image.
|
|
897
|
+
*/
|
|
898
|
+
interface RefineEdgeParams {
|
|
899
|
+
/** Edge-detection band radius in pixels (0 = no edge detection). */
|
|
900
|
+
radius?: number;
|
|
901
|
+
/** Narrow the band where the image edge is sharp (hair stays soft, hard edges stay hard). */
|
|
902
|
+
smartRadius?: boolean;
|
|
903
|
+
/** 0..100: rounds jagged edges. */
|
|
904
|
+
smooth?: number;
|
|
905
|
+
/** Pixels of Gaussian softening. */
|
|
906
|
+
feather?: number;
|
|
907
|
+
/** 0..100: hardens soft edges. */
|
|
908
|
+
contrast?: number;
|
|
909
|
+
/** −100..100: moves the edge out (positive) or in; 100 % is `max(radius, 4)` pixels. */
|
|
910
|
+
shiftEdge?: number;
|
|
911
|
+
}
|
|
912
|
+
declare const DEFAULT_REFINE_EDGE_PARAMS: Required<RefineEdgeParams>;
|
|
913
|
+
/** Guided-filter regulariser (colour guide, samples in 0..1). */
|
|
914
|
+
declare const GUIDED_FILTER_EPS = 0.0001;
|
|
915
|
+
/** Clamped, complete parameters. */
|
|
916
|
+
declare function normalizeRefineEdgeParams(p?: RefineEdgeParams): Required<RefineEdgeParams>;
|
|
917
|
+
/** Pixels around the mask's content that refinement can read or write. */
|
|
918
|
+
declare function refineEdgeHalo(params?: RefineEdgeParams): number;
|
|
919
|
+
/** Box mean of radius `r` (window clipped to the image, divided by its pixel count). O(1) per pixel. */
|
|
920
|
+
declare function boxMean(src: ArrayLike<number>, w: number, h: number, r: number): Float32Array;
|
|
921
|
+
/**
|
|
922
|
+
* Guided filter with a colour guide (He et al., Eq. 19–21: `a_k = (Σ_k + εU)⁻¹ cov_k(I, p)`):
|
|
923
|
+
* filters `p` so that it is locally a linear function of the guide's colour, which makes the
|
|
924
|
+
* output's edges follow the guide's edges. `guide` is three planes of 0..1 values.
|
|
925
|
+
*/
|
|
926
|
+
declare function guidedFilterColor(guide: readonly [Float32Array, Float32Array, Float32Array], p: Float32Array, w: number, h: number, r: number, eps?: number): Float32Array;
|
|
927
|
+
/**
|
|
928
|
+
* Per-pixel transition width (pixels) of the guide's luminance: local range over local maximum
|
|
929
|
+
* gradient in a window of radius `r` (a sharp step gives about 2, a ramp of width L about L).
|
|
930
|
+
*/
|
|
931
|
+
declare function edgeWidth(guide: readonly [Float32Array, Float32Array, Float32Array], w: number, h: number, r: number): Float32Array;
|
|
932
|
+
/**
|
|
933
|
+
* Refines soft coverage `m` (`w × h`, 0..1) with `guide` (three 0..1 planes, required when
|
|
934
|
+
* `radius > 0`): edge-aware re-estimation in a band around the edge, then smooth, feather,
|
|
935
|
+
* contrast and shift edge, in that order.
|
|
936
|
+
*/
|
|
937
|
+
declare function refineCoverage(guide: readonly [Float32Array, Float32Array, Float32Array] | null, m: Float32Array, w: number, h: number, params?: RefineEdgeParams): Float32Array;
|
|
938
|
+
/** Three 0..1 planes of a window of an RGBA buffer. */
|
|
939
|
+
declare function guidePlanes(pixels: PixelBuffer, win?: CropBox): [Float32Array, Float32Array, Float32Array];
|
|
940
|
+
/**
|
|
941
|
+
* Refine Edge on a selection (or a coarse AI mask loaded as one) against `pixels` (the image,
|
|
942
|
+
* same size). Work is confined to the mask's bounds grown by {@link refineEdgeHalo}, so a small
|
|
943
|
+
* selection on a large image stays cheap.
|
|
944
|
+
*/
|
|
945
|
+
declare function refineSelection(pixels: PixelBuffer | null, mask: SelectionMask, params?: RefineEdgeParams): SelectionMask;
|
|
946
|
+
|
|
947
|
+
type CropHandle = 'nw' | 'ne' | 'se' | 'sw' | 'n' | 's' | 'e' | 'w' | 'inside' | null;
|
|
948
|
+
interface ViewportMetrics {
|
|
949
|
+
vpWidth: number;
|
|
950
|
+
vpHeight: number;
|
|
951
|
+
centerX: number;
|
|
952
|
+
centerY: number;
|
|
953
|
+
baseW: number;
|
|
954
|
+
baseH: number;
|
|
955
|
+
fitScale: number;
|
|
956
|
+
renderW: number;
|
|
957
|
+
renderH: number;
|
|
958
|
+
totalScale: number;
|
|
959
|
+
imageRect: {
|
|
960
|
+
x: number;
|
|
961
|
+
y: number;
|
|
962
|
+
width: number;
|
|
963
|
+
height: number;
|
|
964
|
+
};
|
|
965
|
+
cropRect: {
|
|
966
|
+
x: number;
|
|
967
|
+
y: number;
|
|
968
|
+
width: number;
|
|
969
|
+
height: number;
|
|
970
|
+
} | null;
|
|
971
|
+
}
|
|
972
|
+
/**
|
|
973
|
+
* A complete description of the natural-image -> target mapping (see module comment).
|
|
974
|
+
*/
|
|
975
|
+
interface ImageProjection {
|
|
976
|
+
/** Visible region in natural image pixels (crop box or full image). */
|
|
977
|
+
region: CropBox;
|
|
978
|
+
/** Rotation in degrees, normalised to [0, 360). */
|
|
979
|
+
angle: number;
|
|
980
|
+
flipH: boolean;
|
|
981
|
+
flipV: boolean;
|
|
982
|
+
/** Uniform scale from image pixels to target pixels. */
|
|
983
|
+
scale: number;
|
|
984
|
+
/** Target-space point that the centre of `region` maps to. */
|
|
985
|
+
originX: number;
|
|
986
|
+
originY: number;
|
|
987
|
+
}
|
|
988
|
+
/** Normalises any rotation in degrees to [0, 360). */
|
|
989
|
+
declare function normalizeAngle(degrees: number): number;
|
|
990
|
+
/** Whether the rotation swaps the displayed width and height. */
|
|
991
|
+
declare function isQuarterTurnSwapped(transform: Pick<ImageTransform, 'rotate'>): boolean;
|
|
992
|
+
/** Size of a region once rotated (bounding box for arbitrary angles). */
|
|
993
|
+
declare function getRotatedSize(width: number, height: number, transform: Pick<ImageTransform, 'rotate'>): {
|
|
994
|
+
width: number;
|
|
995
|
+
height: number;
|
|
996
|
+
};
|
|
997
|
+
/** Maps a natural-image point to target space. */
|
|
998
|
+
declare function projectImagePoint(pt: ImagePoint, p: ImageProjection): ImagePoint;
|
|
999
|
+
/** Exact inverse of {@link projectImagePoint}. */
|
|
1000
|
+
declare function unprojectCanvasPoint(pt: ImagePoint, p: ImageProjection): ImagePoint;
|
|
1001
|
+
/**
|
|
1002
|
+
* Applies the projection to a 2D context so that subsequent drawing in natural image
|
|
1003
|
+
* pixels lands exactly where {@link projectImagePoint} says it does.
|
|
1004
|
+
*/
|
|
1005
|
+
declare function applyImageProjectionToContext(ctx: Pick<CanvasRenderingContext2D, 'translate' | 'scale' | 'rotate'>, p: ImageProjection): void;
|
|
1006
|
+
/** Projects an image-space rectangle and returns its target-space bounding box. */
|
|
1007
|
+
declare function projectImageRect(rect: CropBox, p: ImageProjection): {
|
|
1008
|
+
x: number;
|
|
1009
|
+
y: number;
|
|
1010
|
+
width: number;
|
|
1011
|
+
height: number;
|
|
1012
|
+
};
|
|
1013
|
+
/** Clamps a crop box to the image bounds. */
|
|
1014
|
+
declare function clampCropToImage(crop: CropBox, width: number, height: number): CropBox;
|
|
1015
|
+
/**
|
|
1016
|
+
* Returns the natural-image -> canvas projection used by the interactive viewport.
|
|
1017
|
+
*/
|
|
1018
|
+
declare function getViewportProjection(state: ImageEditorState, vpWidth: number, vpHeight: number, isActivelyCropping?: boolean, cropOverride?: CropBox | null): ImageProjection;
|
|
1019
|
+
/**
|
|
1020
|
+
* Calculates current viewport projection metrics for canvas <-> image coordinate mapping.
|
|
1021
|
+
* `cropRect` is the on-screen (rotated/flipped) rectangle of the crop box.
|
|
1022
|
+
*/
|
|
1023
|
+
declare function getViewportMetrics(state: ImageEditorState, vpWidth: number, vpHeight: number, isActivelyCropping?: boolean, cropOverride?: CropBox | null): ViewportMetrics;
|
|
1024
|
+
/**
|
|
1025
|
+
* Converts a point on the canvas (in internal canvas pixel space) to natural image pixel
|
|
1026
|
+
* space, accounting for zoom, pan, fit scale, crop offset, rotation and flips.
|
|
1027
|
+
*/
|
|
1028
|
+
declare function canvasToImagePoint(canvasPt: ImagePoint, state: ImageEditorState, vpWidth: number, vpHeight: number, isActivelyCropping?: boolean): ImagePoint;
|
|
1029
|
+
/**
|
|
1030
|
+
* Converts a point in natural image pixel space to internal canvas pixel space.
|
|
1031
|
+
* Exact inverse of {@link canvasToImagePoint}.
|
|
1032
|
+
*/
|
|
1033
|
+
declare function imageToCanvasPoint(imgPt: ImagePoint, state: ImageEditorState, vpWidth: number, vpHeight: number, isActivelyCropping?: boolean): ImagePoint;
|
|
1034
|
+
/**
|
|
1035
|
+
* Converts a crop handle in screen orientation to the equivalent edge/corner of the crop
|
|
1036
|
+
* box in natural image space, or the reverse with `toScreen = true`.
|
|
1037
|
+
*/
|
|
1038
|
+
declare function mapCropHandle(handle: CropHandle, transform: ImageTransform, toScreen?: boolean): CropHandle;
|
|
1039
|
+
/**
|
|
1040
|
+
* Hit-tests the crop box and its corner/edge handles given a canvas point.
|
|
1041
|
+
* The returned handle names the edge/corner of the crop box in natural image space
|
|
1042
|
+
* (what {@link calculateCropDrag} expects); use `getCropCursor(handle, state.transform)`
|
|
1043
|
+
* to obtain the matching on-screen cursor.
|
|
1044
|
+
*/
|
|
1045
|
+
declare function hitTestCrop(canvasPt: ImagePoint, state: ImageEditorState, vpWidth: number, vpHeight: number, handleThreshold?: number, cropOverride?: CropBox | null): CropHandle;
|
|
1046
|
+
/**
|
|
1047
|
+
* Returns CSS cursor style corresponding to a crop handle. Pass the current transform when
|
|
1048
|
+
* the handle comes from {@link hitTestCrop} (image space) so the cursor matches the
|
|
1049
|
+
* on-screen orientation under rotation/flip.
|
|
1050
|
+
*/
|
|
1051
|
+
declare function getCropCursor(handle: CropHandle, transform?: ImageTransform): string;
|
|
1052
|
+
/**
|
|
1053
|
+
* Calculates updated crop rectangle given a drag interaction.
|
|
1054
|
+
*/
|
|
1055
|
+
declare function calculateCropDrag(startCrop: CropBox, handle: CropHandle, startImgPt: ImagePoint, currentImgPt: ImagePoint, imgWidth: number, imgHeight: number, aspectRatio?: number | null, transform?: ImageTransform): CropBox;
|
|
1056
|
+
/**
|
|
1057
|
+
* Calculates bounding box of an annotation.
|
|
1058
|
+
*/
|
|
1059
|
+
declare function getAnnotationBounds(ann: Annotation): {
|
|
1060
|
+
x: number;
|
|
1061
|
+
y: number;
|
|
1062
|
+
width: number;
|
|
1063
|
+
height: number;
|
|
1064
|
+
};
|
|
1065
|
+
/**
|
|
1066
|
+
* Hit tests if a point in image space is within an annotation's bounds.
|
|
1067
|
+
*/
|
|
1068
|
+
declare function hitTestAnnotation(imgPt: ImagePoint, ann: Annotation, padding?: number): boolean;
|
|
1069
|
+
|
|
1070
|
+
/** Properties of a layer mask that leave its pixels intact (Photoshop's Properties › Masks). */
|
|
1071
|
+
interface LayerMaskProps {
|
|
1072
|
+
/** 0..1 (default 1): at 0.5 the masked-out areas still get half of the adjustment. */
|
|
1073
|
+
density?: number;
|
|
1074
|
+
/** Gaussian feather σ in pixels, 0..1000 (default 0). */
|
|
1075
|
+
feather?: number;
|
|
1076
|
+
/** Disabled masks are kept but ignored (the layer applies everywhere). Default true. */
|
|
1077
|
+
enabled?: boolean;
|
|
1078
|
+
}
|
|
1079
|
+
/**
|
|
1080
|
+
* A clean layer mask from stored data, or `null` when it is unusable. Defaults are left out
|
|
1081
|
+
* (density 1, feather 0, enabled), so a plain mask serializes as `{width, height, rle}`. The
|
|
1082
|
+
* RLE is only decoded when rendering.
|
|
1083
|
+
*/
|
|
1084
|
+
declare function normalizeLayerMask(raw: unknown): AdjustmentLayerMask | null;
|
|
1085
|
+
/** A layer mask holding the selection's pixels (Add Layer Mask › Reveal Selection). */
|
|
1086
|
+
declare function layerMaskFromSelection(selection: SelectionMask, props?: LayerMaskProps): AdjustmentLayerMask;
|
|
1087
|
+
/** Applies property changes; `undefined` fields keep their value. */
|
|
1088
|
+
declare function updateLayerMaskProps(mask: AdjustmentLayerMask, props: LayerMaskProps): AdjustmentLayerMask;
|
|
1089
|
+
/** The mask's pixels as a selection (Load Selection from mask), or `null` when the data is damaged. */
|
|
1090
|
+
declare function decodeLayerMask(mask: AdjustmentLayerMask): SelectionMask | null;
|
|
1091
|
+
/** Cache key of everything about a mask that changes pixels. */
|
|
1092
|
+
declare function layerMaskKey(mask: AdjustmentLayerMask | undefined): string;
|
|
1093
|
+
/**
|
|
1094
|
+
* The mask's effective coverage (0..1, mask resolution): feathered (σ = feather, borders
|
|
1095
|
+
* replicated), then density applied as `1 − density·(1 − v)`. `null` for a disabled or damaged
|
|
1096
|
+
* mask, meaning "no mask".
|
|
1097
|
+
*/
|
|
1098
|
+
declare function layerMaskCoverage(mask: AdjustmentLayerMask): Float32Array | null;
|
|
1099
|
+
/**
|
|
1100
|
+
* Resamples mask coverage (natural-image aligned, any resolution) into a target raster drawn
|
|
1101
|
+
* through `projection` (the base canvas of the renderer: crop, rotation, flips): each target
|
|
1102
|
+
* pixel centre is unprojected to natural pixels and sampled bilinearly.
|
|
1103
|
+
*/
|
|
1104
|
+
declare function projectMaskCoverage(coverage: Float32Array, maskWidth: number, maskHeight: number, naturalWidth: number, naturalHeight: number, projection: ImageProjection, targetWidth: number, targetHeight: number): Float32Array;
|
|
1105
|
+
/**
|
|
1106
|
+
* Per-layer mask coverage for a render target, keyed by layer id; `undefined` when no layer has
|
|
1107
|
+
* an enabled, valid mask (so mask-free stacks take the exact same path as before).
|
|
1108
|
+
*/
|
|
1109
|
+
declare function buildLayerMaskPlanes(layers: readonly AdjustmentLayer[] | undefined, naturalWidth: number, naturalHeight: number, projection: ImageProjection, targetWidth: number, targetHeight: number): Map<string, Float32Array> | undefined;
|
|
1110
|
+
|
|
1111
|
+
/** Latest serialized schema version (`2`: adjustment layers). */
|
|
1112
|
+
declare const IMAGE_EDITOR_SCHEMA_VERSION: 2;
|
|
1113
|
+
/** Changes to an adjustment layer; `params` is merged into the current parameters. */
|
|
1114
|
+
interface AdjustmentLayerUpdate<K extends AdjustmentKind = AdjustmentKind> {
|
|
1115
|
+
params?: Partial<AdjustmentParamsMap[K]>;
|
|
1116
|
+
enabled?: boolean;
|
|
1117
|
+
opacity?: number;
|
|
1118
|
+
blend?: BlendMode;
|
|
1119
|
+
name?: string;
|
|
1120
|
+
/** A layer mask, or `null` to remove it. */
|
|
1121
|
+
mask?: AdjustmentLayerMask | null;
|
|
1122
|
+
}
|
|
1123
|
+
/** Options shared by the selection commands. */
|
|
1124
|
+
interface SelectionCommandOptions {
|
|
1125
|
+
/** How the result combines with the current selection (default `replace`). */
|
|
1126
|
+
mode?: SelectionMode;
|
|
1127
|
+
/** Feather the new shape by this many pixels before combining (default 0). */
|
|
1128
|
+
feather?: number;
|
|
1129
|
+
}
|
|
1130
|
+
/** Where the selection tools read colours from. */
|
|
1131
|
+
interface SampleOptions {
|
|
1132
|
+
/** Sample the adjusted image (base adjustments and layers) instead of the source pixels. */
|
|
1133
|
+
sampleMerged?: boolean;
|
|
1134
|
+
/** Pixels to use instead of reading the source image (natural size, RGBA). */
|
|
1135
|
+
pixels?: PixelBuffer;
|
|
1136
|
+
}
|
|
1137
|
+
/** A new adjustment layer: its kind plus optional initial values. */
|
|
1138
|
+
interface AdjustmentLayerInit<K extends AdjustmentKind = AdjustmentKind> extends AdjustmentLayerUpdate<K> {
|
|
1139
|
+
kind: K;
|
|
1140
|
+
id?: string;
|
|
1141
|
+
}
|
|
387
1142
|
declare const DEFAULT_ADJUSTMENTS: ImageAdjustments;
|
|
388
1143
|
/**
|
|
389
1144
|
* Fills in defaults for stored adjustments. A stored object without `process` was saved before
|
|
390
1145
|
* process versions existed and keeps the legacy rendering.
|
|
391
1146
|
*/
|
|
392
1147
|
declare function normalizeStoredAdjustments(stored: Partial<ImageAdjustments> | undefined | null): ImageAdjustments;
|
|
1148
|
+
/**
|
|
1149
|
+
* Brings a stored editor state of any schema version to the current shape. Version 1 (and a
|
|
1150
|
+
* missing version) has no adjustment layers; everything else is unchanged, so old states load
|
|
1151
|
+
* and render exactly as before.
|
|
1152
|
+
*/
|
|
1153
|
+
declare function migrateSerializedImageEditorState(data: Partial<SerializedImageEditorState> & {
|
|
1154
|
+
version?: number;
|
|
1155
|
+
}): SerializedImageEditorState;
|
|
393
1156
|
declare const DEFAULT_TRANSFORM: ImageTransform;
|
|
394
1157
|
declare const DEFAULT_DEPTH_MASK: DepthMaskOptions;
|
|
395
1158
|
/**
|
|
@@ -401,12 +1164,16 @@ declare class ImageEditorController {
|
|
|
401
1164
|
private renderer;
|
|
402
1165
|
private imageElement;
|
|
403
1166
|
private listeners;
|
|
1167
|
+
private histogramListeners;
|
|
404
1168
|
private onStateChange?;
|
|
405
1169
|
private undoStack;
|
|
406
1170
|
private redoStack;
|
|
407
1171
|
private maxHistoryDepth;
|
|
408
1172
|
private isApplyingHistory;
|
|
409
1173
|
private initialSnapshot;
|
|
1174
|
+
/** Pixels the selection tools sample (host-provided or read back from the source). */
|
|
1175
|
+
private samplePixels;
|
|
1176
|
+
private samplePixelsOverride;
|
|
410
1177
|
constructor(options?: ImageEditorOptions);
|
|
411
1178
|
/**
|
|
412
1179
|
* Loads a new source image and makes it the baseline that `reset()` returns to.
|
|
@@ -443,7 +1210,111 @@ declare class ImageEditorController {
|
|
|
443
1210
|
* rendering process (one undo step). Returns false when already current.
|
|
444
1211
|
*/
|
|
445
1212
|
upgradeProcess(): boolean;
|
|
1213
|
+
/** Resets the base sliders (latest process). Adjustment layers are kept; see `clearAdjustmentLayers`. */
|
|
446
1214
|
resetAdjustments(): void;
|
|
1215
|
+
/** The adjustment layers, bottom (first) to top (last). */
|
|
1216
|
+
getAdjustmentLayers(): AdjustmentLayer[];
|
|
1217
|
+
getAdjustmentLayer(id: string): AdjustmentLayer | undefined;
|
|
1218
|
+
private setLayers;
|
|
1219
|
+
/**
|
|
1220
|
+
* Adds an adjustment layer on top (or at `index`, 0 = bottom) as one undo step and returns
|
|
1221
|
+
* its id. `kind` alone gives neutral parameters.
|
|
1222
|
+
*/
|
|
1223
|
+
addAdjustmentLayer<K extends AdjustmentKind>(init: K | AdjustmentLayerInit<K>, index?: number): string;
|
|
1224
|
+
/**
|
|
1225
|
+
* Updates a layer (`params` merged into the current ones, then normalised). Pass
|
|
1226
|
+
* `commitToHistory = false` for the moves of a drag after recording its start once.
|
|
1227
|
+
* Returns false for an unknown id.
|
|
1228
|
+
*/
|
|
1229
|
+
updateAdjustmentLayer(id: string, update: AdjustmentLayerUpdate, commitToHistory?: boolean): boolean;
|
|
1230
|
+
/** Removes a layer as one undo step. Returns false for an unknown id. */
|
|
1231
|
+
removeAdjustmentLayer(id: string): boolean;
|
|
1232
|
+
/** Moves a layer to `toIndex` (0 = bottom) as one undo step. Returns false if nothing moved. */
|
|
1233
|
+
moveAdjustmentLayer(id: string, toIndex: number): boolean;
|
|
1234
|
+
/** Shows or hides a layer (flips it without `enabled`) as one undo step. */
|
|
1235
|
+
toggleAdjustmentLayer(id: string, enabled?: boolean): boolean;
|
|
1236
|
+
/** Removes every adjustment layer as one undo step. */
|
|
1237
|
+
clearAdjustmentLayers(): void;
|
|
1238
|
+
/** The active selection, or `null`. */
|
|
1239
|
+
getSelection(): SelectionMask | null;
|
|
1240
|
+
get hasSelection(): boolean;
|
|
1241
|
+
private get naturalSize();
|
|
1242
|
+
private dropMismatchedSelection;
|
|
1243
|
+
/**
|
|
1244
|
+
* Replaces the selection, or combines `mask` with it by `mode`, as one undo step. A mask of a
|
|
1245
|
+
* different size (e.g. an AI segmentation at another resolution) is resampled to the image.
|
|
1246
|
+
* Returns false when nothing changed.
|
|
1247
|
+
*/
|
|
1248
|
+
setSelection(mask: SelectionMask | null, mode?: SelectionMode): boolean;
|
|
1249
|
+
/** Select › All. */
|
|
1250
|
+
selectAll(): boolean;
|
|
1251
|
+
/** Select › Deselect. */
|
|
1252
|
+
deselect(): boolean;
|
|
1253
|
+
/** Select › Inverse (with nothing selected, selects everything). */
|
|
1254
|
+
invertSelection(): boolean;
|
|
1255
|
+
private shapeCommand;
|
|
1256
|
+
/** Rectangular marquee in natural image pixels. */
|
|
1257
|
+
selectRect(rect: CropBox, options?: SelectionCommandOptions & ShapeSelectionOptions): boolean;
|
|
1258
|
+
/** Elliptical marquee inscribed in `rect`. */
|
|
1259
|
+
selectEllipse(rect: CropBox, options?: SelectionCommandOptions & ShapeSelectionOptions): boolean;
|
|
1260
|
+
/** Lasso / polygonal lasso. */
|
|
1261
|
+
selectPolygon(points: ImagePoint[], options?: SelectionCommandOptions & ShapeSelectionOptions): boolean;
|
|
1262
|
+
/**
|
|
1263
|
+
* Supplies the pixels the selection tools sample (natural size RGBA), e.g. decoded in a worker
|
|
1264
|
+
* or in a test; `null` goes back to reading the source image. A new source image clears it.
|
|
1265
|
+
*/
|
|
1266
|
+
setSamplePixels(pixels: PixelBuffer | null): void;
|
|
1267
|
+
/**
|
|
1268
|
+
* The pixels the selection tools sample: the source image at natural size, or with
|
|
1269
|
+
* `sampleMerged` the source after the base adjustments and adjustment layers (no crop,
|
|
1270
|
+
* rotation or annotations). `null` without pixel access (no DOM, tainted canvas).
|
|
1271
|
+
*/
|
|
1272
|
+
getSamplePixels(options?: SampleOptions): Promise<PixelBuffer | null>;
|
|
1273
|
+
private requirePixels;
|
|
1274
|
+
/**
|
|
1275
|
+
* Magic wand at `point` (natural image pixels). Resolves to the resulting selection (null when
|
|
1276
|
+
* nothing is selected).
|
|
1277
|
+
*/
|
|
1278
|
+
magicWand(point: ImagePoint, options?: MagicWandOptions & SelectionCommandOptions & SampleOptions): Promise<SelectionMask | null>;
|
|
1279
|
+
/** Select › Color Range with colour samples (`#rrggbb` or `[r, g, b]`, optionally where they were picked). */
|
|
1280
|
+
selectColorRange(samples: ColorRangeSample[], options?: ColorRangeOptions & SelectionCommandOptions & SampleOptions): Promise<SelectionMask | null>;
|
|
1281
|
+
/** Select › Modify: grow, shrink, feather, border or smooth by `radius` pixels (one undo step). */
|
|
1282
|
+
modifySelection(op: SelectionModifyOp, radius: number): boolean;
|
|
1283
|
+
/**
|
|
1284
|
+
* Refine Edge: snaps the selection (e.g. a coarse AI mask loaded with `loadSelectionFromImage`)
|
|
1285
|
+
* to the image's edges with a guided filter, then smooth / feather / contrast / shift edge.
|
|
1286
|
+
*/
|
|
1287
|
+
refineSelection(params: RefineEdgeParams, options?: SampleOptions): Promise<boolean>;
|
|
1288
|
+
/**
|
|
1289
|
+
* Loads a selection from a mask image (an AI segmentation, a saved mask): a data URL / URL or
|
|
1290
|
+
* RGBA pixels, by luminance (white = selected) or a channel. Any size; it is resampled.
|
|
1291
|
+
*/
|
|
1292
|
+
loadSelectionFromImage(source: string | PixelBuffer, options?: {
|
|
1293
|
+
channel?: SelectionChannel;
|
|
1294
|
+
invert?: boolean;
|
|
1295
|
+
threshold?: number;
|
|
1296
|
+
mode?: SelectionMode;
|
|
1297
|
+
}): Promise<SelectionMask | null>;
|
|
1298
|
+
/** Quick Mask view (tints the unselected area). View state: no undo step. */
|
|
1299
|
+
setQuickMask(on: boolean): void;
|
|
1300
|
+
/**
|
|
1301
|
+
* Adds the selection as the layer's mask (Reveal Selection), replacing any mask, as one undo
|
|
1302
|
+
* step. Without a selection, returns false.
|
|
1303
|
+
*/
|
|
1304
|
+
applySelectionAsLayerMask(layerId: string, props?: LayerMaskProps): boolean;
|
|
1305
|
+
/** Sets (from a selection-shaped mask) or removes (`null`) a layer's mask as one undo step. */
|
|
1306
|
+
setAdjustmentLayerMask(layerId: string, mask: SelectionMask | null, props?: LayerMaskProps): boolean;
|
|
1307
|
+
/** Changes a layer mask's density (0..1), feather (px) or enabled flag; the mask pixels are kept. */
|
|
1308
|
+
setAdjustmentLayerMaskProps(layerId: string, props: LayerMaskProps, commitToHistory?: boolean): boolean;
|
|
1309
|
+
/** Load Selection from a layer mask (its pixels; density and feather are not applied). */
|
|
1310
|
+
selectionFromLayerMask(layerId: string, mode?: SelectionMode): boolean;
|
|
1311
|
+
/**
|
|
1312
|
+
* Histogram of the last rendered preview (after adjustments and layers, before annotations),
|
|
1313
|
+
* or `null` before the first render or without canvas pixel access.
|
|
1314
|
+
*/
|
|
1315
|
+
getHistogram(): ImageHistogram | null;
|
|
1316
|
+
/** Calls `listener` now and whenever a render produces a new preview histogram. */
|
|
1317
|
+
subscribeHistogram(listener: (histogram: ImageHistogram | null) => void): () => void;
|
|
447
1318
|
setDepthMask(partial: Partial<DepthMaskOptions>): void;
|
|
448
1319
|
resetDepthMask(): void;
|
|
449
1320
|
addAnnotation(annotation: CreateAnnotationPayload): string;
|
|
@@ -464,10 +1335,12 @@ declare class ImageEditorController {
|
|
|
464
1335
|
renderMask(options?: {
|
|
465
1336
|
useAnnotations?: boolean;
|
|
466
1337
|
useCrop?: boolean;
|
|
1338
|
+
useSelection?: boolean;
|
|
467
1339
|
}): Promise<HTMLCanvasElement>;
|
|
468
1340
|
toMaskDataURL(options?: {
|
|
469
1341
|
useAnnotations?: boolean;
|
|
470
1342
|
useCrop?: boolean;
|
|
1343
|
+
useSelection?: boolean;
|
|
471
1344
|
}): Promise<string>;
|
|
472
1345
|
/**
|
|
473
1346
|
* Renders the current source image at natural size with no crop, rotation, flip,
|
|
@@ -487,133 +1360,412 @@ declare class ImageEditorController {
|
|
|
487
1360
|
*/
|
|
488
1361
|
applyBackgroundRemovedImage(newDataUrl: string): Promise<void>;
|
|
489
1362
|
private replaceSource;
|
|
1363
|
+
/** The serializable state; `selection` is included (run-length encoded) only when something is selected. */
|
|
490
1364
|
toJSON(): SerializedImageEditorState;
|
|
491
1365
|
loadJSON(data: SerializedImageEditorState): void;
|
|
492
1366
|
private serializeState;
|
|
493
1367
|
private applySerializedState;
|
|
494
1368
|
}
|
|
495
1369
|
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
x: number;
|
|
510
|
-
y: number;
|
|
511
|
-
width: number;
|
|
512
|
-
height: number;
|
|
513
|
-
};
|
|
514
|
-
cropRect: {
|
|
515
|
-
x: number;
|
|
516
|
-
y: number;
|
|
517
|
-
width: number;
|
|
518
|
-
height: number;
|
|
519
|
-
} | null;
|
|
1370
|
+
/** The `version` that `ImageEditorController.toJSON()` writes. */
|
|
1371
|
+
declare const IMAGE_EDITOR_STATE_VERSION = 1;
|
|
1372
|
+
/**
|
|
1373
|
+
* Migration steps for `SerializedImageEditorState`, keyed by the version they
|
|
1374
|
+
* start from. Empty while only version 1 exists.
|
|
1375
|
+
*/
|
|
1376
|
+
declare const imageEditorStateMigrations: Record<number, MigrationStep>;
|
|
1377
|
+
interface ImageEditorDocumentLoad {
|
|
1378
|
+
/** State to pass to `loadJSON` / `initialState`. */
|
|
1379
|
+
state: SerializedImageEditorState;
|
|
1380
|
+
report: LoadReport;
|
|
1381
|
+
/** Top-level keys this build does not know; spread them into the saved JSON to keep them. */
|
|
1382
|
+
unknown: JsonObject;
|
|
520
1383
|
}
|
|
521
1384
|
/**
|
|
522
|
-
*
|
|
1385
|
+
* Loads stored image editor state (a JSON string or object) with a `LoadReport`:
|
|
1386
|
+
*
|
|
1387
|
+
* - Runs `imageEditorStateMigrations` up to `IMAGE_EDITOR_STATE_VERSION`; a missing
|
|
1388
|
+
* `version` is taken as current.
|
|
1389
|
+
* - A newer `version` is still loaded but reported `readOnly`: do not save over it.
|
|
1390
|
+
* - Each section (`crop`, `transform`, `adjustments`, `depthMask`, `annotations`, and the
|
|
1391
|
+
* optional run-length encoded `selection`)
|
|
1392
|
+
* falls back to its default on its own; invalid annotations are dropped one by one.
|
|
1393
|
+
* - Unknown top-level keys are returned in `unknown`.
|
|
1394
|
+
*
|
|
1395
|
+
* Valid state from `toJSON()` comes back unchanged, so `loadJSON(state)` behaves
|
|
1396
|
+
* exactly as with the raw object.
|
|
523
1397
|
*/
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
1398
|
+
declare function loadImageEditorDocument(input: unknown): ImageEditorDocumentLoad;
|
|
1399
|
+
|
|
1400
|
+
/**
|
|
1401
|
+
* Adjustment layers: Photoshop-matching evaluation on encoded sRGB colours in 0..1.
|
|
1402
|
+
*
|
|
1403
|
+
* Every layer is compiled once per parameter change into a per-pixel function (per-channel kinds
|
|
1404
|
+
* into three 4096-entry LUTs); {@link applyAdjustmentLayers} runs the stack on an ImageData.
|
|
1405
|
+
*/
|
|
1406
|
+
type Rgb = [number, number, number];
|
|
1407
|
+
/** Entries in a tone LUT (curves, levels, colour balance). */
|
|
1408
|
+
declare const ADJUSTMENT_LUT_SIZE = 4096;
|
|
1409
|
+
/** Linear interpolation into a 0..1-domain LUT. */
|
|
1410
|
+
declare function sampleLut(table: ArrayLike<number>, v: number): number;
|
|
1411
|
+
interface AdjustmentKindInfo {
|
|
1412
|
+
kind: AdjustmentKind;
|
|
1413
|
+
label: string;
|
|
536
1414
|
}
|
|
537
|
-
|
|
538
|
-
declare function
|
|
539
|
-
|
|
540
|
-
declare
|
|
541
|
-
/**
|
|
542
|
-
declare function
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
1415
|
+
declare const ADJUSTMENT_KINDS: readonly AdjustmentKindInfo[];
|
|
1416
|
+
declare function isAdjustmentKind(value: unknown): value is AdjustmentKind;
|
|
1417
|
+
declare function adjustmentKindLabel(kind: AdjustmentKind): string;
|
|
1418
|
+
declare const HUE_RANGE_LABELS: readonly ["Reds", "Yellows", "Greens", "Cyans", "Blues", "Magentas"];
|
|
1419
|
+
/** The neutral range `i` (0 reds … 5 magentas): fully on for 30° around its centre, fading over 30° each side. */
|
|
1420
|
+
declare function neutralHueRange(i: number): HueRange;
|
|
1421
|
+
declare const identityCurve: () => CurvePoint[];
|
|
1422
|
+
declare const identityLevels: () => LevelsChannel;
|
|
1423
|
+
/** Neutral parameters of every kind (fresh objects on every call). */
|
|
1424
|
+
declare function defaultAdjustmentParams<K extends AdjustmentKind>(kind: K): AdjustmentParamsMap[K];
|
|
1425
|
+
/** A new layer of `kind` with neutral (or the given) parameters, enabled, opacity 1, normal blend. */
|
|
1426
|
+
declare function createAdjustmentLayer<K extends AdjustmentKind>(kind: K, options?: {
|
|
1427
|
+
id?: string;
|
|
1428
|
+
name?: string;
|
|
1429
|
+
params?: Partial<AdjustmentParamsMap[K]>;
|
|
1430
|
+
enabled?: boolean;
|
|
1431
|
+
opacity?: number;
|
|
1432
|
+
blend?: BlendMode;
|
|
1433
|
+
mask?: AdjustmentLayerMask;
|
|
1434
|
+
}): AdjustmentLayerOf<K>;
|
|
550
1435
|
/**
|
|
551
|
-
*
|
|
552
|
-
*
|
|
1436
|
+
* A clean, deep-copied layer from stored or hand-written data: missing fields get neutral
|
|
1437
|
+
* defaults, numbers are clamped to their ranges. `null` for an unknown kind.
|
|
553
1438
|
*/
|
|
554
|
-
declare function
|
|
555
|
-
/**
|
|
556
|
-
declare function
|
|
557
|
-
x: number;
|
|
558
|
-
y: number;
|
|
559
|
-
width: number;
|
|
560
|
-
height: number;
|
|
561
|
-
};
|
|
562
|
-
/** Clamps a crop box to the image bounds. */
|
|
563
|
-
declare function clampCropToImage(crop: CropBox, width: number, height: number): CropBox;
|
|
1439
|
+
declare function normalizeAdjustmentLayer(raw: unknown): AdjustmentLayer | null;
|
|
1440
|
+
/** Normalises a stored layer list (drops unknown kinds, de-duplicates ids). */
|
|
1441
|
+
declare function normalizeAdjustmentLayers(raw: unknown): AdjustmentLayer[];
|
|
564
1442
|
/**
|
|
565
|
-
*
|
|
1443
|
+
* Photoshop curve: a natural cubic spline through the points (0..1 in and out; it may overshoot
|
|
1444
|
+
* between points, as Photoshop's does), constant outside the first / last point, clamped to
|
|
1445
|
+
* 0..1, sampled into a LUT. Fewer than two distinct points: the identity.
|
|
566
1446
|
*/
|
|
567
|
-
declare function
|
|
1447
|
+
declare function curveLut(points: ReadonlyArray<{
|
|
1448
|
+
input: number;
|
|
1449
|
+
output: number;
|
|
1450
|
+
}>, size?: number): Float32Array;
|
|
1451
|
+
/** {@link curveLut} for Curves points in levels (0..255). */
|
|
1452
|
+
declare function curveLutFromLevels(points: readonly CurvePoint[]): Float32Array;
|
|
1453
|
+
/** A Levels record with values in 0..1 (as `levelsValue` takes them). */
|
|
1454
|
+
interface UnitLevels {
|
|
1455
|
+
inBlack: number;
|
|
1456
|
+
inWhite: number;
|
|
1457
|
+
gamma: number;
|
|
1458
|
+
outBlack: number;
|
|
1459
|
+
outWhite: number;
|
|
1460
|
+
}
|
|
568
1461
|
/**
|
|
569
|
-
*
|
|
570
|
-
*
|
|
1462
|
+
* One Levels record on `v` (0..1). With `quantum` (8-bit: 255) Photoshop works on whole levels:
|
|
1463
|
+
* the input is a level and the stretch is rounded (half up) before the gamma. A gamma above 1 has
|
|
1464
|
+
* Photoshop's soft shadow toe: a p-norm soft-min of the power curve and a line of slope ≈ 2^gamma.
|
|
571
1465
|
*/
|
|
572
|
-
declare function
|
|
1466
|
+
declare function levelsValue(ch: UnitLevels, v: number, quantum?: number): number;
|
|
1467
|
+
/** RGB (0..1) → HSL with hue in turns (0..1). */
|
|
1468
|
+
declare function rgbToHsl(c: readonly number[]): [number, number, number];
|
|
1469
|
+
declare function hslToRgb(h: number, s: number, l: number): Rgb;
|
|
1470
|
+
/** How much a pixel of hue `deg` belongs to `range` (0..1): a trapezoid that may wrap past 0/360. */
|
|
1471
|
+
declare function hueRangeWeight(range: Pick<HueRange, 'bounds'>, deg: number): number;
|
|
1472
|
+
/** Range edits as three hue-indexed tables (hue shift in degrees, saturation and lightness as fractions). */
|
|
1473
|
+
declare function hueRangeTables(ranges: readonly HueRange[]): [Float32Array, Float32Array, Float32Array];
|
|
573
1474
|
/**
|
|
574
|
-
*
|
|
575
|
-
*
|
|
1475
|
+
* One Hue/Saturation evaluation: hue shift in degrees, saturation and lightness in -1..1.
|
|
1476
|
+
* Lightness first, then hue and saturation (raising divides by 1 − s, lowering multiplies by
|
|
1477
|
+
* 1 + s). Colorize sets hue and saturation at the lightened lightness.
|
|
576
1478
|
*/
|
|
577
|
-
declare function
|
|
1479
|
+
declare function hueSaturation(c: readonly number[], hue: number, s: number, l: number, colorize: boolean): Rgb;
|
|
1480
|
+
/** A colour range's Lightness: towards the brightest channel when raised, the darkest when lowered. */
|
|
1481
|
+
declare function rangeLightness(c: readonly number[], l: number): Rgb;
|
|
1482
|
+
/** Grey Vibrance › Saturation desaturates to (linear light; blue has no weight). */
|
|
1483
|
+
declare const VIBRANCE_GREY: readonly [number, number];
|
|
1484
|
+
/** The Vibrance slider (`v` in -1..1) on a linear-light pixel: an HSV change that keeps the hue. */
|
|
1485
|
+
declare function vibranceLinear(c: Rgb, v: number): Rgb;
|
|
1486
|
+
/** Photoshop's Vibrance on one encoded sRGB pixel (`v`, `s`: the sliders / 100). */
|
|
1487
|
+
declare function vibrancePixel(c: readonly number[], v: number, s: number): Rgb;
|
|
578
1488
|
/**
|
|
579
|
-
*
|
|
580
|
-
*
|
|
1489
|
+
* Color Balance on channel `ch` (0 red, 1 green, 2 blue) of `v` (0..1); `tones` are the
|
|
1490
|
+
* shadows, midtones and highlights slider triples (-100..100). Highlights, shadows, then midtones.
|
|
581
1491
|
*/
|
|
582
|
-
declare function
|
|
1492
|
+
declare function colorBalanceChannel(tones: readonly [readonly number[], readonly number[], readonly number[]], preserveLuminosity: boolean, ch: number, v: number): number;
|
|
583
1493
|
/**
|
|
584
|
-
*
|
|
585
|
-
*
|
|
1494
|
+
* Black & White grey: the smallest channel, plus the secondary part (middle − smallest) and the
|
|
1495
|
+
* primary part (largest − middle) weighted by the sliders (percent: reds, yellows, greens, cyans,
|
|
1496
|
+
* blues, magentas).
|
|
586
1497
|
*/
|
|
587
|
-
declare function
|
|
1498
|
+
declare function blackWhiteGray(c: readonly number[], weights: readonly number[]): number;
|
|
588
1499
|
/**
|
|
589
|
-
*
|
|
590
|
-
*
|
|
591
|
-
* (what {@link calculateCropDrag} expects); use `getCropCursor(handle, state.transform)`
|
|
592
|
-
* to obtain the matching on-screen cursor.
|
|
1500
|
+
* Photo Filter's linear-light RGB matrix (row-major 3×3): the pixel's D50 XYZ, relative to white,
|
|
1501
|
+
* multiplied by the filter colour's mixed in by `density` (0..1). `normalizeY` keeps luminance Y.
|
|
593
1502
|
*/
|
|
594
|
-
declare function
|
|
1503
|
+
declare function photoFilterMatrix(color: readonly number[], density: number, normalizeY?: boolean): number[][];
|
|
1504
|
+
/** Photoshop posterize: `levels` equal input bins over 0..255, outputs `floor(k·255 / (levels − 1))`. */
|
|
1505
|
+
declare function posterizeValue(v: number, levels: number): number;
|
|
1506
|
+
/** Rec.601 luma (Photoshop's grey for Threshold). */
|
|
1507
|
+
declare const rgbToGray: (c: readonly number[]) => number;
|
|
1508
|
+
/** `#rrggbb` → 0..1 RGB (black for anything else). */
|
|
1509
|
+
declare function hexToRgb(hex: string): Rgb;
|
|
1510
|
+
/** Mutates an encoded sRGB colour (0..1) in place. */
|
|
1511
|
+
type PixelOp = (c: Rgb) => void;
|
|
595
1512
|
/**
|
|
596
|
-
*
|
|
597
|
-
*
|
|
598
|
-
* on-screen orientation under rotation/flip.
|
|
1513
|
+
* Per-channel LUTs of a Curves or Levels layer: each channel's record first, then the master.
|
|
1514
|
+
* `null` for any other kind.
|
|
599
1515
|
*/
|
|
600
|
-
declare function
|
|
1516
|
+
declare function toneLuts(layer: AdjustmentLayer): [Float32Array, Float32Array, Float32Array] | null;
|
|
601
1517
|
/**
|
|
602
|
-
*
|
|
1518
|
+
* Compiles a layer into a pixel function, or `null` when it is the identity (neutral parameters).
|
|
1519
|
+
* Pure: depends on `kind` and `params` only.
|
|
603
1520
|
*/
|
|
604
|
-
declare function
|
|
1521
|
+
declare function compileAdjustmentLayer(layer: AdjustmentLayer): PixelOp | null;
|
|
1522
|
+
/** Layers that change pixels: enabled, visible, not the identity. */
|
|
1523
|
+
declare function activeAdjustmentLayers(layers: readonly AdjustmentLayer[] | undefined): AdjustmentLayer[];
|
|
605
1524
|
/**
|
|
606
|
-
*
|
|
1525
|
+
* Evaluates one colour (encoded sRGB, 0..1) through a layer stack: each layer adjusts the result
|
|
1526
|
+
* of the layers below and is blended over it with its blend mode and opacity (an opaque
|
|
1527
|
+
* backdrop, so `(1 − α)·Cb + α·B(Cb, Cs)`).
|
|
607
1528
|
*/
|
|
608
|
-
declare function
|
|
1529
|
+
declare function evaluateAdjustmentLayers(color: readonly number[], layers: readonly AdjustmentLayer[]): Rgb;
|
|
1530
|
+
/**
|
|
1531
|
+
* Applies an adjustment-layer stack to 8-bit straight RGBA pixels in place. Each pixel is
|
|
1532
|
+
* decoded once, run through every layer in float, and encoded once. Transparent pixels are
|
|
1533
|
+
* left alone; alpha is never changed.
|
|
1534
|
+
*
|
|
1535
|
+
* `masks` (layer id → 0..1 coverage per pixel of `imageData`, see `buildLayerMaskPlanes`)
|
|
1536
|
+
* scales each masked layer's opacity per pixel: coverage 0 leaves the pixel as the layers below
|
|
1537
|
+
* made it, 1 applies the layer fully.
|
|
1538
|
+
*/
|
|
1539
|
+
declare function applyAdjustmentLayers(imageData: Pick<ImageData, 'data'>, layers: readonly AdjustmentLayer[] | undefined, masks?: ReadonlyMap<string, ArrayLike<number>>): void;
|
|
1540
|
+
/** Stable cache key of a layer stack's pixel effect (for renderer caches). */
|
|
1541
|
+
declare function adjustmentLayersKey(layers: readonly AdjustmentLayer[] | undefined): string;
|
|
1542
|
+
|
|
1543
|
+
/**
|
|
1544
|
+
* Control specs: one table describes every numeric adjustment slider (id, label, section, range,
|
|
1545
|
+
* default, step, display precision and track style). The React and Svelte panels render from it,
|
|
1546
|
+
* the agent tools expose it as a schema, and values are addressed by id.
|
|
1547
|
+
*/
|
|
1548
|
+
type ControlSection = 'light' | 'color' | 'effects' | 'layer';
|
|
1549
|
+
/** How a slider track is drawn. */
|
|
1550
|
+
type ControlTrack =
|
|
1551
|
+
/** Plain track, fill from the minimum. */
|
|
1552
|
+
{
|
|
1553
|
+
kind: 'plain';
|
|
1554
|
+
}
|
|
1555
|
+
/** Zero in the middle. */
|
|
1556
|
+
| {
|
|
1557
|
+
kind: 'centered';
|
|
1558
|
+
}
|
|
1559
|
+
/** Blue → yellow (white-balance temperature). */
|
|
1560
|
+
| {
|
|
1561
|
+
kind: 'temp';
|
|
1562
|
+
}
|
|
1563
|
+
/** Green → magenta (tint). */
|
|
1564
|
+
| {
|
|
1565
|
+
kind: 'tint';
|
|
1566
|
+
}
|
|
1567
|
+
/** A two-colour gradient. */
|
|
1568
|
+
| {
|
|
1569
|
+
kind: 'gradient';
|
|
1570
|
+
from: string;
|
|
1571
|
+
to: string;
|
|
1572
|
+
}
|
|
1573
|
+
/** Full hue rainbow. */
|
|
1574
|
+
| {
|
|
1575
|
+
kind: 'rainbow';
|
|
1576
|
+
};
|
|
1577
|
+
interface ControlSpec {
|
|
1578
|
+
/** Dotted path of the value (`exposure`; inside a layer's params: `midtones.0`, `ranges.4.hue`). */
|
|
1579
|
+
id: string;
|
|
1580
|
+
label: string;
|
|
1581
|
+
section: ControlSection;
|
|
1582
|
+
min: number;
|
|
1583
|
+
max: number;
|
|
1584
|
+
step: number;
|
|
1585
|
+
default: number;
|
|
1586
|
+
/** Decimal places shown (after `displayScale`). */
|
|
1587
|
+
decimals: number;
|
|
1588
|
+
track: ControlTrack;
|
|
1589
|
+
/** Multiplier for display (opacity 0..1 shows as 0..100 %). */
|
|
1590
|
+
displayScale?: number;
|
|
1591
|
+
/** Unit suffix for display (`px`, `%`, `°`). */
|
|
1592
|
+
unit?: string;
|
|
1593
|
+
/** The rendering process the control needs (tint: process 2). */
|
|
1594
|
+
requiresProcess?: 1 | 2;
|
|
1595
|
+
}
|
|
1596
|
+
/** Every numeric base adjustment, in panel order. */
|
|
1597
|
+
declare const IMAGE_ADJUSTMENT_CONTROLS: readonly ControlSpec[];
|
|
1598
|
+
/**
|
|
1599
|
+
* Numeric parameters of each adjustment-layer kind, addressed inside `layer.params`. Curves points
|
|
1600
|
+
* and booleans / colours (colorize, preserve luminosity, tint, filter colour) are edited by the
|
|
1601
|
+
* dedicated controls, not sliders.
|
|
1602
|
+
*/
|
|
1603
|
+
declare const ADJUSTMENT_LAYER_CONTROLS: Readonly<Record<AdjustmentKind, readonly ControlSpec[]>>;
|
|
1604
|
+
/** Opacity of any adjustment layer (0..1, shown as %). */
|
|
1605
|
+
declare const ADJUSTMENT_LAYER_OPACITY_CONTROL: ControlSpec;
|
|
1606
|
+
/** The base-adjustment control with this id. */
|
|
1607
|
+
declare function findAdjustmentControl(id: string): ControlSpec | undefined;
|
|
1608
|
+
/** The control of a layer parameter (`opacity` included). */
|
|
1609
|
+
declare function findLayerControl(kind: AdjustmentKind, id: string): ControlSpec | undefined;
|
|
1610
|
+
/** `v` clamped to the control's range and snapped to its step; non-finite values give the default. */
|
|
1611
|
+
declare function clampControlValue(spec: ControlSpec, v: unknown): number;
|
|
1612
|
+
/** A value as the slider shows it (`+12`, `35%`, `4px`). */
|
|
1613
|
+
declare function formatControlValue(spec: ControlSpec, v: number): string;
|
|
1614
|
+
/** Where `v` sits on the track, 0 (left) to 1 (right). */
|
|
1615
|
+
declare function controlPosition(spec: ControlSpec, v: number): number;
|
|
1616
|
+
/** CSS background for a control's track. */
|
|
1617
|
+
declare function controlTrackBackground(spec: ControlSpec): string | undefined;
|
|
1618
|
+
/** Reads a dotted path (`ranges.2.hue`) from an object. */
|
|
1619
|
+
declare function getControlPath(obj: unknown, path: string): unknown;
|
|
1620
|
+
/** A copy of `obj` with the dotted path set (arrays and objects along the path are cloned). */
|
|
1621
|
+
declare function setControlPath<T>(obj: T, path: string, value: unknown): T;
|
|
1622
|
+
/** The base adjustment values the control table describes. */
|
|
1623
|
+
declare function readAdjustmentControls(adjustments: ImageAdjustments): Record<string, number>;
|
|
1624
|
+
|
|
1625
|
+
interface ImageEditorToolProviderOptions {
|
|
1626
|
+
/** Provider id (unique per registry). Default `image-editor`. */
|
|
1627
|
+
id?: string;
|
|
1628
|
+
/** Always prefix tool names with `<namespace>__`. */
|
|
1629
|
+
namespace?: string;
|
|
1630
|
+
}
|
|
1631
|
+
/**
|
|
1632
|
+
* Agent tools for an image editor, for a `ToolRegistry`:
|
|
1633
|
+
*
|
|
1634
|
+
* - `get_adjustments`: base slider values (by control id), process version and adjustment layers.
|
|
1635
|
+
* - `list_controls`: the control table (ids, ranges, defaults, steps), layer kinds and blend modes.
|
|
1636
|
+
* - `set_adjustments {values, label}`: sets base controls (`exposure`) and layer parameters
|
|
1637
|
+
* (`layers.<id>.vibrance`, `layers.<id>.opacity`) in one undo step; values are clamped to the
|
|
1638
|
+
* control ranges and the applied values are echoed.
|
|
1639
|
+
* - `add_adjustment_layer {kind, params?, opacity?, blend?, name?}`.
|
|
1640
|
+
* - `render_preview {maxSide}`: the rendered image as a PNG, longest side at most `maxSide`.
|
|
1641
|
+
* - Selections and masks: `get_selection`, `select_region`, `select_by_color`, `modify_selection`,
|
|
1642
|
+
* `refine_selection`, `apply_selection_as_mask` (see `createImageSelectionTools`).
|
|
1643
|
+
*/
|
|
1644
|
+
declare function createImageEditorToolProvider(controller: ImageEditorController, options?: ImageEditorToolProviderOptions): AgentToolProvider;
|
|
1645
|
+
|
|
1646
|
+
/** Box coordinates of a curve point. */
|
|
1647
|
+
declare function curvePointToBox(p: CurvePoint, width: number, height: number): {
|
|
609
1648
|
x: number;
|
|
610
1649
|
y: number;
|
|
611
|
-
width: number;
|
|
612
|
-
height: number;
|
|
613
1650
|
};
|
|
1651
|
+
/** The curve point (whole levels, clamped) under box coordinates. */
|
|
1652
|
+
declare function boxToCurvePoint(x: number, y: number, width: number, height: number): CurvePoint;
|
|
1653
|
+
/** An SVG polyline path of the evaluated curve (spline, clamped, constant beyond the end points). */
|
|
1654
|
+
declare function curveSvgPath(points: readonly CurvePoint[], width: number, height: number, samples?: number): string;
|
|
1655
|
+
/** Index of the point within `radius` box units of (x, y), nearest first; -1 for none. */
|
|
1656
|
+
declare function hitTestCurvePoint(points: readonly CurvePoint[], x: number, y: number, width: number, height: number, radius?: number): number;
|
|
1657
|
+
/** Inserts a point in input order (replacing one at the same input). Returns the new list and its index. */
|
|
1658
|
+
declare function insertCurvePoint(points: readonly CurvePoint[], p: CurvePoint): {
|
|
1659
|
+
points: CurvePoint[];
|
|
1660
|
+
index: number;
|
|
1661
|
+
};
|
|
1662
|
+
/** Moves point `index`, keeping its input strictly between its neighbours'. */
|
|
1663
|
+
declare function moveCurvePoint(points: readonly CurvePoint[], index: number, p: CurvePoint): CurvePoint[];
|
|
1664
|
+
/** Removes point `index`; a curve keeps at least two points. */
|
|
1665
|
+
declare function removeCurvePoint(points: readonly CurvePoint[], index: number): CurvePoint[];
|
|
1666
|
+
|
|
614
1667
|
/**
|
|
615
|
-
*
|
|
1668
|
+
* The selection's outline at `threshold` (0..255, default 128) as axis-aligned segments on pixel
|
|
1669
|
+
* boundaries, `[x0, y0, x1, y1, …]` in natural image pixels, with collinear neighbours merged.
|
|
1670
|
+
* This is what marching ants are drawn from. Linear in the pixel count.
|
|
616
1671
|
*/
|
|
617
|
-
declare function
|
|
1672
|
+
declare function selectionOutline(mask: SelectionMask, threshold?: number): Float32Array;
|
|
1673
|
+
interface QuickMaskStyle {
|
|
1674
|
+
/** Overlay colour, `[r, g, b]` 0..255 (default Photoshop's rubylith red). */
|
|
1675
|
+
color?: readonly [number, number, number];
|
|
1676
|
+
/** 0..1 (default 0.5): opacity over fully unselected pixels. */
|
|
1677
|
+
opacity?: number;
|
|
1678
|
+
}
|
|
1679
|
+
/**
|
|
1680
|
+
* Quick Mask view: RGBA pixels (natural image size) tinting the *unselected* area, so the
|
|
1681
|
+
* selection shows through clear, as Photoshop's rubylith overlay.
|
|
1682
|
+
*/
|
|
1683
|
+
declare function quickMaskPixels(mask: SelectionMask, style?: QuickMaskStyle): Uint8ClampedArray;
|
|
1684
|
+
|
|
1685
|
+
/** Selection tools of the image editor UI. */
|
|
1686
|
+
type SelectionToolKind = 'wand' | 'rect' | 'ellipse' | 'lasso';
|
|
1687
|
+
declare const SELECTION_TOOLS: readonly {
|
|
1688
|
+
id: SelectionToolKind;
|
|
1689
|
+
label: string;
|
|
1690
|
+
}[];
|
|
1691
|
+
declare const SELECTION_MODE_LABELS: Record<SelectionMode, string>;
|
|
1692
|
+
/** The options bar of the selection tools (shared by the React and Svelte UIs). */
|
|
1693
|
+
interface SelectionToolOptions {
|
|
1694
|
+
tool: SelectionToolKind;
|
|
1695
|
+
mode: SelectionMode;
|
|
1696
|
+
/** Magic wand tolerance, 0..255. */
|
|
1697
|
+
tolerance: number;
|
|
1698
|
+
contiguous: boolean;
|
|
1699
|
+
antiAlias: boolean;
|
|
1700
|
+
/** Sample the adjusted image instead of the source. */
|
|
1701
|
+
sampleMerged: boolean;
|
|
1702
|
+
distance: ColorDistance;
|
|
1703
|
+
}
|
|
1704
|
+
declare const DEFAULT_SELECTION_TOOL_OPTIONS: SelectionToolOptions;
|
|
1705
|
+
/**
|
|
1706
|
+
* Photoshop's modifier keys: Shift adds, Alt/Option subtracts, both intersect; otherwise the
|
|
1707
|
+
* options bar mode.
|
|
1708
|
+
*/
|
|
1709
|
+
declare function selectionModeFromModifiers(modifiers: {
|
|
1710
|
+
shiftKey?: boolean;
|
|
1711
|
+
altKey?: boolean;
|
|
1712
|
+
}, fallback: SelectionMode): SelectionMode;
|
|
1713
|
+
interface RefineEdgeControl {
|
|
1714
|
+
id: keyof Omit<RefineEdgeParams, 'smartRadius'>;
|
|
1715
|
+
label: string;
|
|
1716
|
+
min: number;
|
|
1717
|
+
max: number;
|
|
1718
|
+
step: number;
|
|
1719
|
+
unit: string;
|
|
1720
|
+
}
|
|
1721
|
+
/** Sliders of the Refine Edge panel. */
|
|
1722
|
+
declare const REFINE_EDGE_CONTROLS: readonly RefineEdgeControl[];
|
|
1723
|
+
/** A one-line status: "No selection" or "W × H px selected (n % of the image)". */
|
|
1724
|
+
declare function describeSelection(mask: SelectionMask | null | undefined): string;
|
|
1725
|
+
|
|
1726
|
+
interface GestureModifiers {
|
|
1727
|
+
shiftKey?: boolean;
|
|
1728
|
+
altKey?: boolean;
|
|
1729
|
+
}
|
|
1730
|
+
/**
|
|
1731
|
+
* Pointer gestures of the selection tools, shared by the React and Svelte image editors: feed
|
|
1732
|
+
* it pointer positions in natural image pixels (`canvasToImagePoint(..., false)`).
|
|
1733
|
+
*
|
|
1734
|
+
* - Magic wand: selects on `begin` (async, as it may read pixels).
|
|
1735
|
+
* - Rectangle / ellipse: drag a box; a click without a drag deselects (replace mode).
|
|
1736
|
+
* - Lasso: drag a free-hand path, closed on `end`.
|
|
1737
|
+
*
|
|
1738
|
+
* Shift adds, Alt subtracts, both intersect (overriding the options bar mode). While dragging,
|
|
1739
|
+
* {@link draftPath} is the outline to show (`RenderOptions.draftSelectionPath`).
|
|
1740
|
+
*/
|
|
1741
|
+
declare class SelectionGesture {
|
|
1742
|
+
readonly controller: ImageEditorController;
|
|
1743
|
+
private readonly getOptions;
|
|
1744
|
+
private start;
|
|
1745
|
+
private points;
|
|
1746
|
+
private current;
|
|
1747
|
+
private modifiers;
|
|
1748
|
+
/** The last error (e.g. pixels unavailable for the wand), for the UI to show. */
|
|
1749
|
+
error: string | null;
|
|
1750
|
+
constructor(controller: ImageEditorController, getOptions: () => SelectionToolOptions);
|
|
1751
|
+
get active(): boolean;
|
|
1752
|
+
/** The outline of the shape being drawn, or `null`. */
|
|
1753
|
+
get draftPath(): ImagePoint[] | null;
|
|
1754
|
+
/** Pointer down. Resolves once a wand click has been applied. */
|
|
1755
|
+
begin(point: ImagePoint, modifiers?: GestureModifiers): Promise<void>;
|
|
1756
|
+
/** Pointer move; returns true when the draft changed (re-render). */
|
|
1757
|
+
move(point: ImagePoint): boolean;
|
|
1758
|
+
/** Pointer up: commits the shape. Returns true when the selection changed. */
|
|
1759
|
+
end(point?: ImagePoint, modifiers?: GestureModifiers): boolean;
|
|
1760
|
+
/** Abandons a drag without changing the selection. */
|
|
1761
|
+
cancel(): void;
|
|
1762
|
+
}
|
|
1763
|
+
|
|
1764
|
+
/**
|
|
1765
|
+
* Agent tools for selections and masks (part of `createImageEditorToolProvider`):
|
|
1766
|
+
* `get_selection`, `select_region`, `select_by_color`, `modify_selection`, `refine_selection`
|
|
1767
|
+
* and `apply_selection_as_mask`. Coordinates are natural pixels of the source image.
|
|
1768
|
+
*/
|
|
1769
|
+
declare function createImageSelectionTools(controller: ImageEditorController): AgentTool[];
|
|
618
1770
|
|
|
619
|
-
export { AS_SHOT_KELVIN, type Annotation, type AnnotationType, type ArrowAnnotation, type AspectRatio, type BaseAnnotation, type Chromaticity, type CircleAnnotation, type CreateAnnotationPayload, type CropBox, type CropHandle, D65, DEFAULT_ADJUSTMENTS, DEFAULT_DEPTH_MASK, DEFAULT_TRANSFORM, type DepthMaskOptions, type ExportOptions, IDENTITY_MATRIX3, type ImageAdjustments, type ImageAnnotation, type ImageDimensions, type ImageEditorAIHooks, ImageEditorController, type ImageEditorOptions, ImageEditorRenderer, type ImageEditorState, type ImageEditorTool, type ImagePoint, type ImageProcessVersion, type ImageProjection, type ImageTransform, type InpaintHook, type InpaintOptions, LATEST_PROCESS_VERSION, LEGACY_PROCESS_VERSION, LUMA_709, type LineAnnotation, MAX_KELVIN, MIN_KELVIN, MIRED_PER_TEMPERATURE_UNIT, type Matrix3, type PenAnnotation, type RectAnnotation, type RemoveBackgroundHook, type RemoveBackgroundOptions, type RenderOptions, type SerializedImageEditorState, TINT_SCALE, TONE_LUT_SIZE, type TextAnnotation, type ViewportMetrics, applyAdjustments, applyDepthMask, applyImageProjectionToContext, applyLegacyAdjustments, applyMatrix3, applyProcess2Adjustments, bradfordAdaptation, buildToneLut, calculateCropDrag, canvasToImagePoint, clampCropToImage, getAnnotationBounds, getCropCursor, getRotatedSize, getViewportMetrics, getViewportProjection, globalImageCache, hitTestAnnotation, hitTestCrop, imageToCanvasPoint, invertMatrix3, isQuarterTurnSwapped, kelvinToTemperature, linearSrgbToXy, linearToSrgb, mapCropHandle, mulMatrix3, normalizeAngle, normalizeProcessVersion, normalizeStoredAdjustments, projectImagePoint, projectImageRect, removeAlpha, sampleToneLut, srgbToLinear, tempTintToXy, temperatureToKelvin, toneCurve, unprojectCanvasPoint, uvToXy, wbMatrix, whiteBalanceFromSample, whiteBalanceMatrix, xyToTempTint, xyToUv };
|
|
1771
|
+
export { ADJUSTMENT_KINDS, ADJUSTMENT_LAYER_CONTROLS, ADJUSTMENT_LAYER_OPACITY_CONTROL, ADJUSTMENT_LUT_SIZE, AS_SHOT_KELVIN, type AdjustmentKind, type AdjustmentKindInfo, type AdjustmentLayer, type AdjustmentLayerBase, type AdjustmentLayerInit, type AdjustmentLayerMask, type AdjustmentLayerOf, type AdjustmentLayerUpdate, type AdjustmentParamsMap, type Annotation, type AnnotationType, type ArrowAnnotation, type AspectRatio, BLEND_MODES, type BaseAnnotation, type BlackWhiteParams, type BlendMode, type BlendModeInfo, type Chromaticity, type CircleAnnotation, type ColorBalanceParams, type ColorBalanceTone, type ColorDistance, type ColorRangeOptions, type ColorRangeSample, type ControlSection, type ControlSpec, type ControlTrack, type CreateAnnotationPayload, type CropBox, type CropHandle, type CurvePoint, type CurvesParams, D65, DEFAULT_ADJUSTMENTS, DEFAULT_DEPTH_MASK, DEFAULT_REFINE_EDGE_PARAMS, DEFAULT_SELECTION_TOOL_OPTIONS, DEFAULT_TRANSFORM, DIRECT_GAUSSIAN_MAX_SIGMA, type DepthMaskOptions, EMPTY_DISTANCE, type ExportOptions, GUIDED_FILTER_EPS, type GestureModifiers, HISTOGRAM_BINS, HUE_RANGE_LABELS, type HistogramChannel, type HueRange, type HueSaturationParams, IDENTITY_MATRIX3, IMAGE_ADJUSTMENT_CONTROLS, IMAGE_EDITOR_SCHEMA_VERSION, IMAGE_EDITOR_STATE_VERSION, type ImageAdjustments, type ImageAnnotation, type ImageDimensions, type ImageEditorAIHooks, ImageEditorController, type ImageEditorDocumentLoad, type ImageEditorOptions, ImageEditorRenderer, type ImageEditorState, type ImageEditorTool, type ImageEditorToolProviderOptions, type ImageHistogram, type ImagePoint, type ImageProcessVersion, type ImageProjection, type ImageTransform, type InpaintHook, type InpaintOptions, type InvertParams, LATEST_PROCESS_VERSION, LEGACY_PROCESS_VERSION, LUMA_709, type LayerMaskProps, type LevelsChannel, type LevelsParams, type LineAnnotation, MAX_KELVIN, MIN_KELVIN, MIRED_PER_TEMPERATURE_UNIT, type MagicWandOptions, type Matrix3, type PenAnnotation, type PhotoFilterParams, type PixelBuffer, type PixelOp, type PosterizeParams, type QuickMaskStyle, REFINE_EDGE_CONTROLS, type RectAnnotation, type RefineEdgeControl, type RefineEdgeParams, type RemoveBackgroundHook, type RemoveBackgroundOptions, type RenderOptions, type Rgb$1 as Rgb, type Rgba, SELECTION_MODES, SELECTION_MODE_LABELS, SELECTION_MODIFY_OPS, SELECTION_TOOLS, type SampleOptions, type SelectionChannel, type SelectionCommandOptions, SelectionGesture, type SelectionMask, type SelectionMode, type SelectionModifyOp, type SelectionToolKind, type SelectionToolOptions, type SerializedImageEditorState, type SerializedSelection, type ShapeSelectionOptions, TINT_SCALE, TONE_LUT_SIZE, TONE_RANGE_PRESETS, type TextAnnotation, type ThresholdParams, type ToneRangePreset, type UnitLevels, VIBRANCE_GREY, type VibranceParams, type ViewportMetrics, activeAdjustmentLayers, adjustmentKindLabel, adjustmentLayersKey, applyAdjustmentLayers, applyAdjustments, applyDepthMask, applyImageProjectionToContext, applyLegacyAdjustments, applyMatrix3, applyProcess2Adjustments, blackWhiteGray, blendChannel, blendImageData, blendLum, blendPixel, blendRgb, borderCoverage, boxMean, boxToCurvePoint, bradfordAdaptation, buildLayerMaskPlanes, buildToneLut, calculateCropDrag, canvasCompositeOperation, canvasToImagePoint, clampControlValue, clampCropToImage, colorBalanceChannel, colorRange, combineSelections, compileAdjustmentLayer, computeHistogram, computeSelectionBounds, contractCoverage, controlPosition, controlTrackBackground, coverageToByte, createAdjustmentLayer, createImageEditorToolProvider, createImageSelectionTools, createSelectionMask, curveLut, curveLutFromLevels, curvePointToBox, curveSvgPath, decodeLayerMask, decodeSelectionRle, defaultAdjustmentParams, describeSelection, deserializeSelection, distanceTransform, edgeWidth, ellipsePoints, ellipseSelection, encodeSelectionRle, evaluateAdjustmentLayers, expandCoverage, featherCoverage, findAdjustmentControl, findLayerControl, formatControlValue, fullSelection, gaussianBlur, getAnnotationBounds, getControlPath, getCropCursor, getRotatedSize, getViewportMetrics, getViewportProjection, globalImageCache, greyMorphology, guidePlanes, guidedFilterColor, hashMaskContent, hexToRgb, histogramPath, hitTestAnnotation, hitTestCrop, hitTestCurvePoint, hslToRgb, hueRange, hueRangeTables, hueRangeWeight, hueSaturation, identityCurve, identityLevels, imageEditorStateMigrations, imageToCanvasPoint, insertCurvePoint, invertMatrix3, invertSelection, isAdjustmentKind, isBlendMode, isQuarterTurnSwapped, isSelectionEmpty, isSelectionMode, isSeparableBlendMode, kelvinToTemperature, layerMaskCoverage, layerMaskFromSelection, layerMaskKey, levelsValue, linearSrgbToXy, linearToSrgb, loadImageEditorDocument, magicWand, mapCropHandle, migrateSerializedImageEditorState, modifySelection, moveCurvePoint, mulMatrix3, neutralHueRange, normalizeAdjustmentLayer, normalizeAdjustmentLayers, normalizeAngle, normalizeBlendMode, normalizeLayerMask, normalizeProcessVersion, normalizeRect, normalizeRefineEdgeParams, normalizeStoredAdjustments, parseSelectionMode, photoFilterMatrix, polygonCoverage, polygonSelection, posterizeValue, projectImagePoint, projectImageRect, projectMaskCoverage, quickMaskPixels, rangeLightness, readAdjustmentControls, rectSelection, refineCoverage, refineEdgeHalo, refineSelection, removeAlpha, removeCurvePoint, resizeSelection, rgbToGray, rgbToHsl, sampleLut, sampleToneLut, selectionArea, selectionFromCoverage, selectionFromPixels, selectionModeFromModifiers, selectionOutline, selectionToCoverage, selectionToPixels, selectionValueAt, serializeSelection, setControlPath, setLum, shiftCoverage, smoothCoverage, srgb8ToLab, srgbToLinear, tempTintToXy, temperatureToKelvin, toneCurve, toneLuts, toneRange, unprojectCanvasPoint, updateLayerMaskProps, uvToXy, vibranceLinear, vibrancePixel, wbMatrix, whiteBalanceFromSample, whiteBalanceMatrix, xyToTempTint, xyToUv };
|