@dilemmagx/orchestra 1.2.1 → 1.2.2
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 +145 -60
- package/dist/core/image.d.ts +4 -0
- package/dist/core/nodes.d.ts +209 -19
- package/dist/core/pipeline.d.ts +15 -2
- package/dist/core/sources.d.ts +55 -0
- package/dist/index.d.ts +6 -5
- package/dist/index.js +16 -2
- package/dist/index.js.map +3 -3
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# @dilemmagx/orchestra
|
|
2
2
|
|
|
3
3
|
Orchestra is a programmable, node-based image synthesis and processing toolkit.
|
|
4
|
-
|
|
4
|
+
The engine is centered around a flexible node state, so every built-in node is created through
|
|
5
|
+
the same custom node API that you use in your own projects.
|
|
5
6
|
|
|
6
7
|
## Install
|
|
7
8
|
|
|
@@ -15,29 +16,150 @@ npm i @dilemmagx/orchestra
|
|
|
15
16
|
import { Pipeline, createNoiseNode, createInvertNode, sourceFromEmpty } from '@dilemmagx/orchestra';
|
|
16
17
|
|
|
17
18
|
const pipeline = new Pipeline().add(createNoiseNode({ grayscale: true })).add(createInvertNode());
|
|
18
|
-
|
|
19
19
|
const image = await pipeline.run(sourceFromEmpty(256, 256, 'rgba8'), { seed: 42 });
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
##
|
|
22
|
+
## Core Concepts
|
|
23
|
+
|
|
24
|
+
- A pipeline runs nodes sequentially.
|
|
25
|
+
- Each node receives a shared context and a mutable state object.
|
|
26
|
+
- The default image key is "image", but nodes may read and write additional image keys.
|
|
27
|
+
|
|
28
|
+
## Simplified Node API
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
import { node, pipeline, sourceFromEmpty } from '@dilemmagx/orchestra';
|
|
32
|
+
|
|
33
|
+
const gradient = node({
|
|
34
|
+
name: 'gradient',
|
|
35
|
+
params: { from: '#22d3ee', to: '#0f172a' },
|
|
36
|
+
run: (pixels, { params }) => {
|
|
37
|
+
const height = pixels.length;
|
|
38
|
+
const width = pixels[0]?.length ?? 0;
|
|
39
|
+
return pixels.map((row, y) =>
|
|
40
|
+
row.map((_pixel, x) => {
|
|
41
|
+
const t = x / Math.max(1, width - 1);
|
|
42
|
+
return {
|
|
43
|
+
r: Math.round(34 + (15 - 34) * t),
|
|
44
|
+
g: Math.round(211 + (23 - 211) * t),
|
|
45
|
+
b: Math.round(238 + (42 - 238) * t),
|
|
46
|
+
a: 255,
|
|
47
|
+
};
|
|
48
|
+
})
|
|
49
|
+
);
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
const image = await pipeline(gradient).run(sourceFromEmpty(512, 256, 'rgba8'));
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Nodes created with `node()` receive a 2D pixel matrix by default. Node names are optional;
|
|
57
|
+
if omitted, Orchestra assigns incremental names like `node-1` to improve traceability.
|
|
58
|
+
|
|
59
|
+
## Noise Suite
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
import {
|
|
63
|
+
pipeline,
|
|
64
|
+
sourceFromEmpty,
|
|
65
|
+
createValueNoiseNode,
|
|
66
|
+
createVoronoiNoiseNode,
|
|
67
|
+
createFractalNoiseNode,
|
|
68
|
+
} from '@dilemmagx/orchestra';
|
|
69
|
+
|
|
70
|
+
const image = await pipeline(
|
|
71
|
+
createValueNoiseNode({ scale: 32, octaves: 2, min: 20, max: 220 }),
|
|
72
|
+
createVoronoiNoiseNode({ scale: 28, jitter: 0.8, mode: 'edge' }),
|
|
73
|
+
createFractalNoiseNode({ scale: 40, octaves: 4, persistence: 0.55 })
|
|
74
|
+
).run(sourceFromEmpty(512, 512, 'rgba8'), { seed: 42 });
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
import {
|
|
79
|
+
pipeline,
|
|
80
|
+
sourceFromEmpty,
|
|
81
|
+
createPerlinNoiseNode,
|
|
82
|
+
createTurbulenceNoiseNode,
|
|
83
|
+
createRidgedNoiseNode,
|
|
84
|
+
} from '@dilemmagx/orchestra';
|
|
85
|
+
|
|
86
|
+
const image = await pipeline(
|
|
87
|
+
createPerlinNoiseNode({ scale: 48, octaves: 3 }),
|
|
88
|
+
createTurbulenceNoiseNode({ scale: 36, octaves: 4, persistence: 0.6 }),
|
|
89
|
+
createRidgedNoiseNode({ scale: 40, octaves: 5, persistence: 0.55 })
|
|
90
|
+
).run(sourceFromEmpty(512, 512, 'rgba8'), { seed: 'detail' });
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Text Tool
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
import { createTextNode, pipeline, sourceFromEmpty } from '@dilemmagx/orchestra';
|
|
97
|
+
|
|
98
|
+
const text = createTextNode({
|
|
99
|
+
text: 'HELLO ORCHESTRA',
|
|
100
|
+
font: {
|
|
101
|
+
family: 'Inter',
|
|
102
|
+
source: { filePath: './fonts/Inter-SemiBold.ttf' },
|
|
103
|
+
weight: 600,
|
|
104
|
+
},
|
|
105
|
+
layout: { x: 64, y: 64, maxWidth: 640, align: 'left' },
|
|
106
|
+
style: { fontSize: 48, bold: true, underline: true },
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
const image = await pipeline(text).run(sourceFromEmpty(800, 450, 'rgba8'));
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Provide a font file to keep output identical across machines. If a font source is not supplied,
|
|
113
|
+
the system font family is used when available.
|
|
114
|
+
|
|
115
|
+
## Custom Node
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
import { Pipeline, createImageNode, sourceFromEmpty } from '@dilemmagx/orchestra';
|
|
119
|
+
|
|
120
|
+
const posterize = createImageNode(
|
|
121
|
+
'posterize',
|
|
122
|
+
{ step: 32 },
|
|
123
|
+
(_context, image, params) =>
|
|
124
|
+
image.mapPixels((pixel) => {
|
|
125
|
+
const next = Math.round(pixel.r / params.step) * params.step;
|
|
126
|
+
return { r: next, g: next, b: next, a: pixel.a };
|
|
127
|
+
})
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
const pipeline = new Pipeline().add(posterize);
|
|
131
|
+
const image = await pipeline.run(sourceFromEmpty(512, 512, 'rgba8'));
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Advanced Node State
|
|
23
135
|
|
|
24
136
|
```ts
|
|
25
137
|
import {
|
|
26
138
|
Pipeline,
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
139
|
+
defineNode,
|
|
140
|
+
getImage,
|
|
141
|
+
sourceFromEmpty,
|
|
142
|
+
DEFAULT_IMAGE_KEY,
|
|
31
143
|
} from '@dilemmagx/orchestra';
|
|
32
144
|
|
|
33
|
-
const
|
|
34
|
-
|
|
145
|
+
const stashStats = defineNode({
|
|
146
|
+
name: 'stash-stats',
|
|
147
|
+
run: (_context, state) => {
|
|
148
|
+
const image = getImage(state, DEFAULT_IMAGE_KEY);
|
|
149
|
+
return {
|
|
150
|
+
data: {
|
|
151
|
+
pixelCount: image.width * image.height,
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
},
|
|
155
|
+
});
|
|
35
156
|
|
|
36
|
-
const
|
|
37
|
-
await
|
|
157
|
+
const pipeline = new Pipeline().add(stashStats);
|
|
158
|
+
const state = await pipeline.runState(sourceFromEmpty(256, 256, 'rgba8'));
|
|
159
|
+
console.log(state.data.pixelCount);
|
|
38
160
|
```
|
|
39
161
|
|
|
40
|
-
##
|
|
162
|
+
## Mask Mapping
|
|
41
163
|
|
|
42
164
|
```ts
|
|
43
165
|
import {
|
|
@@ -46,13 +168,14 @@ import {
|
|
|
46
168
|
createGaussianBlurNode,
|
|
47
169
|
createMapNode,
|
|
48
170
|
sourceFromUrl,
|
|
171
|
+
toRgba,
|
|
49
172
|
} from '@dilemmagx/orchestra';
|
|
50
173
|
|
|
51
174
|
const mask = createMapNode('mask', (_pixel, x, y) => {
|
|
52
175
|
const dx = x - 128;
|
|
53
176
|
const dy = y - 128;
|
|
54
177
|
const inside = dx * dx + dy * dy <= 96 * 96;
|
|
55
|
-
return inside ? '#ffffff' : '#000000';
|
|
178
|
+
return inside ? toRgba('#ffffff') : toRgba('#000000');
|
|
56
179
|
});
|
|
57
180
|
|
|
58
181
|
const mapped = createMaskMapNode(mask, [
|
|
@@ -63,35 +186,7 @@ const pipeline = new Pipeline().add(mapped);
|
|
|
63
186
|
const image = await pipeline.run(sourceFromUrl('https://example.com/image.jpg'));
|
|
64
187
|
```
|
|
65
188
|
|
|
66
|
-
|
|
67
|
-
color to a source image or node output, with optional tolerance.
|
|
68
|
-
|
|
69
|
-
You can also use a dedicated crop node:
|
|
70
|
-
|
|
71
|
-
```ts
|
|
72
|
-
import { createSelectionCropNode } from '@dilemmagx/orchestra';
|
|
73
|
-
|
|
74
|
-
const crop = createSelectionCropNode(selector, { outsideColor: '#00000000' });
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
## Color Formats
|
|
78
|
-
|
|
79
|
-
```ts
|
|
80
|
-
import { toRgba, hsvaToRgba } from '@dilemmagx/orchestra';
|
|
81
|
-
|
|
82
|
-
const rgba = toRgba('#ffcc00');
|
|
83
|
-
const other = hsvaToRgba({ h: 120, s: 50, v: 90, a: 1 });
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
## Common Nodes
|
|
87
|
-
|
|
88
|
-
```ts
|
|
89
|
-
import { Pipeline, createGrayscaleNode, createGammaNode } from '@dilemmagx/orchestra';
|
|
90
|
-
|
|
91
|
-
const pipeline = new Pipeline().add(createGrayscaleNode()).add(createGammaNode(1.2));
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
Built-in nodes:
|
|
189
|
+
## Built-in Nodes
|
|
95
190
|
|
|
96
191
|
- createBrightnessNode
|
|
97
192
|
- createCheckerboardNode
|
|
@@ -106,6 +201,12 @@ Built-in nodes:
|
|
|
106
201
|
- createGrayscaleNode
|
|
107
202
|
- createInvertNode
|
|
108
203
|
- createNoiseNode
|
|
204
|
+
- createFractalNoiseNode
|
|
205
|
+
- createPerlinNoiseNode
|
|
206
|
+
- createRidgedNoiseNode
|
|
207
|
+
- createTurbulenceNoiseNode
|
|
208
|
+
- createValueNoiseNode
|
|
209
|
+
- createVoronoiNoiseNode
|
|
109
210
|
- createPaletteMapNode
|
|
110
211
|
- createRandomFillNode
|
|
111
212
|
- createRectNode
|
|
@@ -113,8 +214,9 @@ Built-in nodes:
|
|
|
113
214
|
- createSaltPepperNoiseNode
|
|
114
215
|
- createSharpenNode
|
|
115
216
|
- createThresholdNode
|
|
217
|
+
- createTextNode
|
|
116
218
|
|
|
117
|
-
Selectors and masking:
|
|
219
|
+
Selectors and masking helpers:
|
|
118
220
|
|
|
119
221
|
- createAlphaSelector
|
|
120
222
|
- createCircleSelector
|
|
@@ -124,23 +226,6 @@ Selectors and masking:
|
|
|
124
226
|
- createRectSelector
|
|
125
227
|
- createSelectionCropNode
|
|
126
228
|
|
|
127
|
-
## Custom Node
|
|
128
|
-
|
|
129
|
-
```ts
|
|
130
|
-
import { Pipeline, createParamNode, sourceFromEmpty } from '@dilemmagx/orchestra';
|
|
131
|
-
|
|
132
|
-
const posterize = createParamNode('posterize', { step: 32 }, (_context, image, params) =>
|
|
133
|
-
image.mapPixels((pixel) => {
|
|
134
|
-
const next = Math.round(pixel.r / params.step) * params.step;
|
|
135
|
-
return { r: next, g: next, b: next, a: pixel.a };
|
|
136
|
-
})
|
|
137
|
-
);
|
|
138
|
-
|
|
139
|
-
const pipeline = new Pipeline().add(posterize);
|
|
140
|
-
const image = await pipeline.run(sourceFromEmpty(512, 512, 'rgba8'));
|
|
141
|
-
```
|
|
142
|
-
|
|
143
229
|
## License
|
|
144
230
|
|
|
145
231
|
GPL-3.0
|
|
146
|
-
|
package/dist/core/image.d.ts
CHANGED
|
@@ -17,6 +17,10 @@ export declare class ImageBuffer {
|
|
|
17
17
|
* Creates a new ImageBuffer and optionally fills it with a color.
|
|
18
18
|
*/
|
|
19
19
|
static create(width: number, height: number, format: PixelFormat, fill?: PixelLike): ImageBuffer;
|
|
20
|
+
/**
|
|
21
|
+
* Creates an ImageBuffer from a 2D pixel matrix.
|
|
22
|
+
*/
|
|
23
|
+
static fromMatrix(matrix: Pixel[][], format?: PixelFormat): ImageBuffer;
|
|
20
24
|
/**
|
|
21
25
|
* Clones the buffer and its pixel data.
|
|
22
26
|
*/
|
package/dist/core/nodes.d.ts
CHANGED
|
@@ -2,21 +2,120 @@ import { ImageBuffer } from './image';
|
|
|
2
2
|
import { ColorInput } from './color';
|
|
3
3
|
import { ImageSource, Pixel, PixelLike } from './types';
|
|
4
4
|
import { SeededRandom } from './random';
|
|
5
|
-
import { ResizeOptions } from './sources';
|
|
5
|
+
import { ResizeOptions, type TextOptions } from './sources';
|
|
6
|
+
export declare const DEFAULT_IMAGE_KEY = "image";
|
|
6
7
|
/**
|
|
7
8
|
* Runtime context shared across nodes in a pipeline run.
|
|
8
9
|
*/
|
|
9
10
|
export type NodeContext = {
|
|
10
11
|
random: SeededRandom;
|
|
12
|
+
stash: Map<string, unknown>;
|
|
11
13
|
};
|
|
14
|
+
/**
|
|
15
|
+
* State passed between nodes in a pipeline run.
|
|
16
|
+
*/
|
|
17
|
+
export type NodeState = {
|
|
18
|
+
images: Record<string, ImageBuffer>;
|
|
19
|
+
data: Record<string, unknown>;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Result returned by a node execution.
|
|
23
|
+
*/
|
|
24
|
+
export type NodeResult = {
|
|
25
|
+
images?: Record<string, ImageBuffer>;
|
|
26
|
+
data?: Record<string, unknown>;
|
|
27
|
+
};
|
|
28
|
+
type NodeRunner<TParams> = {
|
|
29
|
+
bivarianceHack(context: NodeContext, state: NodeState, params: TParams): Promise<NodeResult> | NodeResult;
|
|
30
|
+
}['bivarianceHack'];
|
|
12
31
|
/**
|
|
13
32
|
* Pipeline node definition.
|
|
14
33
|
*/
|
|
15
|
-
export type
|
|
34
|
+
export type NodeDefinition<TParams = unknown> = {
|
|
16
35
|
name: string;
|
|
17
|
-
params?:
|
|
18
|
-
|
|
36
|
+
params?: TParams;
|
|
37
|
+
inputs?: string[];
|
|
38
|
+
outputs?: string[];
|
|
39
|
+
run: NodeRunner<TParams>;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Alias for image-focused nodes.
|
|
43
|
+
*/
|
|
44
|
+
export type ImageNode<TParams = unknown> = NodeDefinition<TParams>;
|
|
45
|
+
/**
|
|
46
|
+
* Image node with typed parameters metadata.
|
|
47
|
+
*/
|
|
48
|
+
export type ParametricNode<TParams> = ImageNode<TParams> & {
|
|
49
|
+
params: TParams;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Definition for a reusable node.
|
|
53
|
+
*/
|
|
54
|
+
export declare function defineNode<TParams>(definition: NodeDefinition<TParams>): NodeDefinition<TParams>;
|
|
55
|
+
/**
|
|
56
|
+
* Image node input definition.
|
|
57
|
+
*/
|
|
58
|
+
export type ImageNodeOptions = {
|
|
59
|
+
input?: string;
|
|
60
|
+
output?: string;
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* 2D pixel matrix representation.
|
|
64
|
+
*/
|
|
65
|
+
export type PixelMatrix = Pixel[][];
|
|
66
|
+
/**
|
|
67
|
+
* Context provided to pixel-based node handlers.
|
|
68
|
+
*/
|
|
69
|
+
export type PixelNodeInfo<TParams> = {
|
|
70
|
+
context: NodeContext;
|
|
71
|
+
image: ImageBuffer;
|
|
72
|
+
state: NodeState;
|
|
73
|
+
params: TParams;
|
|
74
|
+
width: number;
|
|
75
|
+
height: number;
|
|
19
76
|
};
|
|
77
|
+
/**
|
|
78
|
+
* Handler signature for pixel-based nodes.
|
|
79
|
+
*/
|
|
80
|
+
export type PixelNodeRunner<TParams> = (pixels: PixelMatrix, info: PixelNodeInfo<TParams>) => PixelMatrix | ImageBuffer | Promise<PixelMatrix | ImageBuffer>;
|
|
81
|
+
/**
|
|
82
|
+
* Simplified node definition.
|
|
83
|
+
*/
|
|
84
|
+
export type SimpleNodeDefinition<TParams> = {
|
|
85
|
+
name?: string;
|
|
86
|
+
params?: TParams;
|
|
87
|
+
input?: string;
|
|
88
|
+
output?: string;
|
|
89
|
+
run: PixelNodeRunner<TParams>;
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* Creates a node that reads a single image key and writes a single image key.
|
|
93
|
+
*/
|
|
94
|
+
export declare function createImageNode<TParams>(name: string, params: TParams, run: (context: NodeContext, image: ImageBuffer, params: TParams, state: NodeState) => Promise<ImageBuffer> | ImageBuffer, options?: ImageNodeOptions): ImageNode<TParams>;
|
|
95
|
+
/**
|
|
96
|
+
* Creates a node that operates on a 2D pixel matrix.
|
|
97
|
+
*/
|
|
98
|
+
export declare function createPixelNode<TParams>(name: string, params: TParams, run: PixelNodeRunner<TParams>, options?: ImageNodeOptions): ImageNode<TParams>;
|
|
99
|
+
/**
|
|
100
|
+
* Creates a simplified pixel-based node with optional name and parameters.
|
|
101
|
+
*/
|
|
102
|
+
export declare function node<TParams>(definition: SimpleNodeDefinition<TParams>): ImageNode<TParams>;
|
|
103
|
+
/**
|
|
104
|
+
* Returns the image associated with the given key.
|
|
105
|
+
*/
|
|
106
|
+
export declare function getImage(state: NodeState, key?: string): ImageBuffer;
|
|
107
|
+
/**
|
|
108
|
+
* Merges a node result into a state snapshot.
|
|
109
|
+
*/
|
|
110
|
+
export declare function mergeNodeState(state: NodeState, result: NodeResult): NodeState;
|
|
111
|
+
/**
|
|
112
|
+
* Runs a node and returns its raw result.
|
|
113
|
+
*/
|
|
114
|
+
export declare function runNode(node: ImageNode, context: NodeContext, state: NodeState): Promise<NodeResult>;
|
|
115
|
+
/**
|
|
116
|
+
* Runs a node and returns a single image output.
|
|
117
|
+
*/
|
|
118
|
+
export declare function runNodeImage(node: ImageNode, context: NodeContext, state: NodeState, outputKey?: string): Promise<ImageBuffer>;
|
|
20
119
|
/**
|
|
21
120
|
* Selector used to choose pixels for masked execution.
|
|
22
121
|
*/
|
|
@@ -25,24 +124,21 @@ export type PixelSelector = (pixel: Pixel, x: number, y: number, context: NodeCo
|
|
|
25
124
|
* Masking options for nodes.
|
|
26
125
|
*/
|
|
27
126
|
export type SelectionOptions = {
|
|
28
|
-
/**
|
|
29
|
-
* preserve: keep non-selected pixels from the original image.
|
|
30
|
-
* clip: replace non-selected pixels with outsideColor.
|
|
31
|
-
*/
|
|
32
127
|
mode?: SelectionMode;
|
|
33
|
-
/**
|
|
34
|
-
* Color used for clip mode. Defaults to transparent black.
|
|
35
|
-
*/
|
|
36
128
|
outsideColor?: ColorInput;
|
|
37
129
|
};
|
|
38
130
|
/**
|
|
39
131
|
* Masking mode for selection.
|
|
40
132
|
*/
|
|
41
133
|
export type SelectionMode = 'preserve' | 'clip';
|
|
134
|
+
/**
|
|
135
|
+
* Image source input accepted by nodes.
|
|
136
|
+
*/
|
|
137
|
+
export type ImageInput = ImageSource | ImageBuffer | ImageNode;
|
|
42
138
|
/**
|
|
43
139
|
* Mask source for color mapping.
|
|
44
140
|
*/
|
|
45
|
-
export type MaskMapSource =
|
|
141
|
+
export type MaskMapSource = ImageInput;
|
|
46
142
|
/**
|
|
47
143
|
* Color-to-source mapping entry.
|
|
48
144
|
*/
|
|
@@ -91,12 +187,6 @@ export declare function createLumaSelector(threshold: number): PixelSelector;
|
|
|
91
187
|
* Creates an alpha-based selector.
|
|
92
188
|
*/
|
|
93
189
|
export declare function createAlphaSelector(threshold: number): PixelSelector;
|
|
94
|
-
/**
|
|
95
|
-
* Image node with typed parameters metadata.
|
|
96
|
-
*/
|
|
97
|
-
export type ParametricNode<TParams> = ImageNode & {
|
|
98
|
-
params: TParams;
|
|
99
|
-
};
|
|
100
190
|
/**
|
|
101
191
|
* Creates a node with typed parameters stored in the node metadata.
|
|
102
192
|
*/
|
|
@@ -104,7 +194,7 @@ export declare function createParamNode<TParams>(name: string, params: TParams,
|
|
|
104
194
|
/**
|
|
105
195
|
* Creates a masked node that only processes selected pixels.
|
|
106
196
|
*/
|
|
107
|
-
export declare function createMaskedNode(node: ImageNode, selector: PixelSelector, options?: SelectionOptions): ImageNode;
|
|
197
|
+
export declare function createMaskedNode(node: ImageNode, selector: PixelSelector, options?: SelectionOptions, io?: ImageNodeOptions): ImageNode;
|
|
108
198
|
/**
|
|
109
199
|
* Creates a node that composites sources based on a color mask.
|
|
110
200
|
*/
|
|
@@ -130,10 +220,105 @@ export type NoiseOptions = {
|
|
|
130
220
|
alpha?: number;
|
|
131
221
|
grayscale?: boolean;
|
|
132
222
|
};
|
|
223
|
+
/**
|
|
224
|
+
* Options for creating a value noise node.
|
|
225
|
+
*/
|
|
226
|
+
export type ValueNoiseOptions = {
|
|
227
|
+
scale?: number;
|
|
228
|
+
octaves?: number;
|
|
229
|
+
persistence?: number;
|
|
230
|
+
lacunarity?: number;
|
|
231
|
+
min?: number;
|
|
232
|
+
max?: number;
|
|
233
|
+
alpha?: number;
|
|
234
|
+
};
|
|
235
|
+
/**
|
|
236
|
+
* Options for creating a Voronoi noise node.
|
|
237
|
+
*/
|
|
238
|
+
export type VoronoiNoiseOptions = {
|
|
239
|
+
scale?: number;
|
|
240
|
+
jitter?: number;
|
|
241
|
+
min?: number;
|
|
242
|
+
max?: number;
|
|
243
|
+
alpha?: number;
|
|
244
|
+
mode?: 'distance' | 'edge';
|
|
245
|
+
};
|
|
246
|
+
/**
|
|
247
|
+
* Options for creating a fractal noise node.
|
|
248
|
+
*/
|
|
249
|
+
export type FractalNoiseOptions = {
|
|
250
|
+
scale?: number;
|
|
251
|
+
octaves?: number;
|
|
252
|
+
persistence?: number;
|
|
253
|
+
lacunarity?: number;
|
|
254
|
+
min?: number;
|
|
255
|
+
max?: number;
|
|
256
|
+
alpha?: number;
|
|
257
|
+
};
|
|
258
|
+
/**
|
|
259
|
+
* Options for creating a Perlin noise node.
|
|
260
|
+
*/
|
|
261
|
+
export type PerlinNoiseOptions = {
|
|
262
|
+
scale?: number;
|
|
263
|
+
octaves?: number;
|
|
264
|
+
persistence?: number;
|
|
265
|
+
lacunarity?: number;
|
|
266
|
+
min?: number;
|
|
267
|
+
max?: number;
|
|
268
|
+
alpha?: number;
|
|
269
|
+
};
|
|
270
|
+
/**
|
|
271
|
+
* Options for creating a turbulence noise node.
|
|
272
|
+
*/
|
|
273
|
+
export type TurbulenceNoiseOptions = {
|
|
274
|
+
scale?: number;
|
|
275
|
+
octaves?: number;
|
|
276
|
+
persistence?: number;
|
|
277
|
+
lacunarity?: number;
|
|
278
|
+
min?: number;
|
|
279
|
+
max?: number;
|
|
280
|
+
alpha?: number;
|
|
281
|
+
};
|
|
282
|
+
/**
|
|
283
|
+
* Options for creating a ridged noise node.
|
|
284
|
+
*/
|
|
285
|
+
export type RidgedNoiseOptions = {
|
|
286
|
+
scale?: number;
|
|
287
|
+
octaves?: number;
|
|
288
|
+
persistence?: number;
|
|
289
|
+
lacunarity?: number;
|
|
290
|
+
min?: number;
|
|
291
|
+
max?: number;
|
|
292
|
+
alpha?: number;
|
|
293
|
+
};
|
|
133
294
|
/**
|
|
134
295
|
* Creates a node that applies seeded noise to every pixel.
|
|
135
296
|
*/
|
|
136
297
|
export declare function createNoiseNode(options?: NoiseOptions): ImageNode;
|
|
298
|
+
/**
|
|
299
|
+
* Creates a node that generates value noise.
|
|
300
|
+
*/
|
|
301
|
+
export declare function createValueNoiseNode(options?: ValueNoiseOptions): ImageNode;
|
|
302
|
+
/**
|
|
303
|
+
* Creates a node that generates Voronoi noise.
|
|
304
|
+
*/
|
|
305
|
+
export declare function createVoronoiNoiseNode(options?: VoronoiNoiseOptions): ImageNode;
|
|
306
|
+
/**
|
|
307
|
+
* Creates a node that generates fractal value noise.
|
|
308
|
+
*/
|
|
309
|
+
export declare function createFractalNoiseNode(options?: FractalNoiseOptions): ImageNode;
|
|
310
|
+
/**
|
|
311
|
+
* Creates a node that generates Perlin noise.
|
|
312
|
+
*/
|
|
313
|
+
export declare function createPerlinNoiseNode(options?: PerlinNoiseOptions): ImageNode;
|
|
314
|
+
/**
|
|
315
|
+
* Creates a node that generates turbulence noise.
|
|
316
|
+
*/
|
|
317
|
+
export declare function createTurbulenceNoiseNode(options?: TurbulenceNoiseOptions): ImageNode;
|
|
318
|
+
/**
|
|
319
|
+
* Creates a node that generates ridged noise.
|
|
320
|
+
*/
|
|
321
|
+
export declare function createRidgedNoiseNode(options?: RidgedNoiseOptions): ImageNode;
|
|
137
322
|
/**
|
|
138
323
|
* Options for convolution nodes.
|
|
139
324
|
*/
|
|
@@ -239,3 +424,8 @@ export declare function createEdgeDetectNode(): ImageNode;
|
|
|
239
424
|
* Creates a node that resizes the image to the target dimensions.
|
|
240
425
|
*/
|
|
241
426
|
export declare function createResizeNode(width: number, height: number, options?: ResizeOptions): ImageNode;
|
|
427
|
+
/**
|
|
428
|
+
* Creates a node that renders text onto an image.
|
|
429
|
+
*/
|
|
430
|
+
export declare function createTextNode(options: TextOptions): ImageNode<TextOptions>;
|
|
431
|
+
export {};
|
package/dist/core/pipeline.d.ts
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import { ImageBuffer } from './image';
|
|
2
2
|
import { ImageSource } from './types';
|
|
3
3
|
import { SeededRandom } from './random';
|
|
4
|
-
import { ImageNode } from './nodes';
|
|
4
|
+
import { ImageNode, NodeState } from './nodes';
|
|
5
5
|
/**
|
|
6
6
|
* Options for running a pipeline.
|
|
7
7
|
*/
|
|
8
8
|
export type PipelineOptions = {
|
|
9
9
|
seed?: number | string;
|
|
10
10
|
random?: SeededRandom;
|
|
11
|
+
data?: Record<string, unknown>;
|
|
11
12
|
};
|
|
13
|
+
/**
|
|
14
|
+
* Supported inputs for running a pipeline.
|
|
15
|
+
*/
|
|
16
|
+
export type PipelineInput = ImageSource | ImageBuffer | NodeState;
|
|
12
17
|
/**
|
|
13
18
|
* Sequential pipeline that runs image nodes in order.
|
|
14
19
|
*/
|
|
@@ -25,9 +30,17 @@ export declare class Pipeline {
|
|
|
25
30
|
/**
|
|
26
31
|
* Executes the pipeline against an input source or buffer.
|
|
27
32
|
*/
|
|
28
|
-
run(input:
|
|
33
|
+
run(input: PipelineInput, options?: PipelineOptions): Promise<ImageBuffer>;
|
|
34
|
+
/**
|
|
35
|
+
* Executes the pipeline and returns the full node state.
|
|
36
|
+
*/
|
|
37
|
+
runState(input: PipelineInput, options?: PipelineOptions): Promise<NodeState>;
|
|
29
38
|
}
|
|
30
39
|
/**
|
|
31
40
|
* Creates a small example pipeline for quick sanity checks.
|
|
32
41
|
*/
|
|
33
42
|
export declare function createExamplePipeline(): Pipeline;
|
|
43
|
+
/**
|
|
44
|
+
* Creates a pipeline with the provided nodes.
|
|
45
|
+
*/
|
|
46
|
+
export declare function pipeline(...nodes: ImageNode[]): Pipeline;
|
package/dist/core/sources.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ImageBuffer } from './image';
|
|
2
|
+
import { ColorInput } from './color';
|
|
2
3
|
import { ImageSource, PixelLike, PixelFormat } from './types';
|
|
3
4
|
/**
|
|
4
5
|
* Creates an ImageSource from a local file path.
|
|
@@ -38,6 +39,56 @@ export type ResizeOptions = {
|
|
|
38
39
|
fit?: 'contain' | 'cover' | 'fill' | 'inside' | 'outside';
|
|
39
40
|
withoutEnlargement?: boolean;
|
|
40
41
|
};
|
|
42
|
+
/**
|
|
43
|
+
* Text font source configuration.
|
|
44
|
+
*/
|
|
45
|
+
export type TextFontSource = {
|
|
46
|
+
filePath?: string;
|
|
47
|
+
data?: Buffer;
|
|
48
|
+
mime?: string;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Text font configuration.
|
|
52
|
+
*/
|
|
53
|
+
export type TextFont = {
|
|
54
|
+
family: string;
|
|
55
|
+
source?: TextFontSource;
|
|
56
|
+
weight?: number | string;
|
|
57
|
+
style?: 'normal' | 'italic' | 'oblique';
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Text layout options.
|
|
61
|
+
*/
|
|
62
|
+
export type TextLayout = {
|
|
63
|
+
x: number;
|
|
64
|
+
y: number;
|
|
65
|
+
maxWidth?: number;
|
|
66
|
+
maxLines?: number;
|
|
67
|
+
align?: 'left' | 'center' | 'right';
|
|
68
|
+
lineHeight?: number;
|
|
69
|
+
letterSpacing?: number;
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* Text style options.
|
|
73
|
+
*/
|
|
74
|
+
export type TextStyle = {
|
|
75
|
+
fontSize?: number;
|
|
76
|
+
color?: ColorInput;
|
|
77
|
+
bold?: boolean;
|
|
78
|
+
italic?: boolean;
|
|
79
|
+
underline?: boolean;
|
|
80
|
+
strikethrough?: boolean;
|
|
81
|
+
opacity?: number;
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* Text rendering options.
|
|
85
|
+
*/
|
|
86
|
+
export type TextOptions = {
|
|
87
|
+
text: string;
|
|
88
|
+
font: TextFont;
|
|
89
|
+
layout: TextLayout;
|
|
90
|
+
style?: TextStyle;
|
|
91
|
+
};
|
|
41
92
|
/**
|
|
42
93
|
* Serializes an ImageBuffer to an encoded image buffer.
|
|
43
94
|
*/
|
|
@@ -50,3 +101,7 @@ export declare function saveImage(image: ImageBuffer, outputPath: string, option
|
|
|
50
101
|
* Resizes an ImageBuffer and returns a new buffer.
|
|
51
102
|
*/
|
|
52
103
|
export declare function resizeImage(image: ImageBuffer, width: number, height: number, options?: ResizeOptions): Promise<ImageBuffer>;
|
|
104
|
+
/**
|
|
105
|
+
* Renders text onto an ImageBuffer.
|
|
106
|
+
*/
|
|
107
|
+
export declare function renderText(image: ImageBuffer, options: TextOptions): Promise<ImageBuffer>;
|
package/dist/index.d.ts
CHANGED
|
@@ -3,8 +3,9 @@ export { colorDistance, hexToRgba, hslaToRgba, hsvaToRgba, rgbaToHex, rgbaToHsla
|
|
|
3
3
|
export type { Pixel, PixelFormat, PixelLike, ImageSource } from './core/types';
|
|
4
4
|
export { ImageBuffer } from './core/image';
|
|
5
5
|
export { SeededRandom, createRandom } from './core/random';
|
|
6
|
-
export type { ResizeOptions, SaveImageOptions } from './core/sources';
|
|
7
|
-
export { imageToBuffer, loadImage, resizeImage, saveImage, sourceFromBuffer, sourceFromDataUri, sourceFromEmpty, sourceFromPath, sourceFromUrl, } from './core/sources';
|
|
8
|
-
export type { CircleSelectorOptions, ImageNode, MaskMapEntry, MaskMapOptions, MaskMapSource, NodeContext, ParametricNode, PixelSelector, RectSelectorOptions, SelectionMode, SelectionOptions, } from './core/nodes';
|
|
9
|
-
export { createBrightnessNode, createCircleSelector, createCheckerboardNode, createCircleNode, createConvolutionNode, createContrastNode, createAlphaSelector, createEdgeDetectNode, createFillNode, createGammaNode, createGaussianBlurNode, createGaussianNoiseNode, createGrayscaleNode, createInvertNode, createLumaSelector, createMapNode, createMaskMapNode, createMaskedNode, createNoiseNode, createPaletteMapNode, createParamNode, createRandomFillNode, createRectSelector, createResizeNode, createSelectionCropNode, createRectNode, createSaltPepperNoiseNode, createSharpenNode, createThresholdNode, buildBoxKernel, buildGaussianKernel, } from './core/nodes';
|
|
10
|
-
export {
|
|
6
|
+
export type { ResizeOptions, SaveImageOptions, TextFont, TextFontSource, TextLayout, TextOptions, TextStyle, } from './core/sources';
|
|
7
|
+
export { imageToBuffer, loadImage, renderText, resizeImage, saveImage, sourceFromBuffer, sourceFromDataUri, sourceFromEmpty, sourceFromPath, sourceFromUrl, } from './core/sources';
|
|
8
|
+
export type { CircleSelectorOptions, ImageInput, ImageNode, ImageNodeOptions, MaskMapEntry, MaskMapOptions, MaskMapSource, NodeDefinition, NodeContext, NodeResult, NodeState, ParametricNode, PixelMatrix, PixelNodeInfo, PixelNodeRunner, PixelSelector, FractalNoiseOptions, PerlinNoiseOptions, RectSelectorOptions, SelectionMode, SelectionOptions, SimpleNodeDefinition, ValueNoiseOptions, RidgedNoiseOptions, TurbulenceNoiseOptions, VoronoiNoiseOptions, } from './core/nodes';
|
|
9
|
+
export { DEFAULT_IMAGE_KEY, createBrightnessNode, createCircleSelector, createCheckerboardNode, createCircleNode, createConvolutionNode, createContrastNode, createAlphaSelector, createEdgeDetectNode, createFillNode, createGammaNode, createGaussianBlurNode, createGaussianNoiseNode, createGrayscaleNode, createInvertNode, createImageNode, createPixelNode, createLumaSelector, createMapNode, createMaskMapNode, createMaskedNode, createNoiseNode, createFractalNoiseNode, createPerlinNoiseNode, createRidgedNoiseNode, createTurbulenceNoiseNode, createValueNoiseNode, createVoronoiNoiseNode, createPaletteMapNode, createParamNode, createRandomFillNode, createRectSelector, createResizeNode, createSelectionCropNode, createRectNode, createSaltPepperNoiseNode, createSharpenNode, createThresholdNode, createTextNode, defineNode, getImage, mergeNodeState, node, runNode, runNodeImage, buildBoxKernel, buildGaussianKernel, } from './core/nodes';
|
|
10
|
+
export type { PipelineInput, PipelineOptions } from './core/pipeline';
|
|
11
|
+
export { Pipeline, createExamplePipeline, pipeline } from './core/pipeline';
|