@thi.ng/imago 1.0.17 → 1.1.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/CHANGELOG.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Change Log
2
2
 
3
- - **Last updated**: 2025-04-16T11:11:14Z
3
+ - **Last updated**: 2025-05-28T12:02:39Z
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.
@@ -11,6 +11,15 @@ See [Conventional Commits](https://conventionalcommits.org/) for commit guidelin
11
11
  **Note:** Unlisted _patch_ versions only involve non-code or otherwise excluded changes
12
12
  and/or version bumps of transitive dependencies.
13
13
 
14
+ ## [1.1.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/imago@1.1.0) (2025-05-28)
15
+
16
+ #### 🚀 Features
17
+
18
+ - add support for [@thi.ng/pixel](https://github.com/thi-ng/umbrella/tree/main/packages/pixel) int buffers as input ([e0b6de6](https://github.com/thi-ng/umbrella/commit/e0b6de6))
19
+ - update `processImage()`, update docs
20
+ - add `isIntBufferLike()` helper
21
+ - rename `src/units.ts` => `src/utils.ts`
22
+
14
23
  ## [0.8.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/imago@0.8.0) (2024-07-06)
15
24
 
16
25
  #### 🚀 Features
package/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
  [![Mastodon Follow](https://img.shields.io/mastodon/follow/109331703950160316?domain=https%3A%2F%2Fmastodon.thi.ng&style=social)](https://mastodon.thi.ng/@toxi)
8
8
 
9
9
  > [!NOTE]
10
- > This is one of 205 standalone projects, maintained as part
10
+ > This is one of 208 standalone projects, maintained as part
11
11
  > of the [@thi.ng/umbrella](https://github.com/thi-ng/umbrella/) monorepo
12
12
  > and anti-framework.
13
13
  >
@@ -360,7 +360,7 @@ For Node.js REPL:
360
360
  const imago = await import("@thi.ng/imago");
361
361
  ```
362
362
 
363
- Package sizes (brotli'd, pre-treeshake): ESM: 4.94 KB
363
+ Package sizes (brotli'd, pre-treeshake): ESM: 5.00 KB
364
364
 
365
365
  ## Dependencies
366
366
 
package/api.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { Fn, Fn3, IObjectOf, Keys, Range1_4, TypedArray } from "@thi.ng/api";
1
+ import type { Fn, Fn3, IObjectOf, Keys, Range1_4, TypedArray, UIntArray } from "@thi.ng/api";
2
2
  import type { ILogger } from "@thi.ng/logger";
3
3
  import type { AvifOptions, Blend, Exif, ExtendWith, FitEnum, GifOptions, Jp2Options, JpegOptions, JxlOptions, KernelEnum, Metadata, OverlayOptions, PngOptions, Sharp, TiffOptions, TileOptions, WebpOptions } from "sharp";
4
4
  /**
@@ -40,6 +40,18 @@ export interface Position {
40
40
  b?: number;
41
41
  }
42
42
  export type BufferLike = TypedArray | Buffer;
43
+ /**
44
+ * Simplified interface of thi.ng/pixel `IntBuffer`, only defining parts
45
+ * relevant to the conversion for {@link processImage}.
46
+ */
47
+ export interface IntBufferLike {
48
+ width: number;
49
+ height: number;
50
+ format: {
51
+ channels: unknown[];
52
+ };
53
+ data: UIntArray;
54
+ }
43
55
  export type Processor = Fn3<ProcSpec, Sharp, ImgProcCtx, Promise<[Sharp, boolean]>>;
44
56
  export type CompLayerFn = Fn3<CompLayer, Sharp, ImgProcCtx, Promise<OverlayOptions>>;
45
57
  export interface ProcSpec {
package/index.d.ts CHANGED
@@ -2,7 +2,7 @@ export * from "./api.js";
2
2
  export * from "./ops.js";
3
3
  export * from "./path.js";
4
4
  export * from "./proc.js";
5
- export * from "./units.js";
5
+ export * from "./utils.js";
6
6
  export * from "./layers/color.js";
7
7
  export * from "./layers/image.js";
8
8
  export * from "./layers/raw.js";
package/index.js CHANGED
@@ -2,7 +2,7 @@ export * from "./api.js";
2
2
  export * from "./ops.js";
3
3
  export * from "./path.js";
4
4
  export * from "./proc.js";
5
- export * from "./units.js";
5
+ export * from "./utils.js";
6
6
  export * from "./layers/color.js";
7
7
  export * from "./layers/image.js";
8
8
  export * from "./layers/raw.js";
package/layers/color.js CHANGED
@@ -1,4 +1,4 @@
1
- import { coerceColor, computeSize, positionOrGravity } from "../units.js";
1
+ import { coerceColor, computeSize, positionOrGravity } from "../utils.js";
2
2
  const colorLayerImpl = async (layer, _, ctx) => {
3
3
  const {
4
4
  type: __,
package/layers/image.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { illegalArgs } from "@thi.ng/errors";
2
2
  import sharp from "sharp";
3
- import { computeSize, ensureSize, positionOrGravity } from "../units.js";
3
+ import { computeSize, ensureSize, positionOrGravity } from "../utils.js";
4
4
  const imageLayerImpl = async (layer, _, ctx) => {
5
5
  const {
6
6
  type: __,
package/layers/raw.js CHANGED
@@ -1,4 +1,4 @@
1
- import { positionOrGravity } from "../units.js";
1
+ import { positionOrGravity } from "../utils.js";
2
2
  const rawLayerImpl = async (layer, _, ctx) => {
3
3
  const {
4
4
  type: __,
package/layers/svg.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { readText } from "@thi.ng/file-io";
2
- import { positionOrGravity } from "../units.js";
2
+ import { positionOrGravity } from "../utils.js";
3
3
  import { illegalArgs } from "@thi.ng/errors";
4
4
  const svgLayerImpl = async (layer, _, ctx) => {
5
5
  let {
package/layers/text.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { isFunction } from "@thi.ng/checks";
2
2
  import { XML_SVG } from "@thi.ng/prefixes";
3
- import { computeSize, gravityFlags, positionOrGravity } from "../units.js";
3
+ import { computeSize, gravityFlags, positionOrGravity } from "../utils.js";
4
4
  import { readText } from "@thi.ng/file-io";
5
5
  const textLayerImpl = async (layer, _, ctx) => {
6
6
  let {
package/ops/crop.js CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  computeSizeWithAspect,
7
7
  gravityPosition,
8
8
  positionOrGravity
9
- } from "../units.js";
9
+ } from "../utils.js";
10
10
  const cropProc = async (spec, input, ctx) => {
11
11
  const { aspect, border, gravity, pos, size, ref, unit } = spec;
12
12
  if (border == null && size == null)
package/ops/extend.js CHANGED
@@ -1,4 +1,4 @@
1
- import { coerceColor, computeMargins } from "../units.js";
1
+ import { coerceColor, computeMargins } from "../utils.js";
2
2
  const extendProc = async (spec, input, ctx) => {
3
3
  const { bg, border, mode, ref, unit } = spec;
4
4
  const sides = computeMargins(border, ctx.size, ref, unit);
package/ops/resize.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { isNumber } from "@thi.ng/checks";
2
2
  import { GRAVITY_POSITION } from "../api.js";
3
- import { coerceColor, computeSize } from "../units.js";
3
+ import { coerceColor, computeSize } from "../utils.js";
4
4
  const resizeProc = async (spec, input, ctx) => {
5
5
  const { bg, filter, fit, gravity, ref, size, unit } = spec;
6
6
  const aspect = ctx.size[0] / ctx.size[1];
package/ops/rotate.js CHANGED
@@ -1,4 +1,4 @@
1
- import { coerceColor } from "../units.js";
1
+ import { coerceColor } from "../utils.js";
2
2
  const rotateProc = async (spec, input, _) => {
3
3
  const { angle, bg, flipX, flipY } = spec;
4
4
  if (flipX) input = input.flop();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thi.ng/imago",
3
- "version": "1.0.17",
3
+ "version": "1.1.0",
4
4
  "description": "JSON & API-based declarative and extensible image processing trees/pipelines",
5
5
  "type": "module",
6
6
  "module": "./index.js",
@@ -39,25 +39,25 @@
39
39
  "tool:tangle": "../../node_modules/.bin/tangle src/**/*.ts"
40
40
  },
41
41
  "dependencies": {
42
- "@thi.ng/api": "^8.11.26",
43
- "@thi.ng/blurhash": "^1.0.13",
44
- "@thi.ng/checks": "^3.7.6",
45
- "@thi.ng/date": "^2.7.51",
46
- "@thi.ng/defmulti": "^3.0.66",
47
- "@thi.ng/errors": "^2.5.32",
48
- "@thi.ng/file-io": "^2.1.35",
49
- "@thi.ng/logger": "^3.1.7",
50
- "@thi.ng/object-utils": "^1.1.22",
51
- "@thi.ng/pixel": "^7.4.4",
52
- "@thi.ng/pixel-dither": "^1.1.165",
53
- "@thi.ng/prefixes": "^2.3.43",
54
- "sharp": "^0.34.1"
42
+ "@thi.ng/api": "^8.11.28",
43
+ "@thi.ng/blurhash": "^1.0.15",
44
+ "@thi.ng/checks": "^3.7.8",
45
+ "@thi.ng/date": "^2.7.53",
46
+ "@thi.ng/defmulti": "^3.0.68",
47
+ "@thi.ng/errors": "^2.5.34",
48
+ "@thi.ng/file-io": "^2.1.37",
49
+ "@thi.ng/logger": "^3.1.9",
50
+ "@thi.ng/object-utils": "^1.1.24",
51
+ "@thi.ng/pixel": "^7.5.0",
52
+ "@thi.ng/pixel-dither": "^1.1.167",
53
+ "@thi.ng/prefixes": "^2.3.45",
54
+ "sharp": "^0.34.2"
55
55
  },
56
56
  "devDependencies": {
57
- "@thi.ng/vectors": "^8.0.0",
58
- "@types/node": "^22.14.1",
59
- "esbuild": "^0.25.2",
60
- "typedoc": "^0.28.2",
57
+ "@thi.ng/vectors": "^8.2.1",
58
+ "@types/node": "^22.15.21",
59
+ "esbuild": "^0.25.5",
60
+ "typedoc": "^0.28.5",
61
61
  "typescript": "^5.8.3"
62
62
  },
63
63
  "keywords": [
@@ -181,13 +181,13 @@
181
181
  "./proc": {
182
182
  "default": "./proc.js"
183
183
  },
184
- "./units": {
185
- "default": "./units.js"
184
+ "./utils": {
185
+ "default": "./utils.js"
186
186
  }
187
187
  },
188
188
  "thi.ng": {
189
189
  "status": "alpha",
190
190
  "year": 2024
191
191
  },
192
- "gitHead": "c464b6948f92cba90c2ea75b59203dad894fb450\n"
192
+ "gitHead": "61c3833b7ef7d044621454b5ea4af885d39f065e\n"
193
193
  }
package/proc.d.ts CHANGED
@@ -1,14 +1,14 @@
1
1
  import sharp, { type Sharp } from "sharp";
2
- import type { BufferLike, ImgProcCtx, ImgProcOpts, ProcSpec } from "./api.js";
2
+ import type { BufferLike, ImgProcCtx, ImgProcOpts, IntBufferLike, ProcSpec } from "./api.js";
3
3
  export declare const LOGGER: import("@thi.ng/logger").ProxyLogger;
4
4
  /**
5
- * Main API function. Takes an image input (file path, buffer or existing Sharp
6
- * instance) and applies given processing pipeline specs in sequence. Returns a
7
- * promise of final processed image, input metadata (if any), an environment
8
- * object of arbitrary data (likely produced by custom ops/processors) and an
9
- * object of all written output paths (keyed by each output's
10
- * {@link OutputSpec.id}). The process pipeline can be additionally configured
11
- * via provided options.
5
+ * Main API function. Takes an image input (file path, Buffer, ArrayBuffer,
6
+ * thi.ng/pixel IntBuffer or an existing Sharp instance) and applies given
7
+ * processing pipeline specs in sequence. Returns a promise of final processed
8
+ * image, input metadata (if any), an environment object of arbitrary data
9
+ * (likely produced by custom ops/processors) and an object of all written
10
+ * output paths (keyed by each output's {@link OutputSpec.id}). The process
11
+ * pipeline can be additionally configured via provided options.
12
12
  *
13
13
  * @remarks
14
14
  * The `parentCtx` arg is internal use only (nested processors)!
@@ -18,7 +18,7 @@ export declare const LOGGER: import("@thi.ng/logger").ProxyLogger;
18
18
  * @param opts
19
19
  * @param parentCtx
20
20
  */
21
- export declare const processImage: (src: string | BufferLike | ArrayBuffer | Sharp, specs: ProcSpec[], opts?: Partial<ImgProcOpts>, parentCtx?: ImgProcCtx) => Promise<{
21
+ export declare const processImage: (src: string | BufferLike | ArrayBuffer | IntBufferLike | Sharp, specs: ProcSpec[], opts?: Partial<ImgProcOpts>, parentCtx?: ImgProcCtx) => Promise<{
22
22
  img: sharp.Sharp;
23
23
  meta: sharp.Metadata;
24
24
  env: import("@thi.ng/api").IObjectOf<any>;
package/proc.js CHANGED
@@ -17,10 +17,16 @@ import { nestProc } from "./ops/nest.js";
17
17
  import { outputProc } from "./ops/output.js";
18
18
  import { resizeProc } from "./ops/resize.js";
19
19
  import { rotateProc } from "./ops/rotate.js";
20
- import { ensureSize } from "./units.js";
20
+ import { ensureSize, isIntBufferLike } from "./utils.js";
21
21
  const LOGGER = ROOT.childLogger("imgproc");
22
22
  const processImage = async (src, specs, opts = {}, parentCtx) => {
23
- let img = isString(src) || isArrayBufferView(src) ? sharp(src) : src;
23
+ let img = isString(src) || isArrayBufferView(src) ? sharp(src) : isIntBufferLike(src) ? sharp(new Uint8Array(src.data.buffer), {
24
+ raw: {
25
+ width: src.width,
26
+ height: src.height,
27
+ channels: src.format.channels.length
28
+ }
29
+ }) : src;
24
30
  const meta = await img.metadata();
25
31
  ensureSize(meta);
26
32
  const ctx = {
@@ -1,6 +1,7 @@
1
1
  import type { Maybe } from "@thi.ng/api";
2
2
  import type { Metadata } from "sharp";
3
- import { type Color, type Dim, type Gravity, type Position, type Sides, type Size, type SizeRef, type SizeUnit } from "./api.js";
3
+ import { type Color, type Dim, type Gravity, type IntBufferLike, type Position, type Sides, type Size, type SizeRef, type SizeUnit } from "./api.js";
4
+ export declare const isIntBufferLike: (x: any) => x is IntBufferLike;
4
5
  export declare const ensureSize: (meta: Metadata) => false;
5
6
  export declare const coerceColor: (col: Color) => string | {
6
7
  r: number;
@@ -39,4 +40,4 @@ export declare const refSize: ([w, h]: Dim, ref?: SizeRef) => Dim;
39
40
  export declare const computeSize: (size: Size, curr: Dim, ref?: SizeRef, unit?: SizeUnit) => Dim;
40
41
  export declare const computeSizeWithAspect: (size: number, [w, h]: Dim, aspect: number, unit?: SizeUnit, clamp?: boolean) => Dim;
41
42
  export declare const computeMargins: (size: Size | Sides, curr: Dim, ref?: SizeRef, unit?: SizeUnit) => Sides;
42
- //# sourceMappingURL=units.d.ts.map
43
+ //# sourceMappingURL=utils.d.ts.map
@@ -1,9 +1,17 @@
1
- import { isArray, isArrayLike, isNumber, isString } from "@thi.ng/checks";
1
+ import {
2
+ isArray,
3
+ isArrayLike,
4
+ isNumber,
5
+ isPlainObject,
6
+ isString,
7
+ isTypedArray
8
+ } from "@thi.ng/checks";
2
9
  import { illegalArgs } from "@thi.ng/errors";
3
10
  import {
4
11
  GRAVITY_MAP
5
12
  } from "./api.js";
6
13
  const round = Math.round;
14
+ const isIntBufferLike = (x) => isNumber(x.width) && isNumber(x.height) && isTypedArray(x.data) && isPlainObject(x.format);
7
15
  const ensureSize = (meta) => !(isNumber(meta.width) && isNumber(meta.height)) && illegalArgs("can't determine image size");
8
16
  const coerceColor = (col) => isString(col) ? col : isArrayLike(col) ? { r: col[0], g: col[1], b: col[2], alpha: col[3] ?? 1 } : col;
9
17
  const positionOrGravity = ([w, h], parentSize, {
@@ -129,6 +137,7 @@ export {
129
137
  ensureSize,
130
138
  gravityFlags,
131
139
  gravityPosition,
140
+ isIntBufferLike,
132
141
  positionOrGravity,
133
142
  refSize
134
143
  };