@pixerate/editor 0.185.0 → 0.187.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 (40) hide show
  1. package/dist/{chunk-GYYSPMVU.js → chunk-FW7N64XK.js} +295 -188
  2. package/dist/{chunk-C6TRAAG4.cjs → chunk-X2KQQZBT.cjs} +355 -248
  3. package/dist/image-editor/controller.d.cts +89 -0
  4. package/dist/image-editor/controller.d.ts +89 -0
  5. package/dist/image-editor/index.cjs +1602 -1030
  6. package/dist/image-editor/index.js +591 -19
  7. package/dist/image-editor/layers/model.d.cts +5 -1
  8. package/dist/image-editor/layers/model.d.ts +5 -1
  9. package/dist/image-editor/layers/paint-ui.d.cts +2 -1
  10. package/dist/image-editor/layers/paint-ui.d.ts +2 -1
  11. package/dist/image-editor/layers/serialize.d.cts +3 -0
  12. package/dist/image-editor/layers/serialize.d.ts +3 -0
  13. package/dist/image-editor/psd/channels.d.cts +24 -0
  14. package/dist/image-editor/psd/channels.d.ts +24 -0
  15. package/dist/image-editor/psd/export.d.cts +3 -0
  16. package/dist/image-editor/psd/export.d.ts +3 -0
  17. package/dist/image-editor/psd/import.d.cts +10 -0
  18. package/dist/image-editor/psd/import.d.ts +10 -0
  19. package/dist/image-editor/renderer.d.cts +6 -0
  20. package/dist/image-editor/renderer.d.ts +6 -0
  21. package/dist/image-editor/selection/channels.d.cts +52 -0
  22. package/dist/image-editor/selection/channels.d.ts +52 -0
  23. package/dist/image-editor/selection/gesture.d.cts +7 -0
  24. package/dist/image-editor/selection/gesture.d.ts +7 -0
  25. package/dist/image-editor/selection/index.d.cts +2 -0
  26. package/dist/image-editor/selection/index.d.ts +2 -0
  27. package/dist/image-editor/selection/mask-files.d.cts +20 -0
  28. package/dist/image-editor/selection/mask-files.d.ts +20 -0
  29. package/dist/image-editor/selection/overlay.d.cts +2 -0
  30. package/dist/image-editor/selection/overlay.d.ts +2 -0
  31. package/dist/image-editor/tools.d.cts +3 -1
  32. package/dist/image-editor/tools.d.ts +3 -1
  33. package/dist/image-editor/types.d.cts +10 -0
  34. package/dist/image-editor/types.d.ts +10 -0
  35. package/dist/paint-editor/index.cjs +6 -6
  36. package/dist/paint-editor/index.js +1 -1
  37. package/package.json +1 -1
  38. package/skills/pixerate-image-editor/SKILL.md +12 -24
  39. package/skills/pixerate-image-editor/references/painting.md +29 -0
  40. package/skills/pixerate-image-selection-masking/SKILL.md +20 -2
@@ -9,6 +9,7 @@ import { type SelectionModifyOp } from './selection/modify.cjs';
9
9
  import { type SegmentationProvider } from './selection/segmentation.cjs';
10
10
  import { type RefineEdgeParams } from './selection/refine.cjs';
11
11
  import { type LayerMaskProps } from './selection/layer-mask.cjs';
12
+ import { type AlphaChannel } from './selection/channels.cjs';
12
13
  import type { AdjustmentLayerMask } from './types.cjs';
13
14
  import { type LayerBlendMode, type ImageLayer, type LayerFilter, type LayerTarget, type PixelLayer, type RasterMask, type SmartContents, type SmartFilter, type SmartPlacement, type LiveShape, type ShapeFillRule, type ShapeOperation, type ShapePaint, type ShapeStroke, type ParagraphStyle, type TextStyle, type TypeLayer, type ImageEffectAnimation } from './layers/model.cjs';
14
15
  import { type TextLayout, type TextShaper } from './layers/text.cjs';
@@ -112,6 +113,12 @@ export interface SelectionCommandOptions {
112
113
  }
113
114
  /** How the canvas shows the selection: marching ants, a Quick Mask tint, or not at all. */
114
115
  export type SelectionDisplay = 'ants' | 'quickMask' | 'none';
116
+ /** What `exportMaskImage` writes: the selection, an alpha channel or a layer's painted mask. */
117
+ export type MaskImageSource = 'selection' | {
118
+ channelId: string;
119
+ } | {
120
+ layerId: string;
121
+ };
115
122
  /** Where an AI result goes (see `applyInpaintedImage`, `applyBackgroundRemovedImage`). */
116
123
  export interface AIResultOptions {
117
124
  /** `new-layer`: a new layer (inpainting) or a mask (background removal); `replace`: the Background's pixels. Default: by `isMultiLayer`. */
@@ -354,6 +361,8 @@ export interface FillOptions {
354
361
  /** Limit to the selection when there is one (default true). */
355
362
  useSelection?: boolean;
356
363
  }
364
+ /** The `layerId` paint results report for Quick Mask edits (the selection, not a layer). */
365
+ export declare const QUICK_MASK_TARGET = "quick-mask";
357
366
  /** Edit › Stroke (see `strokeSelection`). */
358
367
  export interface StrokeSelectionOptions extends Omit<FillOptions, 'useSelection'> {
359
368
  /** Width of the band in pixels (0 < width ≤ 250). */
@@ -1445,6 +1454,29 @@ export declare class ImageEditorController {
1445
1454
  threshold?: number;
1446
1455
  mode?: SelectionMode;
1447
1456
  }): Promise<SelectionMask | null>;
1457
+ /**
1458
+ * Loads a mask image (a data URL / URL or RGBA pixels, any size, resampled) into a new alpha
1459
+ * channel, read like `loadSelectionFromImage`. The selection does not change. One undo step.
1460
+ */
1461
+ loadChannelFromImage(source: string | PixelBuffer, options?: {
1462
+ name?: string;
1463
+ channel?: SelectionChannel;
1464
+ invert?: boolean;
1465
+ threshold?: number;
1466
+ }): Promise<AlphaChannel>;
1467
+ /**
1468
+ * A full-size greyscale PNG (white = selected / revealed) of the selection, an alpha channel or
1469
+ * a layer's painted mask, as a data URL; `invert` swaps black and white, `maxSide` scales it
1470
+ * down. Encoded in code, so it works without a canvas. Throws when the source is missing.
1471
+ */
1472
+ exportMaskImage(source: MaskImageSource, options?: {
1473
+ invert?: boolean;
1474
+ maxSide?: number;
1475
+ }): {
1476
+ width: number;
1477
+ height: number;
1478
+ dataUrl: string;
1479
+ };
1448
1480
  /** A mask image (data URL / URL, or pixels as they are) as RGBA pixels. */
1449
1481
  private decodeMaskImage;
1450
1482
  /**
@@ -1474,6 +1506,61 @@ export declare class ImageEditorController {
1474
1506
  * it (the selection still applies). View state: no undo step, not saved.
1475
1507
  */
1476
1508
  setSelectionDisplay(display: SelectionDisplay): void;
1509
+ /** The alpha channels (saved selections), in panel order. */
1510
+ getChannels(): readonly AlphaChannel[];
1511
+ getChannel(id: string): AlphaChannel | null;
1512
+ private requireChannel;
1513
+ private setChannels;
1514
+ private newChannelId;
1515
+ /**
1516
+ * Select › Save Selection: a new alpha channel (`name`, default "Alpha n") holding the
1517
+ * selection, or with `channelId` the selection combined into that channel by `mode` (replace,
1518
+ * add, subtract, intersect). One undo step. Throws without a selection.
1519
+ */
1520
+ saveSelection(options?: {
1521
+ channelId?: string;
1522
+ name?: string;
1523
+ mode?: SelectionMode;
1524
+ }): AlphaChannel;
1525
+ /** Appends a new channel holding `mask` (canvas-sized) as one undo step. */
1526
+ private addChannel;
1527
+ /**
1528
+ * Select › Load Selection from an alpha channel (inverted with `invert`), combined with the
1529
+ * selection by `mode`. One undo step.
1530
+ */
1531
+ loadSelectionFromChannel(id: string, options?: {
1532
+ mode?: SelectionMode;
1533
+ invert?: boolean;
1534
+ }): boolean;
1535
+ /** Changes a channel's name, overlay colour, opacity, what it indicates or visibility (one undo step). */
1536
+ setChannelProperties(id: string, props: Partial<Pick<AlphaChannel, 'name' | 'color' | 'opacity' | 'indicates' | 'visible'>>): AlphaChannel;
1537
+ /** Deletes an alpha channel (one undo step). */
1538
+ deleteChannel(id: string): void;
1539
+ /** Duplicates an alpha channel just after it (one undo step). Returns the copy. */
1540
+ duplicateChannel(id: string, name?: string): AlphaChannel;
1541
+ /** Channel summaries (no pixels) for panels and agents. */
1542
+ describeChannels(): {
1543
+ bounds: CropBox | null;
1544
+ percent: number;
1545
+ id: string;
1546
+ name: string;
1547
+ color: string;
1548
+ opacity: number;
1549
+ indicates: "masked" | "selected";
1550
+ visible: boolean;
1551
+ }[];
1552
+ /** Whether Quick Mask mode is on (painting edits the selection). */
1553
+ get quickMaskEditing(): boolean;
1554
+ /**
1555
+ * Quick Mask mode (Q): on, the selection shows as a tint and painting, fills and strokes that
1556
+ * name no layer edit the selection itself (white selects, black deselects, grey partly);
1557
+ * off, it shows as marching ants again. View state: no undo step (the edits are).
1558
+ */
1559
+ setQuickMaskMode(on: boolean): void;
1560
+ /** The selection as a 1-channel surface to paint in Quick Mask mode. */
1561
+ private quickMaskSurface;
1562
+ /** The selection a painted Quick Mask surface stands for (`rects` changed since `base`). */
1563
+ private selectionFromSurface;
1477
1564
  private maskFromSelection;
1478
1565
  /**
1479
1566
  * Adds the selection as the layer's mask (Reveal Selection), replacing any mask, as one undo
@@ -1490,6 +1577,8 @@ export declare class ImageEditorController {
1490
1577
  * with `invert`. False without a painted mask (a depth mask is computed, not painted).
1491
1578
  */
1492
1579
  selectionFromLayerMask(layerId: string, mode?: SelectionMode, invert?: boolean): boolean;
1580
+ /** A layer's painted mask over the canvas as a selection mask; null without one (or for a depth mask). */
1581
+ private layerMaskCoverage;
1493
1582
  /**
1494
1583
  * Histogram of the last rendered preview (after adjustments and layers, before annotations),
1495
1584
  * or `null` before the first render or without canvas pixel access.
@@ -9,6 +9,7 @@ import { type SelectionModifyOp } from './selection/modify.js';
9
9
  import { type SegmentationProvider } from './selection/segmentation.js';
10
10
  import { type RefineEdgeParams } from './selection/refine.js';
11
11
  import { type LayerMaskProps } from './selection/layer-mask.js';
12
+ import { type AlphaChannel } from './selection/channels.js';
12
13
  import type { AdjustmentLayerMask } from './types.js';
13
14
  import { type LayerBlendMode, type ImageLayer, type LayerFilter, type LayerTarget, type PixelLayer, type RasterMask, type SmartContents, type SmartFilter, type SmartPlacement, type LiveShape, type ShapeFillRule, type ShapeOperation, type ShapePaint, type ShapeStroke, type ParagraphStyle, type TextStyle, type TypeLayer, type ImageEffectAnimation } from './layers/model.js';
14
15
  import { type TextLayout, type TextShaper } from './layers/text.js';
@@ -112,6 +113,12 @@ export interface SelectionCommandOptions {
112
113
  }
113
114
  /** How the canvas shows the selection: marching ants, a Quick Mask tint, or not at all. */
114
115
  export type SelectionDisplay = 'ants' | 'quickMask' | 'none';
116
+ /** What `exportMaskImage` writes: the selection, an alpha channel or a layer's painted mask. */
117
+ export type MaskImageSource = 'selection' | {
118
+ channelId: string;
119
+ } | {
120
+ layerId: string;
121
+ };
115
122
  /** Where an AI result goes (see `applyInpaintedImage`, `applyBackgroundRemovedImage`). */
116
123
  export interface AIResultOptions {
117
124
  /** `new-layer`: a new layer (inpainting) or a mask (background removal); `replace`: the Background's pixels. Default: by `isMultiLayer`. */
@@ -354,6 +361,8 @@ export interface FillOptions {
354
361
  /** Limit to the selection when there is one (default true). */
355
362
  useSelection?: boolean;
356
363
  }
364
+ /** The `layerId` paint results report for Quick Mask edits (the selection, not a layer). */
365
+ export declare const QUICK_MASK_TARGET = "quick-mask";
357
366
  /** Edit › Stroke (see `strokeSelection`). */
358
367
  export interface StrokeSelectionOptions extends Omit<FillOptions, 'useSelection'> {
359
368
  /** Width of the band in pixels (0 < width ≤ 250). */
@@ -1445,6 +1454,29 @@ export declare class ImageEditorController {
1445
1454
  threshold?: number;
1446
1455
  mode?: SelectionMode;
1447
1456
  }): Promise<SelectionMask | null>;
1457
+ /**
1458
+ * Loads a mask image (a data URL / URL or RGBA pixels, any size, resampled) into a new alpha
1459
+ * channel, read like `loadSelectionFromImage`. The selection does not change. One undo step.
1460
+ */
1461
+ loadChannelFromImage(source: string | PixelBuffer, options?: {
1462
+ name?: string;
1463
+ channel?: SelectionChannel;
1464
+ invert?: boolean;
1465
+ threshold?: number;
1466
+ }): Promise<AlphaChannel>;
1467
+ /**
1468
+ * A full-size greyscale PNG (white = selected / revealed) of the selection, an alpha channel or
1469
+ * a layer's painted mask, as a data URL; `invert` swaps black and white, `maxSide` scales it
1470
+ * down. Encoded in code, so it works without a canvas. Throws when the source is missing.
1471
+ */
1472
+ exportMaskImage(source: MaskImageSource, options?: {
1473
+ invert?: boolean;
1474
+ maxSide?: number;
1475
+ }): {
1476
+ width: number;
1477
+ height: number;
1478
+ dataUrl: string;
1479
+ };
1448
1480
  /** A mask image (data URL / URL, or pixels as they are) as RGBA pixels. */
1449
1481
  private decodeMaskImage;
1450
1482
  /**
@@ -1474,6 +1506,61 @@ export declare class ImageEditorController {
1474
1506
  * it (the selection still applies). View state: no undo step, not saved.
1475
1507
  */
1476
1508
  setSelectionDisplay(display: SelectionDisplay): void;
1509
+ /** The alpha channels (saved selections), in panel order. */
1510
+ getChannels(): readonly AlphaChannel[];
1511
+ getChannel(id: string): AlphaChannel | null;
1512
+ private requireChannel;
1513
+ private setChannels;
1514
+ private newChannelId;
1515
+ /**
1516
+ * Select › Save Selection: a new alpha channel (`name`, default "Alpha n") holding the
1517
+ * selection, or with `channelId` the selection combined into that channel by `mode` (replace,
1518
+ * add, subtract, intersect). One undo step. Throws without a selection.
1519
+ */
1520
+ saveSelection(options?: {
1521
+ channelId?: string;
1522
+ name?: string;
1523
+ mode?: SelectionMode;
1524
+ }): AlphaChannel;
1525
+ /** Appends a new channel holding `mask` (canvas-sized) as one undo step. */
1526
+ private addChannel;
1527
+ /**
1528
+ * Select › Load Selection from an alpha channel (inverted with `invert`), combined with the
1529
+ * selection by `mode`. One undo step.
1530
+ */
1531
+ loadSelectionFromChannel(id: string, options?: {
1532
+ mode?: SelectionMode;
1533
+ invert?: boolean;
1534
+ }): boolean;
1535
+ /** Changes a channel's name, overlay colour, opacity, what it indicates or visibility (one undo step). */
1536
+ setChannelProperties(id: string, props: Partial<Pick<AlphaChannel, 'name' | 'color' | 'opacity' | 'indicates' | 'visible'>>): AlphaChannel;
1537
+ /** Deletes an alpha channel (one undo step). */
1538
+ deleteChannel(id: string): void;
1539
+ /** Duplicates an alpha channel just after it (one undo step). Returns the copy. */
1540
+ duplicateChannel(id: string, name?: string): AlphaChannel;
1541
+ /** Channel summaries (no pixels) for panels and agents. */
1542
+ describeChannels(): {
1543
+ bounds: CropBox | null;
1544
+ percent: number;
1545
+ id: string;
1546
+ name: string;
1547
+ color: string;
1548
+ opacity: number;
1549
+ indicates: "masked" | "selected";
1550
+ visible: boolean;
1551
+ }[];
1552
+ /** Whether Quick Mask mode is on (painting edits the selection). */
1553
+ get quickMaskEditing(): boolean;
1554
+ /**
1555
+ * Quick Mask mode (Q): on, the selection shows as a tint and painting, fills and strokes that
1556
+ * name no layer edit the selection itself (white selects, black deselects, grey partly);
1557
+ * off, it shows as marching ants again. View state: no undo step (the edits are).
1558
+ */
1559
+ setQuickMaskMode(on: boolean): void;
1560
+ /** The selection as a 1-channel surface to paint in Quick Mask mode. */
1561
+ private quickMaskSurface;
1562
+ /** The selection a painted Quick Mask surface stands for (`rects` changed since `base`). */
1563
+ private selectionFromSurface;
1477
1564
  private maskFromSelection;
1478
1565
  /**
1479
1566
  * Adds the selection as the layer's mask (Reveal Selection), replacing any mask, as one undo
@@ -1490,6 +1577,8 @@ export declare class ImageEditorController {
1490
1577
  * with `invert`. False without a painted mask (a depth mask is computed, not painted).
1491
1578
  */
1492
1579
  selectionFromLayerMask(layerId: string, mode?: SelectionMode, invert?: boolean): boolean;
1580
+ /** A layer's painted mask over the canvas as a selection mask; null without one (or for a depth mask). */
1581
+ private layerMaskCoverage;
1493
1582
  /**
1494
1583
  * Histogram of the last rendered preview (after adjustments and layers, before annotations),
1495
1584
  * or `null` before the first render or without canvas pixel access.