@thi.ng/imago 0.4.1 → 0.5.1

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/CHANGELOG.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Change Log
2
2
 
3
- - **Last updated**: 2024-02-28T14:23:30Z
3
+ - **Last updated**: 2024-03-01T15:22:50Z
4
4
  - **Generator**: [thi.ng/monopub](https://thi.ng/monopub)
5
5
 
6
6
  All notable changes to this project will be documented in this file.
@@ -9,6 +9,39 @@ See [Conventional Commits](https://conventionalcommits.org/) for commit guidelin
9
9
  **Note:** Unlisted _patch_ versions only involve non-code or otherwise excluded changes
10
10
  and/or version bumps of transitive dependencies.
11
11
 
12
+ ## [0.5.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/imago@0.5.0) (2024-03-01)
13
+
14
+ #### 🚀 Features
15
+
16
+ - update/improve/fix fluid position handling ([55284cd](https://github.com/thi-ng/umbrella/commit/55284cd))
17
+ - update computeSize(), computMargins(), refSize(), positionOrGravity()
18
+ - update CompLayerBase
19
+ - add `ref`-side support for crop, resize, and all comp layer types
20
+ - update imageLayer(), use "fill" mode for resizing
21
+ - add tests
22
+ - add docs
23
+ - add defLayerSpec() and layer factory fns ([2fc4334](https://github.com/thi-ng/umbrella/commit/2fc4334))
24
+ - add/update layer types, positioning, origin, gravity ([eae646f](https://github.com/thi-ng/umbrella/commit/eae646f))
25
+ - add RawLayer, update other layer types ([ad59ce3](https://github.com/thi-ng/umbrella/commit/ad59ce3))
26
+ - add rawLayer() & impl
27
+ - update CompLayer types & impls
28
+ - update imageLayer() to support buffer inputs
29
+ - add docs
30
+ - add suport for cropping with aspect ratio ([2b3db06](https://github.com/thi-ng/umbrella/commit/2b3db06))
31
+ - add `aspect` format ID for formatPath() ([25d8377](https://github.com/thi-ng/umbrella/commit/25d8377))
32
+ - update resize, add support for proportional resize ([6b13b0d](https://github.com/thi-ng/umbrella/commit/6b13b0d))
33
+ - update resizeProc() to handle scalar `size` to scale proportionally
34
+ with automatic aspect detection
35
+
36
+ #### 🩹 Bug fixes
37
+
38
+ - use transparent black as default `extend()` bg color ([d5a98ef](https://github.com/thi-ng/umbrella/commit/d5a98ef))
39
+
40
+ #### ♻️ Refactoring
41
+
42
+ - update defLayer() & CompLayerFn args ([294c6d0](https://github.com/thi-ng/umbrella/commit/294c6d0))
43
+ - update types, add docs, minor changes ([e3de1e2](https://github.com/thi-ng/umbrella/commit/e3de1e2))
44
+
12
45
  ### [0.4.1](https://github.com/thi-ng/umbrella/tree/@thi.ng/imago@0.4.1) (2024-02-28)
13
46
 
14
47
  #### 🩹 Bug fixes
package/README.md CHANGED
@@ -1,16 +1,5 @@
1
1
  <!-- This file is generated - DO NOT EDIT! -->
2
2
  <!-- Please see: https://github.com/thi-ng/umbrella/blob/develop/CONTRIBUTING.md#changes-to-readme-files -->
3
- > [!IMPORTANT]
4
- > ‼️ Announcing the thi.ng user survey 2024 📋
5
- >
6
- > [Please participate in the survey here!](https://forms.gle/XacbSDEmQMPZg8197)\
7
- > (open until end of February)
8
- >
9
- > **To achieve a better sample size, I'd highly appreciate if you could
10
- > circulate the link to this survey in your own networks.**
11
- >
12
- > [Discussion](https://github.com/thi-ng/umbrella/discussions/447)
13
-
14
3
  # ![@thi.ng/imago](https://media.thi.ng/umbrella/banners-20230807/thing-imago.svg?5b75bcfc)
15
4
 
16
5
  [![npm version](https://img.shields.io/npm/v/@thi.ng/imago.svg)](https://www.npmjs.com/package/@thi.ng/imago)
@@ -22,7 +11,7 @@
22
11
  > of the [@thi.ng/umbrella](https://github.com/thi-ng/umbrella/) monorepo
23
12
  > and anti-framework.
24
13
  >
25
- > 🚀 Help me to work full-time on these projects by [sponsoring me on
14
+ > 🚀 Please help me to work full-time on these projects by [sponsoring me on
26
15
  > GitHub](https://github.com/sponsors/postspectacular). Thank you! ❤️
27
16
 
28
17
  - [About](#about)
@@ -31,7 +20,9 @@
31
20
  - [blur](#blur)
32
21
  - [composite](#composite)
33
22
  - [Common options](#common-options)
34
- - [Bitmap layers](#bitmap-layers)
23
+ - [Bitmap image layers](#bitmap-image-layers)
24
+ - [Color layers](#color-layers)
25
+ - [Raw bitmap layers](#raw-bitmap-layers)
35
26
  - [SVG layers](#svg-layers)
36
27
  - [Text layers](#text-layers)
37
28
  - [crop](#crop)
@@ -47,10 +38,13 @@
47
38
  - [resize](#resize)
48
39
  - [rotate](#rotate)
49
40
  - [Status](#status)
41
+ - [Positions & sizes](#positions--sizes)
42
+ - [Gravity](#gravity)
50
43
  - [Metadata handling](#metadata-handling)
51
44
  - [Installation](#installation)
52
45
  - [Dependencies](#dependencies)
53
46
  - [API](#api)
47
+ - [Multistage processing pipeline](#multistage-processing-pipeline)
54
48
  - [Authors](#authors)
55
49
  - [License](#license)
56
50
 
@@ -67,7 +61,8 @@ In this new TypeScript version all image I/O and processing is delegated to
67
61
 
68
62
  ### Basic example
69
63
 
70
- Transformation trees/pipelines are simple JSON objects (but can be programmatically created):
64
+ Transformation trees/pipelines are simple JSON objects (but can be
65
+ programmatically created):
71
66
 
72
67
  The following pipeline performs these steps (in sequence):
73
68
 
@@ -76,10 +71,13 @@ The following pipeline performs these steps (in sequence):
76
71
  - proportionally resize image to 1920px (longest side by default)
77
72
  - overlay bitmap logo layer, positioned at 45% left / 5% bottom
78
73
  - add custom EXIF metadata
79
- - output this current stage as high quality AVIF (and record expanded output path)
74
+ - output this current stage as high quality AVIF (and record expanded output
75
+ path)
80
76
  - crop center square region
81
77
  - output as JPEG thumbnail (and record in outputs)
82
- - compute [blurhash](https://github.com/thi-ng/umbrella/blob/develop/packages/blurhash) (and record in outputs)
78
+ - compute
79
+ [blurhash](https://github.com/thi-ng/umbrella/blob/develop/packages/blurhash)
80
+ (and record in outputs)
83
81
 
84
82
  ```json tangle:export/readme-example1.json
85
83
  [
@@ -115,11 +113,12 @@ The following pipeline performs these steps (in sequence):
115
113
  },
116
114
  { "op": "crop", "size": [240, 240], "gravity": "c" },
117
115
  { "op": "output", "id": "thumb", "path": "{name}-thumb.jpg" },
118
- { "op": "output", "id": "hash", "path": "", blurhash: { detail: 4 } }
116
+ { "op": "output", "id": "hash", "blurhash": 4 }
119
117
  ]
120
118
  ```
121
119
 
122
- Then to process an image:
120
+ Then to process an image using above JSON spec (there're also API wrappers to
121
+ create these operator specs programmatically):
123
122
 
124
123
  ```ts tangle:export/readme1.ts
125
124
  import { processImage } from "@thi.ng/imago";
@@ -144,18 +143,31 @@ Gaussian blur
144
143
 
145
144
  ### composite
146
145
 
147
- Compositing multiple layers:
146
+ Compositing multiple layers. The following layer types are available, and custom
147
+ layer types can be registered via the polymorphic
148
+ [`defLayer()`](https://docs.thi.ng/umbrella/imago/functions/defLayer.html)
149
+ function.
148
150
 
149
151
  #### Common options
150
152
 
151
153
  - blend mode
152
- - gravity or position
154
+ - position & origin
155
+ - gravity
153
156
  - tiled repetition
154
157
 
155
- #### Bitmap layers
158
+ #### Bitmap image layers
156
159
 
157
160
  - resizable
158
161
 
162
+ #### Color layers
163
+
164
+ - size
165
+ - fill color (w/ alpha)
166
+
167
+ #### Raw bitmap layers
168
+
169
+ - from typed array or buffer
170
+
159
171
  #### SVG layers
160
172
 
161
173
  - from file or inline doc
@@ -172,7 +184,7 @@ Compositing multiple layers:
172
184
 
173
185
  Cropping a part of the image
174
186
 
175
- - from edges or region
187
+ - from edges, defined region or size & aspect ratio only
176
188
  - supports px or percent units
177
189
  - proportional to a given reference side/size
178
190
 
@@ -253,6 +265,7 @@ Any others will remain as is. Custom IDs take precedence over built-in ones.
253
265
  - `sha1`/`sha224`/`sha256`/`sha384`/`sha512`: truncated hash of output (8 chars)
254
266
  - `w`: current image width
255
267
  - `h`: current image height
268
+ - `aspect`: "p" (portrait), "l" (landscape) or "sq" (square)
256
269
  - `date`: yyyyMMdd date format, e.g. 20240223
257
270
  - `time`: HHmmss time format, e.g. 234459
258
271
  - `year`: 4-digit year
@@ -288,6 +301,28 @@ Auto-rotate, rotate by angle and/or flip image along x/y
288
301
 
289
302
  [Search or submit any issues for this package](https://github.com/thi-ng/umbrella/issues?q=%5Bimago%5D+in%3Atitle)
290
303
 
304
+ ## Positions & sizes
305
+
306
+ Border sizes, general dimensions, and positions can be specified in pixels
307
+ (default) or as percentages (using `unit: "%"`). For the latter case, an
308
+ additional reference side (`ref` option) can be provided. The default ref is
309
+ `min`, referring to whatever is the smaller side of an image.
310
+
311
+ The `ref` option/reference side can take the following values (default: `both`):
312
+
313
+ - `both`: image width for horizontal uses, image height for vertical uses
314
+ - `min`: smaller side of an image (aka `min(width,height)`)
315
+ - `max`: larger side of an image (aka `min(width,height)`)
316
+ - `w`: image width
317
+ - `h`: image height
318
+
319
+ ### Gravity
320
+
321
+ In some operations positioning or alignment can be abstractly stated via one of
322
+ the following gravity values:
323
+
324
+ ![diagram of the 9 possible gravity directions](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/imago/gravity.png)
325
+
291
326
  ## Metadata handling
292
327
 
293
328
  By default all input metadata will be lost in the outputs. The `keepEXIF` and
@@ -309,7 +344,7 @@ For Node.js REPL:
309
344
  const imago = await import("@thi.ng/imago");
310
345
  ```
311
346
 
312
- Package sizes (brotli'd, pre-treeshake): ESM: 4.15 KB
347
+ Package sizes (brotli'd, pre-treeshake): ESM: 4.81 KB
313
348
 
314
349
  ## Dependencies
315
350
 
@@ -331,7 +366,105 @@ Package sizes (brotli'd, pre-treeshake): ESM: 4.15 KB
331
366
 
332
367
  [Generated API docs](https://docs.thi.ng/umbrella/imago/)
333
368
 
334
- TODO
369
+ ### Multistage processing pipeline
370
+
371
+ ```ts tangle:export/readme-api.ts
372
+ import {
373
+ colorLayer,
374
+ composite,
375
+ crop,
376
+ extend,
377
+ imageLayer,
378
+ nest,
379
+ output,
380
+ processImage,
381
+ rawLayer,
382
+ resize,
383
+ rotate,
384
+ } from "@thi.ng/imago";
385
+ import { ConsoleLogger } from "@thi.ng/logger";
386
+
387
+ const res = await processImage(
388
+ "test.jpg",
389
+ // operator pipeline (i.e. a nested array of operator spec objects)
390
+ // the functions used here are merely syntax sugar for generating
391
+ // the spec objects to provide an anchor point for docs
392
+ // (ongoing effort, but since still a new project, mostly still forthcoming...)
393
+ [
394
+ // auto-rotate (EXIF orientation)
395
+ rotate({}),
396
+ // composite w/ semi-transparent color layer (screen)
397
+ composite({
398
+ layers: [
399
+ colorLayer({
400
+ // magenta with 50% opacity
401
+ bg: "#f0f8",
402
+ blend: "screen",
403
+ // layer size is 50x100% of image
404
+ size: [50, 100],
405
+ // aligned left (west)
406
+ gravity: "w",
407
+ // size given in percent
408
+ unit: "%",
409
+ }),
410
+ // diagonal hairline pattern overlay (with tiling) from raw
411
+ // pixel data in ABGR format, i.e. 0xAABBGGRR
412
+ rawLayer({
413
+ // prettier-ignore
414
+ buffer: new Uint32Array([
415
+ 0x00000000, 0x00000000, 0x00000000, 0x80ffffff,
416
+ 0x00000000, 0x00000000, 0x80ffffff, 0x00000000,
417
+ 0x00000000, 0x80ffffff, 0x00000000, 0x00000000,
418
+ 0x80ffffff, 0x00000000, 0x00000000, 0x00000000,
419
+ ]),
420
+ channels: 4,
421
+ size: [4, 4],
422
+ tile: true,
423
+ }),
424
+ ],
425
+ }),
426
+ // nested operations each operate on a clone of the current (already
427
+ // semi-transformed) image, they have no impact on the processing pipeline
428
+ // of their parent(s)
429
+ // multiple child pipelines can be spawned, here only a single one
430
+ nest({
431
+ procs: [
432
+ // this pipeline only creates blurhash (stored in `outputs` of result)
433
+ [resize({ size: 100 }), output({ id: "hash", blurhash: true })],
434
+ ],
435
+ }),
436
+ // crop to 3:2 aspect ratio (always based on longest side)
437
+ crop({ size: 100, aspect: 3 / 2, unit: "%" }),
438
+ // back in the main pipleline, add 5% white border (based on smallest side)
439
+ extend({ border: 5, unit: "%", bg: "white", ref: "min" }),
440
+ // resize image to 1920 (largest side)
441
+ resize({ size: 1920 }),
442
+ // add logo watermark centered horizontally and near the bottom
443
+ composite({
444
+ layers: [
445
+ imageLayer({
446
+ path: "logo-128.png",
447
+ unit: "%",
448
+ origin: "s",
449
+ pos: { l: 50, b: 5 },
450
+ ref: "both",
451
+ blend: "screen",
452
+ }),
453
+ ],
454
+ }),
455
+ output({ id: "main", path: "{date}-1920-frame.jpg" }),
456
+ ],
457
+ {
458
+ logger: new ConsoleLogger("img"),
459
+ }
460
+ );
461
+
462
+ console.log(res.outputs);
463
+ // {
464
+ // hash: "UVKmR.^SIVR$_NRiM{jupLRjjEWC%goxofoM",
465
+ // main: "...../20240301-144948-1920-frame.jpg",
466
+ // }
467
+ ```
335
468
 
336
469
  ## Authors
337
470
 
package/api.d.ts CHANGED
@@ -1,13 +1,22 @@
1
1
  /// <reference types="node" />
2
- import type { Fn, Fn3, Keys, TypedArray } from "@thi.ng/api";
2
+ import type { Fn, Fn3, Keys, Range1_4, TypedArray } from "@thi.ng/api";
3
3
  import type { ILogger } from "@thi.ng/logger";
4
4
  import type { AvifOptions, Blend, Exif, ExtendWith, FitEnum, GifOptions, Jp2Options, JpegOptions, JxlOptions, KernelEnum, Metadata, OverlayOptions, PngOptions, Sharp, TiffOptions, TileOptions, WebpOptions } from "sharp";
5
+ /**
6
+ * ```text
7
+ * nw -- n -- ne
8
+ * | | |
9
+ * w -- c -- e
10
+ * | | |
11
+ * sw -- s -- se
12
+ * ```
13
+ */
5
14
  export type Gravity = "c" | "e" | "n" | "ne" | "nw" | "s" | "se" | "sw" | "w";
6
15
  export type DitherMode = "atkinson" | "burkes" | "column" | "diffusion" | "floyd" | "jarvis" | "row" | "sierra" | "stucki" | "bayer";
7
16
  export type Dim = [number, number];
8
17
  export type Size = number | Dim;
9
18
  export type Sides = [number, number, number, number];
10
- export type SizeRef = "min" | "max" | "w" | "h";
19
+ export type SizeRef = "min" | "max" | "w" | "h" | "both";
11
20
  export type SizeUnit = "px" | "%";
12
21
  export type Color = string | number[] | {
13
22
  r: number;
@@ -15,60 +24,198 @@ export type Color = string | number[] | {
15
24
  b: number;
16
25
  alpha?: number;
17
26
  };
27
+ /**
28
+ * Position defined by max. 2 components/coordinates. If none are defined, the
29
+ * position will be interpreted as centered.
30
+ */
18
31
  export interface Position {
19
32
  l?: number;
20
33
  r?: number;
21
34
  t?: number;
22
35
  b?: number;
23
36
  }
37
+ export type BufferLike = TypedArray | Buffer;
24
38
  export type Processor = Fn3<ProcSpec, Sharp, ImgProcCtx, Promise<[Sharp, boolean]>>;
25
39
  export type CompLayerFn = Fn3<CompLayer, Sharp, ImgProcCtx, Promise<OverlayOptions>>;
26
40
  export interface ProcSpec {
41
+ /**
42
+ * Unique processor ID. Used to by {@link processor} to select correct
43
+ * implementation.
44
+ */
27
45
  op: string;
28
46
  }
29
47
  export interface BlurSpec extends ProcSpec {
30
48
  op: "blur";
49
+ /**
50
+ * Blur radius in pixels (can be fractional)
51
+ */
31
52
  radius: number;
32
53
  }
33
54
  export interface CompSpec extends ProcSpec {
34
55
  op: "composite";
35
56
  layers: CompLayer[];
36
57
  }
37
- export type CompLayer = ImgLayer | SVGLayer;
38
- export interface CompLayerBase {
58
+ export interface CompLayer {
59
+ /**
60
+ * Unique layer type, used by {@link composite} and {@link defLayer} to
61
+ * select correct layer implementation.
62
+ */
39
63
  type: string;
64
+ /**
65
+ * Layer blend mode. See [Sharp
66
+ * docs](https://sharp.pixelplumbing.com/api-composite#composite) for list
67
+ * of available modes.
68
+ *
69
+ * @defaultValue "over"
70
+ */
40
71
  blend?: Blend;
72
+ /**
73
+ * Abstracted layer position. This option is only used if no
74
+ * {@link CompLayer.pos} is specified. It also controls alignment
75
+ * of tiling when {@link CompLayer.tile} is enabled. If neither gravity
76
+ * or position are configured, the layer will be centered.
77
+ */
41
78
  gravity?: Gravity;
79
+ /**
80
+ * Partial layer position given in units of {@link CompLayer.unit}. At
81
+ * most 2 coordinate can be given here (e.g. left & top). The right & bottom
82
+ * values are overriding left/top (in case of conflict).
83
+ *
84
+ * @remarks
85
+ * Note: This option takes precedence over {@link CompLayer.gravity}. If
86
+ * neither gravity or position are configured, the layer will be centered.
87
+ */
42
88
  pos?: Position;
89
+ /**
90
+ * Origin/reference point for the given layer position
91
+ * {@link CompLayer.pos}. Only used if position is given.
92
+ *
93
+ * @remarks
94
+ * The given value specifies one of the 9 points in the layer which is to be
95
+ * used for the layer position (e.g. "se" for south-east aka bottom-right
96
+ * corner).
97
+ *
98
+ * If not given, it will be auto-determined by provided position config,
99
+ * e.g. a `pos` with right & top coords will have an implicit origin of `ne`
100
+ * (aka north-east). See gravity diagram {@link Gravity}.
101
+ */
102
+ origin?: Gravity;
103
+ /**
104
+ * Only used if {@link CompLayer.unit} is percent (`%`). Reference side
105
+ * ID for computing positions and sizes. See {@link SizeRef} for details.
106
+ *
107
+ * @defaultValue "both"
108
+ */
109
+ ref?: SizeRef;
110
+ /**
111
+ * If true, the layer will be repeated across the entire image with the
112
+ * given {@link CompLayer.gravity}.
113
+ */
43
114
  tile?: boolean;
115
+ /**
116
+ * Unit to use for {@link CompLayer.pos} and sizes (where
117
+ * supported). If `%`, the given values are interpreted as percentages,
118
+ * relative to configured {@link CompLayer.ref} side.
119
+ *
120
+ * @defaultValue "px"
121
+ */
44
122
  unit?: SizeUnit;
123
+ [id: string]: any;
45
124
  }
46
- export interface ImgLayer extends CompLayerBase {
47
- path: string;
125
+ export interface ColorLayer extends CompLayer {
126
+ type: "color";
127
+ /**
128
+ * Layer fill/background color.
129
+ */
130
+ bg: Color;
48
131
  size?: Size;
49
- unit?: SizeUnit;
50
132
  }
51
- export interface SVGLayer extends CompLayerBase {
133
+ export interface ImgLayer extends CompLayer {
134
+ type: "img";
135
+ /**
136
+ * Image as buffer (must be in one of sharp's supported image formats, use
137
+ * {@link rawLayer} / {@link RawLayer} for compositing raw image data)
138
+ */
139
+ buffer?: BufferLike;
140
+ /**
141
+ * File path to image, alternative to {@link ImgLayer.buffer}.
142
+ */
143
+ path?: string;
144
+ /**
145
+ * Layer target size (in units defined via {@link CompLayer.unit})
146
+ */
147
+ size?: Size;
148
+ }
149
+ export interface RawLayer extends CompLayer {
150
+ type: "raw";
151
+ buffer: BufferLike;
152
+ channels: Range1_4;
153
+ size: [number, number];
154
+ }
155
+ export interface SVGLayer extends CompLayer {
52
156
  type: "svg";
53
- body: string;
54
- path: string;
157
+ /**
158
+ * Inline SVG document, alternative to {@link SVGLayer.path}.
159
+ */
160
+ body?: string;
161
+ /**
162
+ * File path to SVG document.
163
+ */
164
+ path?: string;
55
165
  }
56
- export interface TextLayer extends CompLayerBase {
166
+ export interface TextLayer extends CompLayer {
57
167
  type: "text";
58
- textGravity: Gravity;
59
- bg: string;
60
- body: string | Fn<ImgProcCtx, string>;
61
- color: string;
62
- font: string;
63
- fontSize: number | string;
64
- padding: number;
65
- path: string;
66
- size: [number, number];
168
+ /**
169
+ * Background color.
170
+ *
171
+ * @defaultValue "#0000"
172
+ */
173
+ bg?: string;
174
+ /**
175
+ * Body text. Alternative to {@link TextLayer.path}. If given as function,
176
+ * the function will be called with the processing context and must return a
177
+ * string.
178
+ *
179
+ * @defaultValue ""
180
+ */
181
+ body?: string | Fn<ImgProcCtx, string>;
182
+ /**
183
+ * Text color
184
+ *
185
+ * @defaultValue "#fff"
186
+ */
187
+ color?: string;
188
+ font?: string;
189
+ fontSize?: number | string;
190
+ padding?: number;
191
+ path?: string;
192
+ /**
193
+ * Layer/textbox size. Required
194
+ */
195
+ size: Dim;
196
+ textGravity?: Gravity;
67
197
  }
68
198
  export interface CropSpec extends ProcSpec {
69
199
  op: "crop";
200
+ /**
201
+ * Target aspect ratio. Only used if {@link CropSpec.size} is given as
202
+ * single numeric value (pixels or percentage). If the aspect ratio is >1,
203
+ * the general aspect of the cropped image will remain principally the same,
204
+ * i.e. a portait image will remain portait (but cropped), ditto for
205
+ * landscape. If the given aspect raatio is <1, the aspect of the image will
206
+ * be flipped/swapped, i.e. a portait aspect becomes landscape and vice
207
+ * versa.
208
+ *
209
+ * @example
210
+ * ```js
211
+ * // crop image to 3:2 aspect ratio
212
+ * { op: "crop", size: 100, unit: "%", aspect: 3/2 }
213
+ * ```
214
+ */
215
+ aspect?: number;
70
216
  border?: Size | Sides;
71
217
  gravity?: Gravity;
218
+ origin?: Gravity;
72
219
  pos?: Position;
73
220
  ref?: SizeRef;
74
221
  size?: Size;
@@ -79,7 +226,7 @@ export interface DitherSpec extends ProcSpec {
79
226
  mode: DitherMode;
80
227
  num: number;
81
228
  rgb?: boolean;
82
- size: 2 | 4 | 8;
229
+ size?: 2 | 4 | 8;
83
230
  }
84
231
  export interface EXIFSpec extends ProcSpec {
85
232
  op: "exif";
@@ -126,9 +273,9 @@ export interface OutputSpec extends ProcSpec {
126
273
  id: string;
127
274
  /**
128
275
  * Possibly templated output path. See {@link formatPath} for details.
129
- * Ignored if {@link OutputSpec.blurhash} is being used.
276
+ * Ignored if {@link OutputSpec.blurhash} is being used, otherwise **required**.
130
277
  */
131
- path: string;
278
+ path?: string;
132
279
  /**
133
280
  * AVIF output options. See [Sharp docs](https://sharp.pixelplumbing.com/api-output#avif)
134
281
  */
@@ -139,18 +286,13 @@ export interface OutputSpec extends ProcSpec {
139
286
  * {@link OutputSpec.path} will be ignored and no file will be written.
140
287
  *
141
288
  * @remarks
289
+ * The value given is the blurhash detail setting in the [1,9] range (usual
290
+ * default is 4), possibly given separately for X/Y axes.
291
+ *
142
292
  * Important: Ensure the image has already been downsized to ~50-500 pixels.
143
293
  * Larger images are causing unnecessary & long processing...
144
294
  */
145
- blurhash?: {
146
- /**
147
- * Blurhash detail setting in 1-9 range, possibly given separately for
148
- * X/Y axis.
149
- *
150
- * @defaultValue 4
151
- */
152
- detail?: number | [number, number];
153
- };
295
+ blurhash?: true | number | [number, number];
154
296
  /**
155
297
  * GIF output options. See [Sharp docs](https://sharp.pixelplumbing.com/api-output#gif)
156
298
  */
@@ -204,13 +346,27 @@ export interface ResizeSpec extends ProcSpec {
204
346
  filter?: Keys<KernelEnum>;
205
347
  fit?: Keys<FitEnum>;
206
348
  gravity?: Gravity;
349
+ ref?: SizeRef;
350
+ /**
351
+ * New size of the image, expressed in pixels or percentages.
352
+ *
353
+ * @remarks
354
+ * If using pixels and size is a single number, it will be interpreted as
355
+ * the target size of the longest side and the other side scaled
356
+ * proportionally, using current aspect ratio.
357
+ *
358
+ * If given as `[width,height]` tuple, a negative value for a side makes
359
+ * that side proportionally scaled. relative to the other. E.g. a size of
360
+ * `[1280,-1]` scales the image to 1280 pixels wide and the height computed
361
+ * based on current aspect ratio.
362
+ */
207
363
  size: Size;
208
364
  unit?: SizeUnit;
209
365
  }
210
366
  export interface RotateSpec extends ProcSpec {
211
367
  op: "rotate";
212
368
  angle?: number;
213
- bg: Color;
369
+ bg?: Color;
214
370
  flipX?: boolean;
215
371
  flipY?: boolean;
216
372
  }
@@ -250,7 +406,7 @@ export interface ImgProcOpts {
250
406
  * Replacement IDs in this object will take precedence over built-in
251
407
  * replacement IDs, e.g. allowing to override `name`, `date` etc.
252
408
  */
253
- pathParts: Record<string, Fn3<ImgProcCtx, OutputSpec, Buffer | TypedArray, string> | string>;
409
+ pathParts: Record<string, Fn3<ImgProcCtx, OutputSpec, BufferLike, string> | string>;
254
410
  }
255
411
  export interface ImgProcCtx {
256
412
  path?: string;
@@ -261,7 +417,8 @@ export interface ImgProcCtx {
261
417
  logger: ILogger;
262
418
  opts: Partial<ImgProcOpts>;
263
419
  /**
264
- * Paths of all exported images.
420
+ * Paths of all exported images, keyed by IDs given via {@link OutputSpec} /
421
+ * {@link output}.
265
422
  */
266
423
  outputs: Record<string, string>;
267
424
  }
package/index.d.ts CHANGED
@@ -3,4 +3,22 @@ export * from "./ops.js";
3
3
  export * from "./path.js";
4
4
  export * from "./proc.js";
5
5
  export * from "./units.js";
6
+ export * from "./layers/color.js";
7
+ export * from "./layers/image.js";
8
+ export * from "./layers/raw.js";
9
+ export * from "./layers/svg.js";
10
+ export * from "./layers/text.js";
11
+ export * from "./ops/blur.js";
12
+ export * from "./ops/composite.js";
13
+ export * from "./ops/crop.js";
14
+ export * from "./ops/dither.js";
15
+ export * from "./ops/exif.js";
16
+ export * from "./ops/extend.js";
17
+ export * from "./ops/gamma.js";
18
+ export * from "./ops/grayscale.js";
19
+ export * from "./ops/hsbl.js";
20
+ export * from "./ops/nest.js";
21
+ export * from "./ops/output.js";
22
+ export * from "./ops/resize.js";
23
+ export * from "./ops/rotate.js";
6
24
  //# sourceMappingURL=index.d.ts.map