@pixerate/editor 0.200.0 → 0.202.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.
Files changed (36) hide show
  1. package/dist/agent/index.cjs +2 -2
  2. package/dist/agent/index.js +1 -1
  3. package/dist/{chunk-GLQQ2VIL.cjs → chunk-53GOGBTM.cjs} +23 -1
  4. package/dist/{chunk-3TNA7JKI.js → chunk-ZPJEH456.js} +22 -0
  5. package/dist/commands/builtins.d.cts +6 -0
  6. package/dist/commands/builtins.d.ts +6 -0
  7. package/dist/commands/index.cjs +4 -2
  8. package/dist/commands/index.js +4 -2
  9. package/dist/image-editor/controller.d.cts +18 -0
  10. package/dist/image-editor/controller.d.ts +18 -0
  11. package/dist/image-editor/index.cjs +180 -19
  12. package/dist/image-editor/index.js +179 -18
  13. package/dist/image-editor/selection/segment/index.d.cts +1 -0
  14. package/dist/image-editor/selection/segment/index.d.ts +1 -0
  15. package/dist/image-editor/selection/segment/sky.d.cts +21 -0
  16. package/dist/image-editor/selection/segment/sky.d.ts +21 -0
  17. package/dist/paint-editor/guide-tools.d.cts +2 -2
  18. package/dist/paint-editor/guide-tools.d.ts +2 -2
  19. package/dist/paint-editor/hosted.d.cts +34 -0
  20. package/dist/paint-editor/hosted.d.ts +34 -0
  21. package/dist/paint-editor/index.cjs +101 -10
  22. package/dist/paint-editor/index.d.cts +1 -0
  23. package/dist/paint-editor/index.d.ts +1 -0
  24. package/dist/paint-editor/index.js +96 -5
  25. package/dist/paint-editor/sticker-tools.d.cts +2 -2
  26. package/dist/paint-editor/sticker-tools.d.ts +2 -2
  27. package/dist/paint-editor/thick-tools.d.cts +2 -2
  28. package/dist/paint-editor/thick-tools.d.ts +2 -2
  29. package/dist/paint-editor/tools.d.cts +19 -2
  30. package/dist/paint-editor/tools.d.ts +19 -2
  31. package/dist/paint-editor/wet-tools.d.cts +2 -2
  32. package/dist/paint-editor/wet-tools.d.ts +2 -2
  33. package/package.json +1 -1
  34. package/skills/pixerate-image-editor/SKILL.md +1 -0
  35. package/skills/pixerate-image-selection-masking/SKILL.md +4 -2
  36. package/skills/pixerate-paint-editor/SKILL.md +9 -0
@@ -5,7 +5,7 @@
5
5
  var _chunkSOSBOS5Tcjs = require('../chunk-SOSBOS5T.cjs');
6
6
 
7
7
 
8
- var _chunkGLQQ2VILcjs = require('../chunk-GLQQ2VIL.cjs');
8
+ var _chunk53GOGBTMcjs = require('../chunk-53GOGBTM.cjs');
9
9
 
10
10
 
11
11
 
@@ -2107,7 +2107,7 @@ function createCanvasComponentToolProvider(controller, options = { id: "canvas-c
2107
2107
  ({ id }) => check(controller.restoreMainComponent(id))
2108
2108
  )
2109
2109
  ];
2110
- if (_chunkGLQQ2VILcjs.hasVariantCommands.call(void 0, controller)) {
2110
+ if (_chunk53GOGBTMcjs.hasVariantCommands.call(void 0, controller)) {
2111
2111
  const SET = { type: "string", description: "Component set, or one of its variants (default: the selection\u2019s set)." };
2112
2112
  const VARIANT = { type: "string", description: "Variant id (default: the first selected variant)." };
2113
2113
  const VALUES = { type: "object", additionalProperties: { type: "string" }, description: 'Variant property \u2192 value, e.g. { "Size": "Medium" }.' };
@@ -5,7 +5,7 @@ import {
5
5
  } from "../chunk-GOBOCZZI.js";
6
6
  import {
7
7
  hasVariantCommands
8
- } from "../chunk-3TNA7JKI.js";
8
+ } from "../chunk-ZPJEH456.js";
9
9
  import {
10
10
  createNodeLookup,
11
11
  ensureLayout,
@@ -283,6 +283,26 @@ var BRUSH_PAINT_PARAM = {
283
283
  }
284
284
  ]
285
285
  };
286
+ function planFreehandPlayback(points, max = 32) {
287
+ if (!Array.isArray(points)) return null;
288
+ const all = points.filter((p) => Array.isArray(p) && Number.isFinite(p[0]) && Number.isFinite(p[1])).map(([x, y]) => ({ x, y }));
289
+ if (!all.length) return null;
290
+ const step = (all.length - 1) / (max - 1);
291
+ const picked = all.length <= max ? all : Array.from({ length: max }, (_, i) => all[Math.round(i * step)]);
292
+ const [first, ...rest] = picked;
293
+ const gap = (p, i) => {
294
+ const prev = i ? rest[i - 1] : first;
295
+ return Math.hypot(p.x - prev.x, p.y - prev.y);
296
+ };
297
+ const total = rest.reduce((sum, p, i) => sum + gap(p, i), 0);
298
+ return [
299
+ { type: "move", to: first },
300
+ { type: "press", gesture: "path" },
301
+ ...rest.map((p, i) => ({ type: "drag", to: p, ms: total > 0 ? Math.max(16, 900 * gap(p, i) / total) : 16 })),
302
+ { type: "release" },
303
+ { type: "commit" }
304
+ ];
305
+ }
286
306
  function createDrawCommands(target, options = {}) {
287
307
  const prefix = _nullishCoalesce(options.prefix, () => ( "canvas."));
288
308
  const group = _nullishCoalesce(options.group, () => ( "Draw"));
@@ -323,6 +343,7 @@ function createDrawCommands(target, options = {}) {
323
343
  }
324
344
  },
325
345
  enabled: () => _optionalChain([options, 'access', _29 => _29.readOnlyReason, 'optionalCall', _30 => _30()]) || true,
346
+ plan: (_ctx, params) => planFreehandPlayback(params.points),
326
347
  run: (_ctx, params) => target.drawStroke({
327
348
  points: params.points,
328
349
  ...params.tool ? { tool: params.tool } : {},
@@ -676,4 +697,5 @@ function createSpreadsheetCommands(controller, options = {}) {
676
697
 
677
698
 
678
699
 
679
- exports.DEFAULT_HISTORY_SHORTCUTS = DEFAULT_HISTORY_SHORTCUTS; exports.createHistoryCommands = createHistoryCommands; exports.matchHistoryShortcut = matchHistoryShortcut; exports.createArrangeCommands = createArrangeCommands; exports.createShapeCommands = createShapeCommands; exports.createDrawCommands = createDrawCommands; exports.hasVariantCommands = hasVariantCommands; exports.createComponentCommands = createComponentCommands; exports.createSpreadsheetCommands = createSpreadsheetCommands;
700
+
701
+ exports.DEFAULT_HISTORY_SHORTCUTS = DEFAULT_HISTORY_SHORTCUTS; exports.createHistoryCommands = createHistoryCommands; exports.matchHistoryShortcut = matchHistoryShortcut; exports.createArrangeCommands = createArrangeCommands; exports.createShapeCommands = createShapeCommands; exports.planFreehandPlayback = planFreehandPlayback; exports.createDrawCommands = createDrawCommands; exports.hasVariantCommands = hasVariantCommands; exports.createComponentCommands = createComponentCommands; exports.createSpreadsheetCommands = createSpreadsheetCommands;
@@ -283,6 +283,26 @@ var BRUSH_PAINT_PARAM = {
283
283
  }
284
284
  ]
285
285
  };
286
+ function planFreehandPlayback(points, max = 32) {
287
+ if (!Array.isArray(points)) return null;
288
+ const all = points.filter((p) => Array.isArray(p) && Number.isFinite(p[0]) && Number.isFinite(p[1])).map(([x, y]) => ({ x, y }));
289
+ if (!all.length) return null;
290
+ const step = (all.length - 1) / (max - 1);
291
+ const picked = all.length <= max ? all : Array.from({ length: max }, (_, i) => all[Math.round(i * step)]);
292
+ const [first, ...rest] = picked;
293
+ const gap = (p, i) => {
294
+ const prev = i ? rest[i - 1] : first;
295
+ return Math.hypot(p.x - prev.x, p.y - prev.y);
296
+ };
297
+ const total = rest.reduce((sum, p, i) => sum + gap(p, i), 0);
298
+ return [
299
+ { type: "move", to: first },
300
+ { type: "press", gesture: "path" },
301
+ ...rest.map((p, i) => ({ type: "drag", to: p, ms: total > 0 ? Math.max(16, 900 * gap(p, i) / total) : 16 })),
302
+ { type: "release" },
303
+ { type: "commit" }
304
+ ];
305
+ }
286
306
  function createDrawCommands(target, options = {}) {
287
307
  const prefix = options.prefix ?? "canvas.";
288
308
  const group = options.group ?? "Draw";
@@ -323,6 +343,7 @@ function createDrawCommands(target, options = {}) {
323
343
  }
324
344
  },
325
345
  enabled: () => options.readOnlyReason?.() || true,
346
+ plan: (_ctx, params) => planFreehandPlayback(params.points),
326
347
  run: (_ctx, params) => target.drawStroke({
327
348
  points: params.points,
328
349
  ...params.tool ? { tool: params.tool } : {},
@@ -672,6 +693,7 @@ export {
672
693
  matchHistoryShortcut,
673
694
  createArrangeCommands,
674
695
  createShapeCommands,
696
+ planFreehandPlayback,
675
697
  createDrawCommands,
676
698
  hasVariantCommands,
677
699
  createComponentCommands,
@@ -3,6 +3,7 @@ import type { CanvasArrangeAction } from '../canvas/arrangeShortcuts.cjs';
3
3
  import type { AlignEdge, DistributeAxis, DistributeMode, ZOrderOperation } from '../canvas/arrange.cjs';
4
4
  import type { CanvasBrush, CanvasBrushPaint, CanvasBrushPreset } from '../canvas/brushTypes.cjs';
5
5
  import type { CommandSpec } from './registry.cjs';
6
+ import type { PlaybackStep } from '../tools/playback.cjs';
6
7
  import { type ShortcutBinding } from './shortcuts.cjs';
7
8
  import type { KeyboardEventLike, Platform } from './chords.cjs';
8
9
  /** Minimal history surface (`HistoryManager` satisfies it). */
@@ -135,6 +136,11 @@ export interface DrawCommandOptions {
135
136
  /** Refuse drawing with this reason (e.g. a read-only canvas); `canvas.listBrushes` still runs. */
136
137
  readOnlyReason?: () => string | null | undefined;
137
138
  }
139
+ /**
140
+ * Agent playback for `canvas.drawFreehand`: traces the stroke (canvas coordinates) with the
141
+ * button down, through at most `max` of its points, paced by length (about 900 ms in all).
142
+ */
143
+ export declare function planFreehandPlayback(points: unknown, max?: number): PlaybackStep[] | null;
138
144
  /**
139
145
  * Agent / palette commands for freehand drawing: `canvas.drawFreehand` (a pen or highlighter
140
146
  * stroke through given points, optionally brushed with a dry paint preset and a pressure / tilt
@@ -3,6 +3,7 @@ import type { CanvasArrangeAction } from '../canvas/arrangeShortcuts.js';
3
3
  import type { AlignEdge, DistributeAxis, DistributeMode, ZOrderOperation } from '../canvas/arrange.js';
4
4
  import type { CanvasBrush, CanvasBrushPaint, CanvasBrushPreset } from '../canvas/brushTypes.js';
5
5
  import type { CommandSpec } from './registry.js';
6
+ import type { PlaybackStep } from '../tools/playback.js';
6
7
  import { type ShortcutBinding } from './shortcuts.js';
7
8
  import type { KeyboardEventLike, Platform } from './chords.js';
8
9
  /** Minimal history surface (`HistoryManager` satisfies it). */
@@ -135,6 +136,11 @@ export interface DrawCommandOptions {
135
136
  /** Refuse drawing with this reason (e.g. a read-only canvas); `canvas.listBrushes` still runs. */
136
137
  readOnlyReason?: () => string | null | undefined;
137
138
  }
139
+ /**
140
+ * Agent playback for `canvas.drawFreehand`: traces the stroke (canvas coordinates) with the
141
+ * button down, through at most `max` of its points, paced by length (about 900 ms in all).
142
+ */
143
+ export declare function planFreehandPlayback(points: unknown, max?: number): PlaybackStep[] | null;
138
144
  /**
139
145
  * Agent / palette commands for freehand drawing: `canvas.drawFreehand` (a pen or highlighter
140
146
  * stroke through given points, optionally brushed with a dry paint preset and a pressure / tilt
@@ -8,7 +8,8 @@
8
8
 
9
9
 
10
10
 
11
- var _chunkGLQQ2VILcjs = require('../chunk-GLQQ2VIL.cjs');
11
+
12
+ var _chunk53GOGBTMcjs = require('../chunk-53GOGBTM.cjs');
12
13
 
13
14
 
14
15
 
@@ -1027,4 +1028,5 @@ function createCanvasAnimationCommands(controller, options = {}) {
1027
1028
 
1028
1029
 
1029
1030
 
1030
- exports.CommandRegistry = CommandRegistry; exports.CommandRegistryError = CommandRegistryError; exports.DEFAULT_HISTORY_SHORTCUTS = _chunkGLQQ2VILcjs.DEFAULT_HISTORY_SHORTCUTS; exports.DEFAULT_RECENT_LIMIT = DEFAULT_RECENT_LIMIT; exports.PLATFORMS = _chunk4EFNS2HVcjs.PLATFORMS; exports.ShortcutMap = _chunk4EFNS2HVcjs.ShortcutMap; exports.chordToString = _chunk4EFNS2HVcjs.chordToString; exports.codeFromKey = _chunk4EFNS2HVcjs.codeFromKey; exports.codeToKeyText = _chunk4EFNS2HVcjs.codeToKeyText; exports.createArrangeCommands = _chunkGLQQ2VILcjs.createArrangeCommands; exports.createCanvasAnimationCommands = createCanvasAnimationCommands; exports.createCommandPaletteController = createCommandPaletteController; exports.createCommandRegistry = createCommandRegistry; exports.createCommandToolProvider = createCommandToolProvider; exports.createComponentCommands = _chunkGLQQ2VILcjs.createComponentCommands; exports.createDrawCommands = _chunkGLQQ2VILcjs.createDrawCommands; exports.createFormatCommands = _chunkVCL7CB56cjs.createFormatCommands; exports.createHistoryCommands = _chunkGLQQ2VILcjs.createHistoryCommands; exports.createShapeCommands = _chunkGLQQ2VILcjs.createShapeCommands; exports.createSpreadsheetCommands = _chunkGLQQ2VILcjs.createSpreadsheetCommands; exports.defineCommand = defineCommand; exports.detectPlatform = _chunk4EFNS2HVcjs.detectPlatform; exports.effectiveChord = _chunk4EFNS2HVcjs.effectiveChord; exports.effectiveChordKey = _chunk4EFNS2HVcjs.effectiveChordKey; exports.eventCode = _chunk4EFNS2HVcjs.eventCode; exports.exactBonus = exactBonus; exports.formatCommandsFor = _chunkVCL7CB56cjs.formatCommandsFor; exports.formatShortcut = _chunk4EFNS2HVcjs.formatShortcut; exports.fuzzyMatch = fuzzyMatch; exports.fuzzyScore = fuzzyScore; exports.hasVariantCommands = _chunkGLQQ2VILcjs.hasVariantCommands; exports.isEditableEventTarget = _chunk4EFNS2HVcjs.isEditableEventTarget; exports.keyToCode = _chunk4EFNS2HVcjs.keyToCode; exports.matchHistoryShortcut = _chunkGLQQ2VILcjs.matchHistoryShortcut; exports.matchPaletteHotkey = matchPaletteHotkey; exports.normalizeChord = _chunk4EFNS2HVcjs.normalizeChord; exports.parseChord = _chunk4EFNS2HVcjs.parseChord; exports.pushRecent = pushRecent; exports.rankCommands = rankCommands; exports.shortcutCode = _chunk4EFNS2HVcjs.shortcutCode; exports.toShortcutBindings = _chunk4EFNS2HVcjs.toShortcutBindings;
1031
+
1032
+ exports.CommandRegistry = CommandRegistry; exports.CommandRegistryError = CommandRegistryError; exports.DEFAULT_HISTORY_SHORTCUTS = _chunk53GOGBTMcjs.DEFAULT_HISTORY_SHORTCUTS; exports.DEFAULT_RECENT_LIMIT = DEFAULT_RECENT_LIMIT; exports.PLATFORMS = _chunk4EFNS2HVcjs.PLATFORMS; exports.ShortcutMap = _chunk4EFNS2HVcjs.ShortcutMap; exports.chordToString = _chunk4EFNS2HVcjs.chordToString; exports.codeFromKey = _chunk4EFNS2HVcjs.codeFromKey; exports.codeToKeyText = _chunk4EFNS2HVcjs.codeToKeyText; exports.createArrangeCommands = _chunk53GOGBTMcjs.createArrangeCommands; exports.createCanvasAnimationCommands = createCanvasAnimationCommands; exports.createCommandPaletteController = createCommandPaletteController; exports.createCommandRegistry = createCommandRegistry; exports.createCommandToolProvider = createCommandToolProvider; exports.createComponentCommands = _chunk53GOGBTMcjs.createComponentCommands; exports.createDrawCommands = _chunk53GOGBTMcjs.createDrawCommands; exports.createFormatCommands = _chunkVCL7CB56cjs.createFormatCommands; exports.createHistoryCommands = _chunk53GOGBTMcjs.createHistoryCommands; exports.createShapeCommands = _chunk53GOGBTMcjs.createShapeCommands; exports.createSpreadsheetCommands = _chunk53GOGBTMcjs.createSpreadsheetCommands; exports.defineCommand = defineCommand; exports.detectPlatform = _chunk4EFNS2HVcjs.detectPlatform; exports.effectiveChord = _chunk4EFNS2HVcjs.effectiveChord; exports.effectiveChordKey = _chunk4EFNS2HVcjs.effectiveChordKey; exports.eventCode = _chunk4EFNS2HVcjs.eventCode; exports.exactBonus = exactBonus; exports.formatCommandsFor = _chunkVCL7CB56cjs.formatCommandsFor; exports.formatShortcut = _chunk4EFNS2HVcjs.formatShortcut; exports.fuzzyMatch = fuzzyMatch; exports.fuzzyScore = fuzzyScore; exports.hasVariantCommands = _chunk53GOGBTMcjs.hasVariantCommands; exports.isEditableEventTarget = _chunk4EFNS2HVcjs.isEditableEventTarget; exports.keyToCode = _chunk4EFNS2HVcjs.keyToCode; exports.matchHistoryShortcut = _chunk53GOGBTMcjs.matchHistoryShortcut; exports.matchPaletteHotkey = matchPaletteHotkey; exports.normalizeChord = _chunk4EFNS2HVcjs.normalizeChord; exports.parseChord = _chunk4EFNS2HVcjs.parseChord; exports.planFreehandPlayback = _chunk53GOGBTMcjs.planFreehandPlayback; exports.pushRecent = pushRecent; exports.rankCommands = rankCommands; exports.shortcutCode = _chunk4EFNS2HVcjs.shortcutCode; exports.toShortcutBindings = _chunk4EFNS2HVcjs.toShortcutBindings;
@@ -7,8 +7,9 @@ import {
7
7
  createShapeCommands,
8
8
  createSpreadsheetCommands,
9
9
  hasVariantCommands,
10
- matchHistoryShortcut
11
- } from "../chunk-3TNA7JKI.js";
10
+ matchHistoryShortcut,
11
+ planFreehandPlayback
12
+ } from "../chunk-ZPJEH456.js";
12
13
  import {
13
14
  PLATFORMS,
14
15
  ShortcutMap,
@@ -1023,6 +1024,7 @@ export {
1023
1024
  matchPaletteHotkey,
1024
1025
  normalizeChord,
1025
1026
  parseChord,
1027
+ planFreehandPlayback,
1026
1028
  pushRecent,
1027
1029
  rankCommands,
1028
1030
  shortcutCode,
@@ -3,6 +3,7 @@ import { type PathToSelectionOptions, type SelectionToPathOptions } from './sele
3
3
  import { type MagneticEdgeOptions } from './selection/magnetic.cjs';
4
4
  import { type ObjectTarget } from './selection/segment/grabcut.cjs';
5
5
  import { type FocusAreaOptions } from './selection/segment/focus.cjs';
6
+ import { type SkyOptions } from './selection/segment/sky.cjs';
6
7
  import { RenderOptions } from './renderer.cjs';
7
8
  import { type BlendMode } from './blend.cjs';
8
9
  import type { ImageHistogram } from './histogram.cjs';
@@ -160,6 +161,13 @@ export interface FocusAreaCommandOptions extends FocusAreaOptions {
160
161
  /** Sample every layer (default true) or only the active pixel layer. */
161
162
  sampleAllLayers?: boolean;
162
163
  }
164
+ /** Options of {@link ImageEditorController.selectSky}. */
165
+ export interface SkyCommandOptions extends SkyOptions {
166
+ /** How the sky combines with the selection (default `replace`). */
167
+ mode?: SelectionMode;
168
+ /** Sample every layer (default true) or only the active pixel layer. */
169
+ sampleAllLayers?: boolean;
170
+ }
163
171
  /** Options of {@link ImageEditorController.selectObject}. */
164
172
  export interface SelectObjectCommandOptions {
165
173
  /** How the object combines with the selection (default `replace`). */
@@ -1557,6 +1565,16 @@ export declare class ImageEditorController {
1557
1565
  selection: SelectionMask | null;
1558
1566
  noiseLevel: number;
1559
1567
  }>;
1568
+ /**
1569
+ * Select › Sky: selects the sky (blue, or bright and grey when overcast; smooth; grown down from
1570
+ * the top of the image, with patches seen through gaps), fitted to its edges, combined with the
1571
+ * selection by `mode` as one undo step. Resolves to the selection and, when no sky was found
1572
+ * (the selection is then unchanged), why.
1573
+ */
1574
+ selectSky(options?: SkyCommandOptions): Promise<{
1575
+ selection: SelectionMask | null;
1576
+ note?: string;
1577
+ }>;
1560
1578
  /**
1561
1579
  * Supplies the pixels the selection tools sample (natural size RGBA), e.g. decoded in a worker
1562
1580
  * or in a test; `null` goes back to reading the source image. Without a canvas (Node, workers)
@@ -3,6 +3,7 @@ import { type PathToSelectionOptions, type SelectionToPathOptions } from './sele
3
3
  import { type MagneticEdgeOptions } from './selection/magnetic.js';
4
4
  import { type ObjectTarget } from './selection/segment/grabcut.js';
5
5
  import { type FocusAreaOptions } from './selection/segment/focus.js';
6
+ import { type SkyOptions } from './selection/segment/sky.js';
6
7
  import { RenderOptions } from './renderer.js';
7
8
  import { type BlendMode } from './blend.js';
8
9
  import type { ImageHistogram } from './histogram.js';
@@ -160,6 +161,13 @@ export interface FocusAreaCommandOptions extends FocusAreaOptions {
160
161
  /** Sample every layer (default true) or only the active pixel layer. */
161
162
  sampleAllLayers?: boolean;
162
163
  }
164
+ /** Options of {@link ImageEditorController.selectSky}. */
165
+ export interface SkyCommandOptions extends SkyOptions {
166
+ /** How the sky combines with the selection (default `replace`). */
167
+ mode?: SelectionMode;
168
+ /** Sample every layer (default true) or only the active pixel layer. */
169
+ sampleAllLayers?: boolean;
170
+ }
163
171
  /** Options of {@link ImageEditorController.selectObject}. */
164
172
  export interface SelectObjectCommandOptions {
165
173
  /** How the object combines with the selection (default `replace`). */
@@ -1557,6 +1565,16 @@ export declare class ImageEditorController {
1557
1565
  selection: SelectionMask | null;
1558
1566
  noiseLevel: number;
1559
1567
  }>;
1568
+ /**
1569
+ * Select › Sky: selects the sky (blue, or bright and grey when overcast; smooth; grown down from
1570
+ * the top of the image, with patches seen through gaps), fitted to its edges, combined with the
1571
+ * selection by `mode` as one undo step. Resolves to the selection and, when no sky was found
1572
+ * (the selection is then unchanged), why.
1573
+ */
1574
+ selectSky(options?: SkyCommandOptions): Promise<{
1575
+ selection: SelectionMask | null;
1576
+ note?: string;
1577
+ }>;
1560
1578
  /**
1561
1579
  * Supplies the pixels the selection tools sample (natural size RGBA), e.g. decoded in a worker
1562
1580
  * or in a test; `null` goes back to reading the source image. Without a canvas (Node, workers)