@pixerate/editor 0.208.0 → 0.210.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 (30) hide show
  1. package/dist/{chunk-X4LUGTQX.cjs → chunk-L52VMQZS.cjs} +21 -10
  2. package/dist/{chunk-DWYQPL2A.js → chunk-LQ5SALHK.js} +13 -2
  3. package/dist/chunk-MQDIP4CF.cjs +462 -0
  4. package/dist/chunk-XI2NV5U7.js +462 -0
  5. package/dist/{chunk-3EHPLDFQ.cjs → chunk-YF3YZZ6G.cjs} +16 -453
  6. package/dist/{chunk-USQCKRZG.js → chunk-ZGJGSCUW.js} +8 -445
  7. package/dist/image-editor/content-aware-fill-session.d.cts +109 -0
  8. package/dist/image-editor/content-aware-fill-session.d.ts +109 -0
  9. package/dist/image-editor/controller.d.cts +85 -3
  10. package/dist/image-editor/controller.d.ts +85 -3
  11. package/dist/image-editor/index.cjs +847 -396
  12. package/dist/image-editor/index.d.cts +1 -0
  13. package/dist/image-editor/index.d.ts +1 -0
  14. package/dist/image-editor/index.js +492 -41
  15. package/dist/image-editor/selection/tool-options.d.cts +3 -1
  16. package/dist/image-editor/selection/tool-options.d.ts +3 -1
  17. package/dist/image-editor/selection/worker.d.cts +10 -0
  18. package/dist/image-editor/selection/worker.d.ts +10 -0
  19. package/dist/image-editor/selection-worker.cjs +4 -3
  20. package/dist/image-editor/selection-worker.js +2 -1
  21. package/dist/image-editor/types.d.cts +14 -0
  22. package/dist/image-editor/types.d.ts +14 -0
  23. package/dist/paint/heal.d.cts +3 -1
  24. package/dist/paint/heal.d.ts +3 -1
  25. package/dist/paint/index.cjs +4 -2
  26. package/dist/paint/index.js +10 -8
  27. package/package.json +1 -1
  28. package/skills/pixerate-image-editor/SKILL.md +21 -23
  29. package/skills/pixerate-image-editor/references/layer-effects.md +24 -0
  30. package/skills/pixerate-image-selection-masking/SKILL.md +2 -1
@@ -1,4 +1,4 @@
1
- import { AdjustmentKind, AdjustmentLayer, AdjustmentParamsMap, Annotation, CreateAnnotationPayload, AspectRatio, CropBox, DepthMaskOptions, ExportOptions, ImageAdjustments, ImageDimensions, ImageEditorFit, ImageEditorOptions, ImageEditorState, ImageEditorTool, ImageTransform, ImagePoint, SerializedImageEditorState } from './types.cjs';
1
+ import { AdjustmentKind, AdjustmentLayer, AdjustmentParamsMap, Annotation, CreateAnnotationPayload, AspectRatio, CropBox, DepthMaskOptions, ExportOptions, ImageAdjustments, ImageDimensions, ImageEditorFit, ImageEditorOptions, ImageEditorState, ImageEditorTool, ImageTransform, ImagePoint, SerializedImageEditorState, DocumentOpener } from './types.cjs';
2
2
  import { type PathToSelectionOptions, type SelectionToPathOptions } from './selection/path.cjs';
3
3
  import { type MagneticEdgeOptions } from './selection/magnetic.cjs';
4
4
  import type { ObjectTarget } from './selection/segment/grabcut.cjs';
@@ -168,7 +168,7 @@ export interface FocusAreaCommandOptions extends FocusAreaOptions {
168
168
  sampleAllLayers?: boolean;
169
169
  }
170
170
  /** Where Select and Mask puts its result (Photoshop's Output To). */
171
- export type RefineOutput = 'selection' | 'layer-mask' | 'new-layer' | 'new-layer-with-mask';
171
+ export type RefineOutput = 'selection' | 'layer-mask' | 'new-layer' | 'new-layer-with-mask' | 'new-document' | 'new-document-with-mask';
172
172
  /** What {@link ImageEditorController.refineSelectionTo} made. */
173
173
  export interface RefineOutputResult {
174
174
  output: RefineOutput;
@@ -176,6 +176,8 @@ export interface RefineOutputResult {
176
176
  layerId?: string;
177
177
  /** The layer it made (`new-layer`, `new-layer-with-mask`). */
178
178
  newLayerId?: string;
179
+ /** The id the host's document opener returned (`new-document`, `new-document-with-mask`). */
180
+ documentId?: string;
179
181
  /** How the edge was refined: by colour, or with the segmentation model (object aware). */
180
182
  refineMode: 'color' | 'object';
181
183
  }
@@ -486,6 +488,31 @@ export interface ContentAwareFillOptions {
486
488
  sampleRadius?: number;
487
489
  /** Random seed: the same seed gives the same fill (default 0). */
488
490
  seed?: number;
491
+ /**
492
+ * Where the fill may copy from (natural pixels), instead of the automatic ring around the
493
+ * selection: a mask (the Content-Aware Fill workspace's painted area), an alpha channel, or
494
+ * rectangles. `excludeRects` are never copied from, whichever way the area is given.
495
+ */
496
+ samplingArea?: SelectionMask | null;
497
+ samplingChannelId?: string;
498
+ sampleRects?: CropBox[];
499
+ excludeRects?: CropBox[];
500
+ }
501
+ /** What a Content-Aware Fill works on: the selection's window of a pixel layer (see `prepareContentAwareFill`). */
502
+ export interface ContentAwareFillPlan {
503
+ layerId: string;
504
+ /** The window it fills and samples in (document pixels). */
505
+ window: CropBox;
506
+ /** The selection's bounds. */
507
+ bounds: CropBox;
508
+ /** The layer's pixels in the window, RGBA. */
509
+ before: Uint8ClampedArray;
510
+ /** 1 where the selection covers (the hole), per window pixel. */
511
+ hole: Uint8Array;
512
+ /** The selection's coverage 0..255 per window pixel. */
513
+ coverage: Uint8Array;
514
+ /** 1 where the fill may not copy from, per window pixel (null: everywhere outside the hole). */
515
+ exclude: Uint8Array | null;
489
516
  }
490
517
  /** Pixels on the editor's clipboard: RGBA, and where they were copied from (document pixels). */
491
518
  export interface ClipboardImage extends PixelBuffer {
@@ -691,6 +718,7 @@ export declare class ImageEditorController {
691
718
  /** The segmentation provider behind `selectSubject` (see `setSegmentationProvider`). */
692
719
  private segmentation;
693
720
  private selectionWorker;
721
+ private documentOpener;
694
722
  /** The effects provider slot (see `setEffectsProvider`). */
695
723
  readonly effects: EffectsSlot;
696
724
  /** Renders provider effects: effect smart filter results and effect layers. */
@@ -726,6 +754,24 @@ export declare class ImageEditorController {
726
754
  * A worker that is cancelled or fails is replaced by a fresh one on the next job.
727
755
  */
728
756
  setSelectionWorker(factory: SelectionWorkerFactory | null): void;
757
+ /** Sets (or with `null` removes) how new documents are opened (see `DocumentOpener`). Not an edit. */
758
+ setDocumentOpener(opener: DocumentOpener | null): void;
759
+ /** Whether the host can open new documents (the New Document outputs are available). */
760
+ get canOpenDocuments(): boolean;
761
+ /**
762
+ * A new one-layer document from the selection (or `options.selection`) on a pixel layer
763
+ * (`layerId`, default the active one), the size of this image: the selected pixels on
764
+ * transparency, or with `withMask` the whole layer masked by the selection. This document is
765
+ * not changed. `decontaminate` (0..100) cleans the soft edge's colours as the new-layer
766
+ * outputs do.
767
+ */
768
+ documentFromSelection(options?: {
769
+ layerId?: string;
770
+ withMask?: boolean;
771
+ selection?: SelectionMask | null;
772
+ decontaminate?: number;
773
+ radius?: number;
774
+ }): SerializedLayeredImageEditorState;
729
775
  /** Whether the long selections run in a worker. */
730
776
  get hasSelectionWorker(): boolean;
731
777
  /**
@@ -1431,13 +1477,47 @@ export declare class ImageEditorController {
1431
1477
  * (PatchMatch, as the Spot Healing Brush's content-aware mode), blended by the selection's
1432
1478
  * coverage. `output` `current` paints into the layer; `new-layer` puts the fill on a new layer
1433
1479
  * above it. Samples within `sampleRadius` px of the selection (default its larger side, at
1434
- * least 32). Deterministic for a `seed`. One undo step. 8-bit documents only for now.
1480
+ * least 32), or from the given sampling area. Deterministic for a `seed`. One undo step.
1481
+ * 8-bit documents only for now. Runs here; see `contentAwareFillAsync` for the worker.
1435
1482
  */
1436
1483
  contentAwareFill(options?: ContentAwareFillOptions): {
1437
1484
  layerId: string;
1438
1485
  bounds: CropBox;
1439
1486
  output: 'current' | 'new-layer';
1440
1487
  };
1488
+ /**
1489
+ * `contentAwareFill` with the synthesis in the selection worker when there is one, with
1490
+ * `signal` and `onProgress`. The layer is checked again before the result lands.
1491
+ */
1492
+ contentAwareFillAsync(options?: ContentAwareFillOptions & {
1493
+ signal?: AbortSignal;
1494
+ onProgress?: SelectionProgress;
1495
+ }): Promise<{
1496
+ layerId: string;
1497
+ bounds: CropBox;
1498
+ output: 'current' | 'new-layer';
1499
+ }>;
1500
+ /**
1501
+ * The fill without changing anything: the window, its pixels before and after (RGBA, the fill
1502
+ * blended by the selection's coverage) and the sampling area used, for a preview.
1503
+ */
1504
+ previewContentAwareFill(options?: ContentAwareFillOptions & {
1505
+ signal?: AbortSignal;
1506
+ onProgress?: SelectionProgress;
1507
+ }): Promise<{
1508
+ plan: ContentAwareFillPlan;
1509
+ after: Uint8ClampedArray;
1510
+ }>;
1511
+ private synthesiseFill;
1512
+ /**
1513
+ * Checks and gathers what a Content-Aware Fill needs: the selection, the 8-bit pixel layer, the
1514
+ * window around the selection (and the sampling area), and which pixels it may copy from.
1515
+ */
1516
+ prepareContentAwareFill(options?: ContentAwareFillOptions): ContentAwareFillPlan;
1517
+ /** The window's pixels with `filled` blended in by the coverage (`current`), or the fill alone, its alpha by the coverage (`new-layer`). */
1518
+ private blendFill;
1519
+ /** Puts a computed fill into the document as one undo step. */
1520
+ private applyContentAwareFill;
1441
1521
  /** The pixel clipboard (Copy / Cut), or null. */
1442
1522
  private clipboard;
1443
1523
  /** What Copy or Cut last put on the editor's clipboard, or null. */
@@ -1696,6 +1776,8 @@ export declare class ImageEditorController {
1696
1776
  * its alpha.
1697
1777
  */
1698
1778
  private decontaminateLayer;
1779
+ /** `layer`'s surface with Decontaminate Colors applied along `coverage`'s soft edge, colours read from `source`. */
1780
+ private decontaminatedSurface;
1699
1781
  /**
1700
1782
  * Loads a selection from a mask image (an AI segmentation, a saved mask): a data URL / URL or
1701
1783
  * RGBA pixels, by luminance (white = selected) or a channel. Any size; it is resampled.
@@ -1,4 +1,4 @@
1
- import { AdjustmentKind, AdjustmentLayer, AdjustmentParamsMap, Annotation, CreateAnnotationPayload, AspectRatio, CropBox, DepthMaskOptions, ExportOptions, ImageAdjustments, ImageDimensions, ImageEditorFit, ImageEditorOptions, ImageEditorState, ImageEditorTool, ImageTransform, ImagePoint, SerializedImageEditorState } from './types.js';
1
+ import { AdjustmentKind, AdjustmentLayer, AdjustmentParamsMap, Annotation, CreateAnnotationPayload, AspectRatio, CropBox, DepthMaskOptions, ExportOptions, ImageAdjustments, ImageDimensions, ImageEditorFit, ImageEditorOptions, ImageEditorState, ImageEditorTool, ImageTransform, ImagePoint, SerializedImageEditorState, DocumentOpener } from './types.js';
2
2
  import { type PathToSelectionOptions, type SelectionToPathOptions } from './selection/path.js';
3
3
  import { type MagneticEdgeOptions } from './selection/magnetic.js';
4
4
  import type { ObjectTarget } from './selection/segment/grabcut.js';
@@ -168,7 +168,7 @@ export interface FocusAreaCommandOptions extends FocusAreaOptions {
168
168
  sampleAllLayers?: boolean;
169
169
  }
170
170
  /** Where Select and Mask puts its result (Photoshop's Output To). */
171
- export type RefineOutput = 'selection' | 'layer-mask' | 'new-layer' | 'new-layer-with-mask';
171
+ export type RefineOutput = 'selection' | 'layer-mask' | 'new-layer' | 'new-layer-with-mask' | 'new-document' | 'new-document-with-mask';
172
172
  /** What {@link ImageEditorController.refineSelectionTo} made. */
173
173
  export interface RefineOutputResult {
174
174
  output: RefineOutput;
@@ -176,6 +176,8 @@ export interface RefineOutputResult {
176
176
  layerId?: string;
177
177
  /** The layer it made (`new-layer`, `new-layer-with-mask`). */
178
178
  newLayerId?: string;
179
+ /** The id the host's document opener returned (`new-document`, `new-document-with-mask`). */
180
+ documentId?: string;
179
181
  /** How the edge was refined: by colour, or with the segmentation model (object aware). */
180
182
  refineMode: 'color' | 'object';
181
183
  }
@@ -486,6 +488,31 @@ export interface ContentAwareFillOptions {
486
488
  sampleRadius?: number;
487
489
  /** Random seed: the same seed gives the same fill (default 0). */
488
490
  seed?: number;
491
+ /**
492
+ * Where the fill may copy from (natural pixels), instead of the automatic ring around the
493
+ * selection: a mask (the Content-Aware Fill workspace's painted area), an alpha channel, or
494
+ * rectangles. `excludeRects` are never copied from, whichever way the area is given.
495
+ */
496
+ samplingArea?: SelectionMask | null;
497
+ samplingChannelId?: string;
498
+ sampleRects?: CropBox[];
499
+ excludeRects?: CropBox[];
500
+ }
501
+ /** What a Content-Aware Fill works on: the selection's window of a pixel layer (see `prepareContentAwareFill`). */
502
+ export interface ContentAwareFillPlan {
503
+ layerId: string;
504
+ /** The window it fills and samples in (document pixels). */
505
+ window: CropBox;
506
+ /** The selection's bounds. */
507
+ bounds: CropBox;
508
+ /** The layer's pixels in the window, RGBA. */
509
+ before: Uint8ClampedArray;
510
+ /** 1 where the selection covers (the hole), per window pixel. */
511
+ hole: Uint8Array;
512
+ /** The selection's coverage 0..255 per window pixel. */
513
+ coverage: Uint8Array;
514
+ /** 1 where the fill may not copy from, per window pixel (null: everywhere outside the hole). */
515
+ exclude: Uint8Array | null;
489
516
  }
490
517
  /** Pixels on the editor's clipboard: RGBA, and where they were copied from (document pixels). */
491
518
  export interface ClipboardImage extends PixelBuffer {
@@ -691,6 +718,7 @@ export declare class ImageEditorController {
691
718
  /** The segmentation provider behind `selectSubject` (see `setSegmentationProvider`). */
692
719
  private segmentation;
693
720
  private selectionWorker;
721
+ private documentOpener;
694
722
  /** The effects provider slot (see `setEffectsProvider`). */
695
723
  readonly effects: EffectsSlot;
696
724
  /** Renders provider effects: effect smart filter results and effect layers. */
@@ -726,6 +754,24 @@ export declare class ImageEditorController {
726
754
  * A worker that is cancelled or fails is replaced by a fresh one on the next job.
727
755
  */
728
756
  setSelectionWorker(factory: SelectionWorkerFactory | null): void;
757
+ /** Sets (or with `null` removes) how new documents are opened (see `DocumentOpener`). Not an edit. */
758
+ setDocumentOpener(opener: DocumentOpener | null): void;
759
+ /** Whether the host can open new documents (the New Document outputs are available). */
760
+ get canOpenDocuments(): boolean;
761
+ /**
762
+ * A new one-layer document from the selection (or `options.selection`) on a pixel layer
763
+ * (`layerId`, default the active one), the size of this image: the selected pixels on
764
+ * transparency, or with `withMask` the whole layer masked by the selection. This document is
765
+ * not changed. `decontaminate` (0..100) cleans the soft edge's colours as the new-layer
766
+ * outputs do.
767
+ */
768
+ documentFromSelection(options?: {
769
+ layerId?: string;
770
+ withMask?: boolean;
771
+ selection?: SelectionMask | null;
772
+ decontaminate?: number;
773
+ radius?: number;
774
+ }): SerializedLayeredImageEditorState;
729
775
  /** Whether the long selections run in a worker. */
730
776
  get hasSelectionWorker(): boolean;
731
777
  /**
@@ -1431,13 +1477,47 @@ export declare class ImageEditorController {
1431
1477
  * (PatchMatch, as the Spot Healing Brush's content-aware mode), blended by the selection's
1432
1478
  * coverage. `output` `current` paints into the layer; `new-layer` puts the fill on a new layer
1433
1479
  * above it. Samples within `sampleRadius` px of the selection (default its larger side, at
1434
- * least 32). Deterministic for a `seed`. One undo step. 8-bit documents only for now.
1480
+ * least 32), or from the given sampling area. Deterministic for a `seed`. One undo step.
1481
+ * 8-bit documents only for now. Runs here; see `contentAwareFillAsync` for the worker.
1435
1482
  */
1436
1483
  contentAwareFill(options?: ContentAwareFillOptions): {
1437
1484
  layerId: string;
1438
1485
  bounds: CropBox;
1439
1486
  output: 'current' | 'new-layer';
1440
1487
  };
1488
+ /**
1489
+ * `contentAwareFill` with the synthesis in the selection worker when there is one, with
1490
+ * `signal` and `onProgress`. The layer is checked again before the result lands.
1491
+ */
1492
+ contentAwareFillAsync(options?: ContentAwareFillOptions & {
1493
+ signal?: AbortSignal;
1494
+ onProgress?: SelectionProgress;
1495
+ }): Promise<{
1496
+ layerId: string;
1497
+ bounds: CropBox;
1498
+ output: 'current' | 'new-layer';
1499
+ }>;
1500
+ /**
1501
+ * The fill without changing anything: the window, its pixels before and after (RGBA, the fill
1502
+ * blended by the selection's coverage) and the sampling area used, for a preview.
1503
+ */
1504
+ previewContentAwareFill(options?: ContentAwareFillOptions & {
1505
+ signal?: AbortSignal;
1506
+ onProgress?: SelectionProgress;
1507
+ }): Promise<{
1508
+ plan: ContentAwareFillPlan;
1509
+ after: Uint8ClampedArray;
1510
+ }>;
1511
+ private synthesiseFill;
1512
+ /**
1513
+ * Checks and gathers what a Content-Aware Fill needs: the selection, the 8-bit pixel layer, the
1514
+ * window around the selection (and the sampling area), and which pixels it may copy from.
1515
+ */
1516
+ prepareContentAwareFill(options?: ContentAwareFillOptions): ContentAwareFillPlan;
1517
+ /** The window's pixels with `filled` blended in by the coverage (`current`), or the fill alone, its alpha by the coverage (`new-layer`). */
1518
+ private blendFill;
1519
+ /** Puts a computed fill into the document as one undo step. */
1520
+ private applyContentAwareFill;
1441
1521
  /** The pixel clipboard (Copy / Cut), or null. */
1442
1522
  private clipboard;
1443
1523
  /** What Copy or Cut last put on the editor's clipboard, or null. */
@@ -1696,6 +1776,8 @@ export declare class ImageEditorController {
1696
1776
  * its alpha.
1697
1777
  */
1698
1778
  private decontaminateLayer;
1779
+ /** `layer`'s surface with Decontaminate Colors applied along `coverage`'s soft edge, colours read from `source`. */
1780
+ private decontaminatedSurface;
1699
1781
  /**
1700
1782
  * Loads a selection from a mask image (an AI segmentation, a saved mask): a data URL / URL or
1701
1783
  * RGBA pixels, by luminance (white = selected) or a channel. Any size; it is resampled.