@pixerate/editor 0.101.0 → 0.103.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 (67) hide show
  1. package/THIRD_PARTY_NOTICES.md +2 -0
  2. package/dist/agent/index.cjs +7 -7
  3. package/dist/agent/index.cjs.map +1 -1
  4. package/dist/agent/index.js +7 -7
  5. package/dist/canvas/index.cjs +3 -3
  6. package/dist/canvas/index.cjs.map +1 -1
  7. package/dist/canvas/index.js +4 -4
  8. package/dist/{chunk-WIR377F6.js → chunk-67FRIOPZ.js} +15 -12
  9. package/dist/chunk-67FRIOPZ.js.map +1 -0
  10. package/dist/chunk-6BU5WU4R.cjs +1 -0
  11. package/dist/chunk-6BU5WU4R.cjs.map +1 -0
  12. package/dist/{chunk-IB53LVGV.js → chunk-DS7KDKPX.js} +1 -1
  13. package/dist/chunk-NQLQ2JOI.js +7176 -0
  14. package/dist/chunk-NQLQ2JOI.js.map +1 -0
  15. package/dist/{chunk-ZZOTHJ4K.cjs → chunk-PV42JITT.cjs} +1 -1
  16. package/dist/{chunk-ZZOTHJ4K.cjs.map → chunk-PV42JITT.cjs.map} +1 -1
  17. package/dist/chunk-VSMM7B3P.cjs +7176 -0
  18. package/dist/chunk-VSMM7B3P.cjs.map +1 -0
  19. package/dist/{chunk-WT6ZAWJP.cjs → chunk-WSTEXEKD.cjs} +27 -24
  20. package/dist/chunk-WSTEXEKD.cjs.map +1 -0
  21. package/dist/chunk-XYBJKUAU.js +1 -0
  22. package/dist/chunk-XYBJKUAU.js.map +1 -0
  23. package/dist/compositor-B1ZrKR89.d.ts +835 -0
  24. package/dist/compositor-CTMU-B1t.d.cts +835 -0
  25. package/dist/export-BLpMyCYg.d.ts +3139 -0
  26. package/dist/export-X9rY79p0.d.cts +3139 -0
  27. package/dist/homography-CZ-tFjay.d.cts +50 -0
  28. package/dist/homography-Ctfjoc1b.d.ts +50 -0
  29. package/dist/image-editor/index.cjs +3889 -8657
  30. package/dist/image-editor/index.cjs.map +1 -1
  31. package/dist/image-editor/index.d.cts +224 -2723
  32. package/dist/image-editor/index.d.ts +224 -2723
  33. package/dist/image-editor/index.js +3326 -8094
  34. package/dist/image-editor/index.js.map +1 -1
  35. package/dist/mixer-DG_9Yu2W.d.ts +282 -0
  36. package/dist/mixer-DGcH6HLu.d.cts +282 -0
  37. package/dist/paint/index.cjs +4 -3
  38. package/dist/paint/index.cjs.map +1 -1
  39. package/dist/paint/index.d.cts +3 -281
  40. package/dist/paint/index.d.ts +3 -281
  41. package/dist/paint/index.js +2 -1
  42. package/dist/paint-editor/index.cjs +3330 -0
  43. package/dist/paint-editor/index.cjs.map +1 -0
  44. package/dist/paint-editor/index.d.cts +1233 -0
  45. package/dist/paint-editor/index.d.ts +1233 -0
  46. package/dist/paint-editor/index.js +3330 -0
  47. package/dist/paint-editor/index.js.map +1 -0
  48. package/dist/raster/index.cjs +2 -2
  49. package/dist/raster/index.d.cts +6 -827
  50. package/dist/raster/index.d.ts +6 -827
  51. package/dist/raster/index.js +1 -1
  52. package/dist/{surface-DIA-XatS.d.cts → surface-AfHCH7BR.d.cts} +1 -1
  53. package/dist/{surface-DIA-XatS.d.ts → surface-AfHCH7BR.d.ts} +1 -1
  54. package/dist/tools/index.cjs +3 -3
  55. package/dist/tools/index.cjs.map +1 -1
  56. package/dist/tools/index.js +3 -3
  57. package/dist/vector/index.d.cts +2 -1
  58. package/dist/vector/index.d.ts +2 -1
  59. package/dist/{warp-B8rAguzs.d.ts → warp-CWHZzE3x.d.ts} +2 -49
  60. package/dist/{warp-nYs2DPrx.d.cts → warp-D5jz_tN7.d.cts} +2 -49
  61. package/package.json +6 -1
  62. package/skills/README.md +1 -0
  63. package/skills/pixerate-image-editor/SKILL.md +69 -11
  64. package/skills/pixerate-paint-editor/SKILL.md +162 -0
  65. package/dist/chunk-WIR377F6.js.map +0 -1
  66. package/dist/chunk-WT6ZAWJP.cjs.map +0 -1
  67. /package/dist/{chunk-IB53LVGV.js.map → chunk-DS7KDKPX.js.map} +0 -0
@@ -1,2707 +1,34 @@
1
- import { RasterLayerBase, RasterMask as RasterMask$1, RasterPixelLayer, GroupBlendMode, LayerLocation as LayerLocation$1, LayerLocks, LayerEffect, GlobalLight, LayerEffects, EffectPattern, RasterSources, RasterCompositor, CompositorOptions, LayerEffectKind, Interpolation } from '../raster/index.js';
2
- export { BevelContour, BevelEmbossEffect, BevelStyle, BevelTechnique, BevelTexture, ColorOverlayEffect, CompositeCallOptions, CompositeStats, ContourPoint, DEFAULT_GLOBAL_LIGHT, DIRECT_GAUSSIAN_MAX_SIGMA, DecodedPng, DropShadowEffect, EffectContour, EffectFill, EffectGradient, EffectPatternRef, EffectRect, GlowTechnique, GradientColorStop, GradientOpacityStop, GradientOverlayEffect, GradientStyle, INTERPOLATIONS, InnerGlowEffect, InnerShadowEffect, LAYER_EFFECT_KINDS, LayerEffectError, MAX_EFFECT_REACH, MAX_TRANSFORM_PIXELS, OuterGlowEffect, PatternOverlayEffect, PatternPlacement, PatternTile, ResampleOptions, SatinEffect, StrokeEffect, StrokePosition, TransformTooLargeError, ZlibError, adler32, base64ToBytes, blendTile, builtinPattern, builtinPatternIds, bytesToBase64, changedTiles, compositeSurfaceOver, curveLut, decodePng, defaultEffectGradient, defaultLayerEffect, deflate, deflateRaw, effectColorHex, effectReach, effectsFingerprint, effectsMargin, effectsScale, encodePng, findLayer, flattenLayers, gaussianBlur, hasActiveEffects, hashNoise, inflate, inflateRaw, insertLayer, isInterpolation, isLayerEffectKind, isLayerLocked, isPng, keysWeight, layerEffectFields, layerEffectLabel, mapLayer, mergeLayerEffect, newEffectId, normalizeLayerEffects, parseDataUrl, parseEffectColor, pngDataUrl, reduceSurface, renderLayerEffects, scaleLayerEffect, transformSurface, transformedBounds, validateEffectGradient, validateLayerEffect, validateLayerEffects, warpSurface } from '../raster/index.js';
3
- import { P as PixelSurface, T as TiledSurface, B as BlendMode } from '../surface-DIA-XatS.js';
4
- export { a as BLEND_MODES, b as BlendModeInfo, M as MaskSurface, R as RasterRect, c as Rgb, d as Rgba, S as SurfaceDraft, e as TILE, f as TILE_SHIFT, g as Tile, h as TileKey, i as blendChannel, j as blendImageData, k as blendLum, l as blendPixel, m as blendRgb, n as canvasCompositeOperation, o as collectTiles, p as contentBounds, q as emptySurface, r as fillRect, s as finishTile, t as isBlendMode, u as isSeparableBlendMode, v as mixPigment8, w as mixPigmentRgb, x as normalizeBlendMode, y as packRgba, z as readPixel, A as readRegion, C as setLum, D as solidSurface, E as surfaceBytes, F as surfaceFromPixels, G as surfacesEqual, H as tileCoord, I as tileKey, J as tileRect, K as tilesInRect, L as translateSurface, N as uniformTile, O as writeRegion } from '../surface-DIA-XatS.js';
5
- import { BrushSettings, MixerSettings, MixerLoad, StrokeCoverage, MixerTarget, MixerStroke, StrokeApply, StrokePoint } from '../paint/index.js';
6
- export { CoverageMap, DEFAULT_BRUSH, DEFAULT_MIXER, Dab, DabWalker, EMPTY_MIXER_LOAD, MAX_BRUSH_SIZE, MIXER_DRAIN, MIXER_PICKUP_RATE, MIXING_MODELS, MixingModel, PIGMENT_BANDS, PIGMENT_LAMBDA_MIN, PIGMENT_LAMBDA_STEP, PIGMENT_WAVELENGTHS, Pigment, PigmentOptions, PigmentRgb, applyStrokeToTile, cleanMixer, coverageTileCoord, createPigment, createPigmentTools, dabCoverage, dabRect, lerpPigment, lerpPigmentInto, loadMixer, mixPigments, normalizeBrush, normalizeMixer, rasterizeDab, reflectanceToRgb, rgbToReflectance, setPigmentColor, smoothPoints, tipFalloff, tipReach, tipShape, walkDabs } from '../paint/index.js';
7
- import { Q as Quad, a as WarpMesh, V as Vec2, A as AffineMatrix, H as Homography, W as WarpStyle } from '../types-CwMPoRMU.js';
8
- import { b as WarpPreset } from '../warp-B8rAguzs.js';
9
- export { W as WARP_STYLES, a as WARP_STYLE_LABELS, c as applyHomography, B as boxQuad, d as dragWarpMeshPoint, e as evalWarpMesh, C as homographyFromAffine, l as homographyFromPoints, q as identityWarpMesh, D as invertHomography, p as pullWarpMesh, E as rectToQuad, h as resizeWarpMesh, u as warpMeshEditPoints, v as warpMeshGridCurves, x as warpMeshParamAt, A as warpPresetMesh } from '../warp-B8rAguzs.js';
1
+ import { a as ImageAdjustments, D as DepthMaskOptions, b as SerializedImageEditorState, A as AdjustmentKind, c as AdjustmentLayer, d as AdjustmentParamsMap, e as AdjustmentLayerMask, f as AdjustmentLayerOf, C as CurvePoint, H as HueRange, L as LevelsChannel, g as ImageEditorController, h as SelectionMask, i as SelectionMode, j as ColorDistance, R as RefineEdgeParams, k as ImagePoint, l as ImageLayer, m as CropBox, n as RasterMask, o as Annotation, p as AdjustmentLayerNode, q as AnnotationLayer, r as LayerFilter, s as PixelLayer, t as DevelopFilter, u as ImageTransform, v as ImageHistogram, w as ImageProjection, x as CompositorSources, y as LayerCompositor, z as SmartFilterStack, B as SmartFilter, E as SmartObjectLayer, F as SmartContents, G as SmartDocument, J as SmartPlacement, K as FreeTransformGeometry, M as LayerPlacement, N as FreeTransformMode, O as FreeTransformResult, Q as FreeTransformSession, T as FreeTransformInit, U as TransformAnchor } from '../export-BLpMyCYg.js';
2
+ export { V as AIResultOptions, W as AdjustmentLayerBase, X as AdjustmentLayerInit, Y as AdjustmentLayerUpdate, Z as AnnotationPlacement, _ as AnnotationType, $ as ArrowAnnotation, a0 as AspectRatio, a1 as BaseAnnotation, a2 as BlackWhiteParams, a3 as BlurFilter, a4 as CircleAnnotation, a5 as ColorBalanceParams, a6 as ColorBalanceTone, a7 as ColorRangeOptions, a8 as ColorRangeSample, a9 as CreateAnnotationPayload, aa as CropHandle, ab as CurvesParams, ac as DEFAULT_ADJUSTMENTS, ad as DEFAULT_DEPTH_MASK, ae as DEFAULT_REFINE_EDGE_PARAMS, af as DEFAULT_TRANSFORM, ag as DeserializeContext, ah as DevelopSettings, ai as EMPTY_DISTANCE, aj as ExportOptions, ak as FREE_TRANSFORM_CONTENTS, al as FREE_TRANSFORM_MODES, am as FillOptions, an as FreeTransformContent, ao as FreeTransformHost, ap as FreeTransformPreview, aq as GUIDED_FILTER_EPS, ar as GroupLayer, as as HISTOGRAM_BINS, at as HistogramChannel, au as HistoryEntryHandle, av as HueSaturationParams, aw as IMAGE_EDITOR_SCHEMA_VERSION, ax as ImageAnnotation, ay as ImageDimensions, az as ImageEditorAIHooks, I as ImageEditorAssetStore, aA as ImageEditorFit, aB as ImageEditorOptions, aC as ImageEditorRenderer, aD as ImageEditorState, aE as ImageEditorTool, aF as ImageLayerType, aG as InpaintHook, aH as InpaintOptions, aI as InvertParams, aJ as LAYERED_SCHEMA_VERSION, aK as LayerBase, aL as LayerBlendMode, aM as LayerFilterKind, aN as LayerLocation, aO as LayerMaskProps, aP as LayerOperationError, aQ as LayerProperties, aR as LayerSourcesHost, aS as LayerTarget, aT as LegacySerializedImageEditorState, aU as LevelsParams, aV as LineAnnotation, aW as MagicWandOptions, aX as MixerStrokeInit, aY as PSD_BLEND_KEYS, aZ as PaintOptions, a_ as PaintStrokeResult, a$ as PaintStrokeSession, b0 as PenAnnotation, b1 as PhotoFilterParams, b2 as PixelBuffer, b3 as PixelLayerInit, b4 as PosterizeParams, b5 as PsdChannel, b6 as PsdExportInput, P as PsdExportResult, b7 as PsdFile, b8 as PsdHeader, b9 as PsdImportOptions, ba as PsdImportResult, bb as PsdLayerMask, bc as PsdLayerRecord, bd as PsdLayerSummary, be as PsdRect, bf as PsdResource, bg as PsdSmartFilter, bh as PsdTaggedBlock, bi as PsdTreeNode, bj as RectAnnotation, bk as RemoveBackgroundHook, bl as RemoveBackgroundOptions, bm as RenderOptions, bn as SELECTION_MODES, bo as SELECTION_MODIFY_OPS, bp as SampleOptions, bq as SelectionChannel, br as SelectionCommandOptions, bs as SelectionModifyOp, bt as SerializeContext, bu as SerializedAdjustmentLayer, bv as SerializedAnnotationLayer, bw as SerializedGroupLayer, S as SerializedLayer, bx as SerializedLayerEffects, by as SerializedLayeredImageEditorState, bz as SerializedPattern, bA as SerializedPixelLayer, bB as SerializedRasterMask, bC as SerializedSelection, bD as SerializedSmartContents, bE as SerializedSmartFilter, bF as SerializedSmartObjectLayer, bG as ShapeSelectionOptions, bH as SmartFilterKind, bI as SmartObjectInfo, bJ as SmartPsdData, bK as StrokeInit, bL as StrokeTool, bM as TONE_RANGE_PRESETS, bN as TRANSFORM_ANCHORS, bO as TextAnnotation, bP as ThresholdParams, bQ as ToneRangePreset, bR as TransformParams, bS as TransformReadout, bT as VibranceParams, bU as ViewportMetrics, bV as addLayerEffect, bW as addLayerFilter, bX as adjustmentNodeAsLayer, bY as anchorPoint, bZ as applyImageProjectionToContext, b_ as applyParams, b$ as blurFilter, c0 as borderCoverage, c1 as boxMean, c2 as boxPointOf, c3 as buildLayerMaskPlanes, c4 as calculateCropDrag, c5 as canvasToImagePoint, c6 as clampCropToImage, c7 as colorRange, c8 as combineSelections, c9 as computeHistogram, ca as computeSelectionBounds, cb as contractCoverage, cc as cornersFromMatrix, cd as coverageToByte, ce as createSelectionMask, cf as decodeLayerChannel, cg as decodeLayerMask, ch as decodeMergedImage, ci as decodePngDataUrl, cj as decodeSelectionRle, ck as depthMaskAlpha, cl as describeTransform, cm as deserializeEffects, cn as deserializeLayer, co as deserializeLayers, cp as deserializePatterns, cq as deserializeSelection, cr as developFilter, cs as distanceTransform, ct as duplicateLayer, cu as edgeWidth, cv as ellipsePoints, cw as ellipseSelection, cx as encodeSelectionRle, cy as encodeSurface, cz as expandCoverage, cA as exportPsd, cB as featherCoverage, cC as flipCorners, cD as fullSelection, cE as geometryHomography, cF as getAnnotationBounds, cG as getCropCursor, cH as getRotatedSize, cI as getViewportMetrics, cJ as getViewportProjection, cK as globalImageCache, cL as greyMorphology, cM as groupLayers, cN as guidePlanes, cO as guidedFilterColor, cP as hasSurface, cQ as hasWarp, cR as hashMaskContent, cS as histogramPath, cT as hitTestAnnotation, cU as hitTestCrop, cV as hueRange, cW as identityTransform, cX as imageToCanvasPoint, cY as importPsd, cZ as invertSelection, c_ as isActiveFilter, c$ as isIdentityTransform, d0 as isQuarterTurnSwapped, d1 as isSelectionEmpty, d2 as isSelectionMode, d3 as isSpatialFilter, d4 as isTransformAnchor, d5 as isValidWarp, d6 as layerEffectsOf, d7 as layerMaskCoverage, d8 as layerMaskFromSelection, d9 as layerMaskKey, da as layerName, db as layerTree, dc as layerTypeLabel, dd as magicWand, de as mapCropHandle, df as matrixFromCorners, dg as matrixFromParams, dh as migrateSerializedImageEditorState, di as migrateToLayeredState, dj as modifySelection, dk as moveLayer, dl as newLayerId, dm as normalizeAngle, dn as normalizeFilter, dp as normalizeLayerMask, dq as normalizeRect, dr as normalizeRefineEdgeParams, ds as normalizeStoredAdjustments, dt as offsetLayer, du as parseBlend, dv as parseColor, dw as parseSelectionMode, dx as pixelLayerBounds, dy as pixelLayers, dz as placeLayer, dA as polygonCoverage, dB as polygonSelection, dC as presetWarp, dD as previewStep, dE as projectImagePoint, dF as projectImageRect, dG as projectMaskCoverage, dH as psdToLayers, dI as readPsd, dJ as rectSelection, dK as referencePoint, dL as refineCoverage, dM as refineEdgeHalo, dN as refineSelection, dO as removeLayer, dP as removeLayerEffect, dQ as removeLayerFilter, dR as requireLayer, dS as requireUnlocked, dT as resizePixels, dU as resizeSelection, dV as resolveExternalAssets, dW as runLayerFilters, dX as selectionArea, dY as selectionFromCoverage, dZ as selectionFromPixels, d_ as selectionToCoverage, d$ as selectionToPixels, e0 as selectionValueAt, e1 as serializeContents, e2 as serializeEffects, e3 as serializeLayer, e4 as serializeLayers, e5 as serializeLayersExternal, e6 as serializePatterns, e7 as serializeSelection, e8 as setLayerEffects, e9 as setLayerEffectsEnabled, ea as setLayerMask, eb as setLayerProperties, ec as shiftCoverage, ed as smartObjectLayers, ee as smoothCoverage, ef as srgb8ToLab, eg as toHex, eh as toneRange, ei as transformHomography, ej as transformMap, ek as transformedBox, el as transformedPoint, em as ungroupLayer, en as unionRect, eo as unprojectCanvasPoint, ep as updateLayerEffect, eq as updateLayerFilter, er as updateLayerMaskProps, es as withNewIds, et as writePsd } from '../export-BLpMyCYg.js';
10
3
  import { b as LoadReport, J as JsonObject, f as MigrationStep } from '../migrate-iTlm3a8h.js';
4
+ import { B as BlendMode, P as PixelSurface, R as RasterRect } from '../surface-AfHCH7BR.js';
5
+ export { c as BLEND_MODES, d as BlendModeInfo, M as MaskSurface, e as Rgb, f as Rgba, S as SurfaceDraft, g as TILE, h as TILE_SHIFT, b as Tile, T as TileKey, a as TiledSurface, i as blendChannel, j as blendImageData, k as blendLum, l as blendPixel, m as blendRgb, n as canvasCompositeOperation, o as collectTiles, p as contentBounds, q as emptySurface, r as fillRect, s as finishTile, t as isBlendMode, u as isSeparableBlendMode, v as mixPigment8, w as mixPigmentRgb, x as normalizeBlendMode, y as packRgba, z as readPixel, A as readRegion, C as setLum, D as solidSurface, E as surfaceBytes, F as surfaceFromPixels, G as surfacesEqual, H as tileCoord, I as tileKey, J as tileRect, K as tilesInRect, L as translateSurface, N as uniformTile, O as writeRegion } from '../surface-AfHCH7BR.js';
11
6
  import { a as AgentToolProvider, A as AgentTool } from '../registry-D-4fit9C.js';
7
+ import { j as LayerEffects, l as LayerEffectKind, i as LayerEffect, E as EffectPattern, I as Interpolation } from '../compositor-B1ZrKR89.js';
8
+ export { B as BevelContour, m as BevelEmbossEffect, n as BevelStyle, o as BevelTechnique, p as BevelTexture, q as ColorOverlayEffect, r as CompositeCallOptions, s as CompositeStats, k as CompositorOptions, t as ContourPoint, D as DEFAULT_GLOBAL_LIGHT, u as DropShadowEffect, v as EffectContour, w as EffectFill, x as EffectGradient, y as EffectPatternRef, g as GlobalLight, z as GlowTechnique, A as GradientColorStop, F as GradientOpacityStop, H as GradientOverlayEffect, J as GradientStyle, K as INTERPOLATIONS, M as InnerGlowEffect, N as InnerShadowEffect, O as LAYER_EFFECT_KINDS, P as LayerEffectError, L as LayerLocks, Q as MAX_EFFECT_REACH, S as MAX_TRANSFORM_PIXELS, T as OuterGlowEffect, U as PatternOverlayEffect, V as PatternPlacement, W as PatternTile, X as ResampleOptions, Y as SatinEffect, Z as StrokeEffect, _ as StrokePosition, $ as TransformTooLargeError, a0 as blendTile, a1 as builtinPattern, a2 as builtinPatternIds, a3 as changedTiles, a4 as compositeSurfaceOver, a5 as defaultEffectGradient, a6 as defaultLayerEffect, a7 as effectColorHex, a8 as effectReach, a9 as effectsFingerprint, aa as effectsMargin, ab as effectsScale, ac as findLayer, ad as flattenLayers, ae as hasActiveEffects, af as hashNoise, ag as insertLayer, ah as isInterpolation, ai as isLayerEffectKind, aj as isLayerLocked, ak as keysWeight, al as layerEffectFields, am as layerEffectLabel, an as mapLayer, ao as mergeLayerEffect, ap as newEffectId, aq as normalizeLayerEffects, ar as parseEffectColor, as as reduceSurface, at as scaleLayerEffect, au as transformSurface, av as transformedBounds, aw as validateEffectGradient, ax as validateLayerEffect, ay as validateLayerEffects, az as warpSurface } from '../compositor-B1ZrKR89.js';
12
9
  import { b as CaptureSurface } from '../capture-wwNGaW05.js';
10
+ export { DIRECT_GAUSSIAN_MAX_SIGMA, DecodedPng, EffectRect, ZlibError, adler32, base64ToBytes, bytesToBase64, curveLut, decodePng, deflate, deflateRaw, encodePng, gaussianBlur, inflate, inflateRaw, isPng, parseDataUrl, pngDataUrl, renderLayerEffects } from '../raster/index.js';
11
+ import { a as MixerLoad, M as MixerSettings } from '../mixer-DG_9Yu2W.js';
12
+ export { B as BrushSettings, C as CoverageMap, g as DEFAULT_BRUSH, h as DEFAULT_MIXER, D as Dab, i as DabWalker, E as EMPTY_MIXER_LOAD, b as MAX_BRUSH_SIZE, j as MIXER_DRAIN, k as MIXER_PICKUP_RATE, l as MIXING_MODELS, e as MixerStroke, d as MixerTarget, m as MixingModel, f as StrokeApply, c as StrokeCoverage, S as StrokePoint, n as applyStrokeToTile, o as cleanMixer, p as coverageTileCoord, q as dabCoverage, r as dabRect, s as loadMixer, t as normalizeBrush, u as normalizeMixer, v as rasterizeDab, w as smoothPoints, x as tipFalloff, y as tipReach, z as tipShape, A as walkDabs } from '../mixer-DG_9Yu2W.js';
13
+ export { PIGMENT_BANDS, PIGMENT_LAMBDA_MIN, PIGMENT_LAMBDA_STEP, PIGMENT_WAVELENGTHS, Pigment, PigmentOptions, PigmentRgb, createPigment, createPigmentTools, lerpPigment, lerpPigmentInto, mixPigments, reflectanceToRgb, rgbToReflectance, setPigmentColor } from '../paint/index.js';
14
+ import { W as WarpStyle, a as WarpMesh, V as Vec2, Q as Quad } from '../types-CwMPoRMU.js';
15
+ export { A as AffineMatrix, H as Homography } from '../types-CwMPoRMU.js';
16
+ export { a as applyHomography, c as boxQuad, d as homographyFromAffine, h as homographyFromPoints, i as invertHomography, r as rectToQuad } from '../homography-Ctfjoc1b.js';
17
+ export { a as WARP_STYLES, b as WARP_STYLE_LABELS, W as WarpPreset, d as dragWarpMeshPoint, e as evalWarpMesh, j as identityWarpMesh, p as pullWarpMesh, g as resizeWarpMesh, l as warpMeshEditPoints, n as warpMeshGridCurves, o as warpMeshParamAt, u as warpPresetMesh } from '../warp-CWHZzE3x.js';
13
18
  import '../schema-Di0CS6Pe.js';
14
19
 
15
- /**
16
- * A selection: one 8-bit coverage value per image pixel (0 = not selected, 255 = fully
17
- * selected), row-major over the whole source image in natural pixels — the same space as the
18
- * crop box and annotations. Soft values are partial selection (feathered or anti-aliased edges).
19
- *
20
- * Treat a mask as immutable: every operation returns a new one, so history entries can share
21
- * them without copying.
22
- */
23
- interface SelectionMask {
24
- readonly width: number;
25
- readonly height: number;
26
- readonly data: Uint8Array;
27
- /** Bounding box of the non-zero coverage, or `null` when nothing is selected. */
28
- readonly bounds: CropBox | null;
29
- }
30
- /** How a new selection combines with the current one. */
31
- type SelectionMode = 'replace' | 'add' | 'subtract' | 'intersect';
32
- declare const SELECTION_MODES: readonly SelectionMode[];
33
- declare function isSelectionMode(value: unknown): value is SelectionMode;
34
- /** Parses `replace|add|subtract|intersect`; anything else is `replace`. */
35
- declare function parseSelectionMode(value: unknown): SelectionMode;
36
- /** RGBA pixels, 8 bits per channel, straight alpha (an `ImageData` qualifies). */
37
- interface PixelBuffer {
38
- width: number;
39
- height: number;
40
- data: ArrayLike<number>;
41
- }
42
- /** Serialized selection: a run-length encoding of the 8-bit coverage. */
43
- interface SerializedSelection {
44
- width: number;
45
- height: number;
46
- /** `r1:` + base64 of (value byte, LEB128 run length) pairs. */
47
- rle: string;
48
- }
49
- /** Bounding box of non-zero bytes. */
50
- declare function computeSelectionBounds(width: number, height: number, data: ArrayLike<number>): CropBox | null;
51
- /** Wraps coverage bytes (taken over, not copied) as a selection, computing its bounds. */
52
- declare function createSelectionMask(width: number, height: number, data?: Uint8Array): SelectionMask;
53
- /** Select › All. */
54
- declare function fullSelection(width: number, height: number): SelectionMask;
55
- declare function isSelectionEmpty(mask: SelectionMask | null | undefined): boolean;
56
- /** Coverage at a pixel, 0..1 (0 outside the image). */
57
- declare function selectionValueAt(mask: SelectionMask, x: number, y: number): number;
58
- /** 8-bit value of a coverage (clamped and rounded; NaN → 0). */
59
- declare function coverageToByte(v: number): number;
60
- /** A selection from 0..1 coverage. */
61
- declare function selectionFromCoverage(width: number, height: number, coverage: ArrayLike<number>): SelectionMask;
62
- /** The selection's coverage as 0..1 floats. */
63
- declare function selectionToCoverage(mask: SelectionMask): Float32Array;
64
- /** Number of fully-or-partly selected pixels, weighted by coverage (Σ coverage). */
65
- declare function selectionArea(mask: SelectionMask | null | undefined): number;
66
- /**
67
- * Combines `next` with `prev` by `mode` (8-bit, exact: combining a mask with itself is a no-op).
68
- * Add is the maximum, Subtract `max(prev − next, 0)`, Intersect the minimum. A missing `prev`
69
- * reads as nothing selected. Returns `null` when nothing remains selected.
70
- */
71
- declare function combineSelections(prev: SelectionMask | null | undefined, next: SelectionMask, mode: SelectionMode): SelectionMask | null;
72
- /** Select › Inverse. */
73
- declare function invertSelection(mask: SelectionMask): SelectionMask;
74
- /** Bilinear resample to another size (e.g. an AI mask returned at a different resolution). */
75
- declare function resizeSelection(mask: SelectionMask, width: number, height: number): SelectionMask;
76
- type SelectionChannel = 'alpha' | 'luminance' | 'red' | 'green' | 'blue';
77
- /**
78
- * A selection from an image: by default its luminance (white = selected, the usual convention
79
- * of segmentation masks), or one channel. Partly transparent pixels count as black for
80
- * luminance, so a mask PNG with transparency works either way.
81
- */
82
- declare function selectionFromPixels(pixels: PixelBuffer, options?: {
83
- channel?: SelectionChannel;
84
- invert?: boolean;
85
- threshold?: number;
86
- }): SelectionMask;
87
- /** The selection as RGBA pixels: grey (white = selected, opaque) or white with coverage as alpha. */
88
- declare function selectionToPixels(mask: SelectionMask, as?: 'gray' | 'alpha'): {
89
- width: number;
90
- height: number;
91
- data: Uint8ClampedArray;
92
- };
93
- /** Run-length encodes coverage bytes: `r1:` + base64 of (value, LEB128 run length) pairs. */
94
- declare function encodeSelectionRle(data: Uint8Array): string;
95
- /** Decodes {@link encodeSelectionRle}; throws unless the runs cover exactly `length` bytes. */
96
- declare function decodeSelectionRle(rle: string, length: number): Uint8Array;
97
- declare function serializeSelection(mask: SelectionMask): SerializedSelection;
98
- /** Restores a {@link SerializedSelection}; throws on damaged data. */
99
- declare function deserializeSelection(value: unknown): SelectionMask;
100
- /** A short, stable hash of a string or bytes (FNV-1a, 32-bit, hex) for cache keys. */
101
- declare function hashMaskContent(content: string | Uint8Array): string;
102
-
103
- /**
104
- * The image editor's layer stack: pixel, adjustment, group and annotation layers in one ordered
105
- * tree (bottom to top), all in document space (natural pixels of the document).
106
- *
107
- * Layer objects are immutable. Every change builds new objects along the path from the root to
108
- * the changed layer and shares everything else, so undo history, the compositor's caches and
109
- * serialization can compare layers by identity.
110
- */
111
-
112
- /** Blend modes of a layer; groups also accept `pass-through`. */
113
- type LayerBlendMode = GroupBlendMode;
114
-
115
- /**
116
- * A layer mask (see the raster module's `RasterMask`) whose parametric `source` is a depth map:
117
- * a depth mask is generated from it instead of painted, and its surface is unused.
118
- */
119
- type RasterMask = RasterMask$1<DepthMaskOptions>;
120
- interface LayerBase extends RasterLayerBase {
121
- mask?: RasterMask;
122
- }
123
- /** The base sliders of the old document-level adjustments, as a filter on one layer. */
124
- interface DevelopSettings {
125
- brightness: number;
126
- contrast: number;
127
- saturation: number;
128
- exposure: number;
129
- temperature: number;
130
- tint?: number;
131
- /** Rendering process (see `ImageAdjustments.process`). */
132
- process?: 1 | 2;
133
- }
134
- type DevelopFilter = {
135
- id: string;
136
- kind: 'develop';
137
- enabled: boolean;
138
- } & DevelopSettings;
139
- /** Box blur of `radius` pixels (the old `adjustments.blur`), clamped at the canvas edges. */
140
- interface BlurFilter {
141
- id: string;
142
- kind: 'blur';
143
- enabled: boolean;
144
- radius: number;
145
- }
146
- type LayerFilter = DevelopFilter | BlurFilter;
147
- type LayerFilterKind = LayerFilter['kind'];
148
- interface PixelLayer extends LayerBase, Omit<RasterPixelLayer, keyof RasterLayerBase> {
149
- /** Live filters, applied bottom (first) to top before the mask and blend. */
150
- filters?: LayerFilter[];
151
- /**
152
- * `'document'`: the pixels are the document's source image, unmodified (the Background of an
153
- * opened image). Such a layer's `surface` is a placeholder; read its pixels through the
154
- * controller. Painting it drops the flag.
155
- */
156
- source?: 'document';
157
- }
158
- type AdjustmentLayerNode<K extends AdjustmentKind = AdjustmentKind> = {
159
- [P in K]: LayerBase & {
160
- type: 'adjustment';
161
- kind: P;
162
- params: AdjustmentParamsMap[P];
163
- };
164
- }[K];
165
- interface GroupLayer extends Omit<LayerBase, 'blend'> {
166
- type: 'group';
167
- blend: LayerBlendMode;
168
- /** Bottom to top. */
169
- children: ImageLayer[];
170
- /** UI only. */
171
- collapsed?: boolean;
172
- }
173
- /** One annotation (pen, shape, arrow, text, image) as a layer, drawn by the annotation renderer. */
174
- interface AnnotationLayer extends LayerBase {
175
- type: 'annotation';
176
- annotation: Annotation;
177
- }
178
- type ImageLayer = PixelLayer | AdjustmentLayerNode | GroupLayer | AnnotationLayer;
179
- type ImageLayerType = ImageLayer['type'];
180
- /** Which part of the active layer painting targets. */
181
- type LayerTarget = 'pixels' | 'mask';
182
- /** A fresh id with `prefix` (`layer`, `flt`, …). */
183
- declare function newLayerId(prefix?: string): string;
184
- type LayerLocation = LayerLocation$1<ImageLayer>;
185
-
186
- /** The top-level and nested pixel layers. */
187
- declare function pixelLayers(layers: readonly ImageLayer[]): PixelLayer[];
188
- /** The develop filter of a pixel layer, if any. */
189
- declare function developFilter(layer: PixelLayer): DevelopFilter | undefined;
190
- declare function blurFilter(layer: PixelLayer): BlurFilter | undefined;
191
- /** True for filters that change pixels (enabled, non-neutral). */
192
- declare function isActiveFilter(f: LayerFilter): boolean;
193
- /** True when a filter needs neighbouring pixels (it can't run tile by tile). */
194
- declare function isSpatialFilter(f: LayerFilter): boolean;
195
- /** Document-space bounds of a pixel layer's stored tiles, or `null`. */
196
- declare function pixelLayerBounds(layer: PixelLayer, surface?: PixelSurface): CropBox | null;
197
- /** Human label of a layer kind. */
198
- declare function layerTypeLabel(type: ImageLayerType): string;
199
-
200
- /**
201
- * Schema version 3 of the image editor document: the layer tree, with pixel layers and painted
202
- * masks stored as PNG assets (cropped to their content and placed by position), plus the
203
- * document-level crop, transform, output opacity, migrated blur and selection.
204
- *
205
- * Encoding is synchronous and exact (see `png.ts`). Each surface's encoding is memoised, so
206
- * saving an unchanged layer again costs nothing.
207
- */
208
-
209
- declare const LAYERED_SCHEMA_VERSION: 3;
210
- /** A stored raster mask. Pixels: `asset` (grey PNG) placed at `x`, `y`; elsewhere `defaultValue`. */
211
- interface SerializedRasterMask {
212
- defaultValue: 0 | 255;
213
- asset?: string;
214
- x?: number;
215
- y?: number;
216
- density?: number;
217
- feather?: number;
218
- enabled?: boolean;
219
- /** `false`: unlinked from the layer's pixels. */
220
- linked?: boolean;
221
- source?: DepthMaskOptions;
222
- }
223
- interface SerializedLayerBase {
224
- id: string;
225
- name: string;
226
- visible: boolean;
227
- opacity: number;
228
- blend: string;
229
- clipped?: boolean;
230
- mask?: SerializedRasterMask;
231
- locks?: LayerLocks;
232
- effects?: SerializedLayerEffects;
233
- }
234
- /** A layer's effects: the effect list as JSON plus the PSD block they came from (base64). */
235
- interface SerializedLayerEffects {
236
- enabled: boolean;
237
- scale?: number;
238
- items: LayerEffect[];
239
- psd?: {
240
- key: string;
241
- data: string;
242
- };
243
- }
244
- interface SerializedPixelLayer extends SerializedLayerBase {
245
- type: 'pixel';
246
- /** Asset id of the pixels (RGBA PNG) placed at `x`, `y` in layer space; missing when empty. */
247
- asset?: string;
248
- x?: number;
249
- y?: number;
250
- offset: {
251
- x: number;
252
- y: number;
253
- };
254
- fillOpacity?: number;
255
- filters?: LayerFilter[];
256
- /** `'document'`: the pixels are the document's source image (no asset is stored). */
257
- source?: 'document';
258
- }
259
- interface SerializedAdjustmentLayer extends SerializedLayerBase {
260
- type: 'adjustment';
261
- kind: string;
262
- params: unknown;
263
- }
264
- interface SerializedGroupLayer extends SerializedLayerBase {
265
- type: 'group';
266
- children: SerializedLayer[];
267
- collapsed?: boolean;
268
- }
269
- interface SerializedAnnotationLayer extends SerializedLayerBase {
270
- type: 'annotation';
271
- annotation: Annotation;
272
- }
273
- type SerializedLayer = SerializedPixelLayer | SerializedAdjustmentLayer | SerializedGroupLayer | SerializedAnnotationLayer;
274
- /** A version 3 document (layers). */
275
- interface SerializedLayeredImageEditorState {
276
- version: 3;
277
- /** Canvas size in pixels. */
278
- width: number;
279
- height: number;
280
- /** Bottom to top. */
281
- layers: SerializedLayer[];
282
- /** Asset id → PNG data URL (or an external reference, see `ImageEditorAssetStore`). */
283
- assets: Record<string, string>;
284
- activeLayerId: string | null;
285
- crop: CropBox | null;
286
- transform: ImageTransform;
287
- /** Export alpha, 0..1. */
288
- opacity: number;
289
- /** Blur migrated from a v1 / v2 document with adjustment layers (runs after the layers). */
290
- legacyOutputBlur?: number;
291
- selection?: SerializedSelection;
292
- /** Global light for layer effects (missing = 120°, 30°). */
293
- globalLight?: GlobalLight;
294
- /** The document's patterns for pattern effects, each an RGBA PNG data URL. */
295
- patterns?: SerializedPattern[];
296
- }
297
- interface SerializedPattern {
298
- id: string;
299
- name: string;
300
- png: string;
301
- }
302
- declare function serializePatterns(patterns: readonly EffectPattern[]): SerializedPattern[];
303
- /** Reads stored patterns, skipping (and reporting in `problems`) any that cannot be decoded. */
304
- declare function deserializePatterns(raw: unknown, problems?: string[]): EffectPattern[];
305
- interface EncodedSurface {
306
- url: string;
307
- x: number;
308
- y: number;
309
- }
310
- /** The surface's content (non-default pixels) as a PNG data URL and its position, or `null`. */
311
- declare function encodeSurface(surface: TiledSurface): EncodedSurface | null;
312
- interface SerializeContext {
313
- /** Adds an asset and returns its id. */
314
- addAsset(url: string, hint: string): string;
315
- }
316
- declare function serializeEffects(effects: LayerEffects): SerializedLayerEffects;
317
- /** Reads stored effects (leniently: broken effects are dropped), or `undefined`. */
318
- declare function deserializeEffects(raw: unknown): LayerEffects | undefined;
319
- declare function serializeLayer(layer: ImageLayer, ctx: SerializeContext): SerializedLayer;
320
- /** Serializes a layer tree with inline assets (asset ids are derived from layer ids). */
321
- declare function serializeLayers(layers: readonly ImageLayer[]): {
322
- layers: SerializedLayer[];
323
- assets: Record<string, string>;
324
- };
325
- /**
326
- * Where a host keeps layer pixels outside the JSON (`toJSON({ assets: 'external', store })`):
327
- * `put` stores a PNG and returns a reference (a URL, a key) that `get` resolves later.
328
- */
329
- interface ImageEditorAssetStore {
330
- put(blob: Blob, info: {
331
- id: string;
332
- width: number;
333
- height: number;
334
- }): Promise<string>;
335
- get(ref: string): Promise<Blob>;
336
- }
337
- /**
338
- * Serializes a layer tree with its assets in `store`: each PNG is uploaded once per store (by
339
- * content), and `assets` maps asset ids to the store's references.
340
- */
341
- declare function serializeLayersExternal(layers: readonly ImageLayer[], store: ImageEditorAssetStore): Promise<{
342
- layers: SerializedLayer[];
343
- assets: Record<string, string>;
344
- }>;
345
- /**
346
- * Turns external asset references back into data URLs through `store.get` (data URLs pass through),
347
- * so the document loads like an inline one. References that fail are reported and left out.
348
- */
349
- declare function resolveExternalAssets(assets: Record<string, string>, store: ImageEditorAssetStore | undefined, problems: string[]): Promise<Record<string, string>>;
350
- interface DeserializeContext {
351
- assets: Record<string, string>;
352
- /** Decodes an asset (PNG data URL by default). Throw for an unusable asset. */
353
- decodeAsset?(ref: string, channels: 1 | 4): {
354
- width: number;
355
- height: number;
356
- data: ArrayLike<number>;
357
- };
358
- /** Problems found while reading (unknown kinds, broken assets); the rest still loads. */
359
- problems: string[];
360
- }
361
- /** Decodes a PNG data URL into pixels of `channels` bytes each. */
362
- declare function decodePngDataUrl(url: string, channels: 1 | 4): {
363
- width: number;
364
- height: number;
365
- data: Uint8ClampedArray;
366
- };
367
- declare function deserializeLayer(raw: unknown, ctx: DeserializeContext): ImageLayer | null;
368
- /** Reads a stored layer tree (layers that cannot be read are dropped and reported). */
369
- declare function deserializeLayers(raw: unknown, ctx: DeserializeContext): ImageLayer[];
370
-
371
- /** Display bins of a histogram. */
372
- declare const HISTOGRAM_BINS = 256;
373
- interface ImageHistogram {
374
- /** 256-bin counts per channel. */
375
- red: Uint32Array;
376
- green: Uint32Array;
377
- blue: Uint32Array;
378
- /** 256-bin counts of Rec.709 luma `round(0.2126 R + 0.7152 G + 0.0722 B)` of the encoded values. */
379
- luminance: Uint32Array;
380
- /** Visible pixels counted (alpha > 0). Each counts once, partially transparent ones included. */
381
- samples: number;
382
- /** Fully transparent pixels, excluded from every bin. */
383
- transparent: number;
384
- /** Per channel (R, G, B): visible pixels at exactly 0. */
385
- shadows: [number, number, number];
386
- /** Per channel (R, G, B): visible pixels at exactly 255. */
387
- highlights: [number, number, number];
388
- /** Largest bin count over R, G, B and luminance (for scaling a plot). */
389
- max: number;
390
- }
391
- interface PixelSource {
392
- data: ArrayLike<number>;
393
- width?: number;
394
- height?: number;
395
- }
396
- /**
397
- * Per-channel and luminance histograms of straight 8-bit RGBA pixels (an `ImageData` or anything
398
- * with `data`), with clipping counts at the exact endpoints. Transparent pixels cannot add
399
- * phantom peaks: they are counted separately and excluded.
400
- */
401
- declare function computeHistogram(imageData: PixelSource): ImageHistogram;
402
- type HistogramChannel = 'red' | 'green' | 'blue' | 'luminance';
403
- /**
404
- * An SVG path (`M … Z`) of one channel scaled into a `width` × `height` box, bins left to right,
405
- * counts up from the bottom. `scale: 'sqrt'` (default) keeps small populations visible.
406
- */
407
- declare function histogramPath(histogram: ImageHistogram, channel: HistogramChannel, width: number, height: number, options?: {
408
- scale?: 'linear' | 'sqrt';
409
- max?: number;
410
- }): string;
411
-
412
- /**
413
- * The image editor's compositor: the raster engine (`@pixerate/editor/raster`) with the photo
414
- * layer kinds plugged in. Adjustment layers filter what is below them (a run of adjacent ones is
415
- * one float pass with one rounding at the end, exactly as `applyAdjustmentLayers` does, so a
416
- * document migrated from adjustment layers renders identically); annotation layers are drawn by
417
- * the host; pixel layers can carry develop and blur filters; masks can be depth masks.
418
- */
419
-
420
- /** What the compositor needs from its host besides the layers. */
421
- interface CompositorSources extends RasterSources {
422
- /** The pixels of a pixel layer (resolves layers whose pixels are the document source). */
423
- surfaceOf?(layer: PixelLayer): PixelSurface;
424
- /**
425
- * A parametric mask's depth map as RGBA at canvas size (the red channel is the depth), or
426
- * `null` while it is unavailable (the mask then reveals everything).
427
- */
428
- depthMap?(source: DepthMaskOptions): {
429
- width: number;
430
- height: number;
431
- data: ArrayLike<number>;
432
- } | null;
433
- /** Draws one annotation into RGBA for `rect` (canvas hosts only); `null` when unavailable. */
434
- rasterizeAnnotation?(annotation: Annotation, rect: CropBox): Uint8ClampedArray | null;
435
- }
436
- /** The `AdjustmentLayer` shape `applyAdjustmentLayers` evaluates, for a node (memoised). */
437
- declare function adjustmentNodeAsLayer(node: AdjustmentLayerNode): AdjustmentLayer;
438
- /** Evaluates a depth mask (see `applyDepthMask`) into one coverage byte per depth sample. */
439
- declare function depthMaskAlpha(depth: number, options: DepthMaskOptions): number;
440
- /** The per-tile compositor for image editor layer stacks (see the raster module for the caches). */
441
- declare class LayerCompositor extends RasterCompositor<ImageLayer, CompositorSources> {
442
- constructor(options?: CompositorOptions);
443
- }
444
-
445
- interface RenderOptions {
446
- viewportWidth?: number;
447
- viewportHeight?: number;
448
- showCropOverlay?: boolean;
449
- showSelectionOverlay?: boolean;
450
- interactive?: boolean;
451
- draftAnnotation?: Annotation | null;
452
- draftCrop?: CropBox | null;
453
- /** Viewport fit mode: 'contain' scales to full viewport bounds; 'margin' scales to 85% with 1.0 cap (default). */
454
- fit?: ImageEditorFit;
455
- /**
456
- * How the active selection is shown: marching ants (default when there is a selection),
457
- * a Quick Mask tint over the unselected area (default when `state.quickMask`), or not at all.
458
- */
459
- selectionDisplay?: 'ants' | 'quickMask' | 'none';
460
- /** Dash offset of the marching ants in screen pixels (animate it to make them march). */
461
- antsOffset?: number;
462
- /** A selection being drawn (e.g. a lasso), shown as a dashed outline in natural pixels. */
463
- draftSelectionPath?: ImagePoint[] | null;
464
- /** Document rectangles that are the only change since the last render (strokes); recomposites only there. */
465
- dirty?: CropBox[];
466
- /** The layer being edited: tiles keep a checkpoint below it so strokes and drags on it start there. */
467
- checkpointLayerId?: string | null;
468
- /** The paint tools' cursor: a circle of `diameter` px at (`x`, `y`) in natural pixels. */
469
- brushCursor?: {
470
- x: number;
471
- y: number;
472
- diameter: number;
473
- } | null;
474
- /** Free Transform's frame, handles and reference point in natural pixels (`FreeTransformTool.overlay()`). */
475
- freeTransform?: {
476
- outline: ImagePoint[];
477
- handles: ImagePoint[];
478
- reference: ImagePoint;
479
- /** Warp mode: the mesh's grid lines as cubics, its anchors, and handles with their anchors. */
480
- warp?: {
481
- curves: ImagePoint[][];
482
- anchors: ImagePoint[];
483
- handles: Array<{
484
- point: ImagePoint;
485
- anchor: ImagePoint;
486
- }>;
487
- };
488
- } | null;
489
- }
490
- /**
491
- * Image Cache to avoid refetching HTMLImageElement objects repeatedly during re-renders.
492
- */
493
- declare class ImageCache {
494
- private cache;
495
- get(src: string): Promise<HTMLImageElement>;
496
- set(src: string, img: HTMLImageElement): void;
497
- /** The loaded image for `src`, or `undefined` while it is not loaded yet. */
498
- peek(src: string): HTMLImageElement | undefined;
499
- clear(): void;
500
- }
501
- declare const globalImageCache: ImageCache;
502
- /**
503
- * Renders an image with all its transformations, filters, depth masks, and annotations
504
- * to a target HTMLCanvasElement.
505
- */
506
- declare class ImageEditorRenderer {
507
- imageCache: ImageCache;
508
- private cachedBaseCanvas;
509
- private cachedBaseKey;
510
- /**
511
- * Histogram of the last viewport base render (after adjustments and layers, before
512
- * annotations); `null` until a render with pixel access has happened.
513
- */
514
- previewHistogram: ImageHistogram | null;
515
- /** Called whenever the viewport base image is re-rendered with the new histogram. */
516
- onPreviewHistogram?: (histogram: ImageHistogram | null) => void;
517
- private sourceIds;
518
- private nextSourceId;
519
- /**
520
- * The viewport's compositor. It only ever composites the viewport's stack, so its tile cache can
521
- * trust dirty rectangles; exports use `exportCompositor`.
522
- */
523
- compositor: LayerCompositor;
524
- private exportCompositor;
525
- /** How the host resolves layer pixels (set by the controller). */
526
- layerSources?: LayerSourcesHost;
527
- /**
528
- * Debug / test switch: `'legacy'` forces the old base path for documents that still have the
529
- * v1 / v2 shape, `'layers'` forces the compositor. Default: chosen per document.
530
- */
531
- baseRoute: 'auto' | 'legacy' | 'layers';
532
- /** Which path the last base render took. */
533
- lastBaseRoute: 'legacy' | 'layers' | null;
534
- private comp;
535
- private depthMaps;
536
- private assetVersion;
537
- private scratch;
538
- private cachedPostCanvas;
539
- private cachedPostKey;
540
- private cachedPostHistogram;
541
- /**
542
- * Helper to create a canvas element safely in browser/JSDOM.
543
- */
544
- createCanvas(width: number, height: number): HTMLCanvasElement;
545
- /**
546
- * Renders the editor state onto a canvas (viewport or preview).
547
- */
548
- renderToCanvas(targetCanvas: HTMLCanvasElement, imageSource: CanvasImageSource | string, state: ImageEditorState, options?: RenderOptions): Promise<void>;
549
- /**
550
- * Draws `region` of the source image with rotation/flip applied, then pixel adjustments
551
- * and the depth mask (which receives the identical transform so it stays aligned).
552
- */
553
- private renderBaseImage;
554
- /** Which base path renders `state` (see `needsLegacyBase`). */
555
- private chooseRoute;
556
- /** Compositor sources for a `width × height` canvas: layer pixels, depth maps and annotation rasterizing. */
557
- compositorSources(width: number, height: number): CompositorSources;
558
- /** Loads what the compositor reads synchronously: depth maps (at canvas size) and annotation images. */
559
- /** Loads depth maps and annotation images the compositor reads synchronously. */
560
- prepareLayerAssets(layers: readonly ImageLayer[], width: number, height: number): Promise<void>;
561
- /** Whether annotation layers can be rasterized here (a 2D canvas with pixel access). */
562
- canRasterize(): boolean;
563
- /** One annotation drawn into a tile-sized RGBA buffer at `rect` (document space), or `null` without a canvas. */
564
- private rasterizeAnnotation;
565
- private putTile;
566
- /**
567
- * Brings the viewport's composite canvas (document space, covering `region`) up to date,
568
- * uploading only the tiles that changed since the last render.
569
- */
570
- private updateComposite;
571
- /**
572
- * The base canvas of a layered document: the composite drawn through the base projection (crop,
573
- * rotation, flips at scale 1), then output opacity and the migrated blur, which run in the output
574
- * frame. Cached until the composite or those settings change.
575
- */
576
- private layeredBase;
577
- /** Output opacity then the migrated blur, in place on a base canvas; returns its histogram. */
578
- private applyPost;
579
- private publishHistogram;
580
- private quickMaskCache;
581
- private outlineCache;
582
- /** Rubylith over the unselected area, drawn in natural image space. */
583
- private drawQuickMask;
584
- /** Marching ants: a white line under a black dashed one, one screen pixel wide. */
585
- private drawAnts;
586
- private drawDraftPath;
587
- private getSourceId;
588
- /**
589
- * Draws an individual annotation onto the canvas.
590
- */
591
- drawAnnotation(ctx: CanvasRenderingContext2D, ann: Annotation): Promise<void>;
592
- /**
593
- * Scalar fallback for blend modes the canvas cannot composite (Photoshop soft light, linear /
594
- * vivid / pin light, hard mix, subtract, divide, darker / lighter colour, linear burn / dodge):
595
- * draws the annotation on a same-size layer with the same transform, blends it into a copy of
596
- * the target's pixels with `blendImageData`, and copies the result back inside the current clip.
597
- */
598
- private drawAnnotationBlended;
599
- private drawAnnotationContent;
600
- /** Draws an annotation synchronously; an image annotation draws `img` (skipped when `null`). */
601
- drawAnnotationShape(ctx: CanvasRenderingContext2D, ann: Annotation, img: CanvasImageSource | null): void;
602
- /**
603
- * Draws selection box around active annotation.
604
- */
605
- private drawAnnotationSelection;
606
- /** @deprecated Use the standalone `getAnnotationBounds` from the geometry module. */
607
- getAnnotationBounds(ann: Annotation): {
608
- x: number;
609
- y: number;
610
- width: number;
611
- height: number;
612
- };
613
- /**
614
- * Draws a rule-of-thirds crop grid overlay. All rectangles come from
615
- * `getViewportMetrics`, i.e. the crop box projected through rotation/flip.
616
- */
617
- private drawCropOverlay;
618
- private drawFittedImage;
619
- /**
620
- * Performs an export render at exact pixel dimensions without zoom/pan viewport offsets.
621
- */
622
- renderExport(imageSource: CanvasImageSource | string, state: ImageEditorState, options?: ExportOptions): Promise<HTMLCanvasElement>;
623
- /**
624
- * Generates a strictly binary mask canvas (white = area to regenerate, black = keep) in
625
- * natural image pixel space of the current source image — the same space the crop box
626
- * and annotations are stored in. Pair it with `toSourceDataURL()` for AI inpainting.
627
- */
628
- renderMask(state: ImageEditorState, options?: {
629
- useAnnotations?: boolean;
630
- useCrop?: boolean;
631
- useSelection?: boolean;
632
- }): Promise<HTMLCanvasElement>;
633
- private drawAnnotationMask;
634
- }
635
- /** What the renderer asks its host (the controller) about layer pixels. */
636
- interface LayerSourcesHost {
637
- surfaceOf(layer: PixelLayer): PixelSurface;
638
- sourceIsOpaque(): boolean;
639
- version(): string;
640
- /** The document's global light for layer effects. */
641
- globalLight?(): GlobalLight | undefined;
642
- /** A document pattern for pattern effects (built-in patterns are found without it). */
643
- pattern?(id: string): EffectPattern | null;
644
- }
645
-
646
- interface ShapeSelectionOptions {
647
- /** Partial coverage along the edge (default true). */
648
- antiAlias?: boolean;
649
- }
650
- /**
651
- * Even-odd polygon coverage over a `width × height` image: exact horizontal coverage on 4
652
- * sub-rows per pixel row (1 without anti-aliasing, where a pixel is in when its centre is).
653
- * Each sub-row only tests the edges that cross it (an active edge list over edges sorted by
654
- * their top), so the cost is about pixels + edges × rows they span.
655
- */
656
- declare function polygonCoverage(points: readonly ImagePoint[], width: number, height: number, antiAlias?: boolean): Float32Array;
657
- /** Lasso / polygonal lasso: an even-odd polygon in natural image pixels. */
658
- declare function polygonSelection(width: number, height: number, points: readonly ImagePoint[], options?: ShapeSelectionOptions): SelectionMask;
659
- /** Normalises a rectangle with a negative width or height. */
660
- declare function normalizeRect(rect: CropBox): CropBox;
661
- /** Rectangular marquee. Fractional edges get partial coverage when anti-aliased. */
662
- declare function rectSelection(width: number, height: number, rect: CropBox, options?: ShapeSelectionOptions): SelectionMask;
663
- /** The ellipse inscribed in `rect` as a polygon fine enough that its chords stay within 0.05 px. */
664
- declare function ellipsePoints(rect: CropBox): ImagePoint[];
665
- /** Elliptical marquee inscribed in `rect`. */
666
- declare function ellipseSelection(width: number, height: number, rect: CropBox, options?: ShapeSelectionOptions): SelectionMask;
667
-
668
- /** How the magic wand measures colour difference. */
669
- type ColorDistance = 'rgb' | 'perceptual';
670
- interface MagicWandOptions {
671
- /**
672
- * 0..255. `rgb`: the largest per-channel difference in levels (alpha included), as
673
- * Photoshop's wand. `perceptual`: CIE76 ΔE*ab, with 255 ≙ ΔE 100. Default 32.
674
- */
675
- tolerance?: number;
676
- /** Only the 4-connected region around the seed (default true); otherwise every similar pixel. */
677
- contiguous?: boolean;
678
- /** Soft one-pixel fringe on the edge (default true). */
679
- antiAlias?: boolean;
680
- /** Default `rgb`. */
681
- distance?: ColorDistance;
682
- }
683
- /** CIE Lab (D65) of an 8-bit sRGB colour. */
684
- declare function srgb8ToLab(r: number, g: number, b: number): [number, number, number];
685
- /**
686
- * Magic wand: pixels similar to the seed pixel. Contiguous mode is a scanline span fill with an
687
- * explicit stack (fill a run, then scan the rows above and below it for new runs), so it is
688
- * linear in the pixels visited and never recurses. An empty selection when the seed is outside.
689
- */
690
- declare function magicWand(pixels: PixelBuffer, seed: ImagePoint, options?: MagicWandOptions): SelectionMask;
691
- /** One Color Range sample: a colour (0..255 levels or `#rrggbb`) and, optionally, where it was picked. */
692
- interface ColorRangeSample {
693
- color: readonly [number, number, number] | string;
694
- at?: ImagePoint;
695
- }
696
- interface ColorRangeOptions {
697
- /** 0..200 levels (default 40): coverage falls off linearly to 0 at `fuzziness + 1` levels. */
698
- fuzziness?: number;
699
- /**
700
- * Localized Color Clusters: a sample with a position also fades with distance from it,
701
- * reaching 0 at this many pixels.
702
- */
703
- localized?: number;
704
- }
705
- /**
706
- * Select › Color Range › Sampled Colors: each pixel takes its best match over the samples; a
707
- * match falls off linearly with the largest per-channel difference, `1 − d / (fuzziness + 1)`.
708
- * Transparent pixels are never selected.
709
- */
710
- declare function colorRange(pixels: PixelBuffer, samples: readonly ColorRangeSample[], options?: ColorRangeOptions): SelectionMask;
711
- type ToneRangePreset = 'shadows' | 'midtones' | 'highlights';
712
- /** Luma bounds (0..255, Rec. 601) of the tonal presets. */
713
- declare const TONE_RANGE_PRESETS: Record<ToneRangePreset, [number, number]>;
714
- /**
715
- * Select › Color Range › Shadows / Midtones / Highlights: pixels whose luma lies in `lo..hi` are
716
- * selected; outside, selection falls off linearly to 0 over `falloff` levels.
717
- */
718
- declare function toneRange(pixels: PixelBuffer, range: ToneRangePreset | readonly [number, number], falloff?: number): SelectionMask;
719
- /**
720
- * Select › Color Range › Reds … Magentas (`center` 0, 60, …, 300°): closeness of hue (full at
721
- * the centre, none 60° away) × chroma × (2 − max), so neutrals are never selected.
722
- */
723
- declare function hueRange(pixels: PixelBuffer, center: number): SelectionMask;
724
-
725
- /** Distance reported for every pixel when there is no seed at all. */
726
- declare const EMPTY_DISTANCE = 10000000000;
727
- /**
728
- * Exact Euclidean distance from every pixel centre to the nearest seed pixel centre (row-major
729
- * `inside`, non-zero = seed): nearest seeds along columns, then the lower envelope of parabolas
730
- * along rows (Felzenszwalb & Huttenlocher). Linear in the pixel count.
731
- */
732
- declare function distanceTransform(inside: ArrayLike<number | boolean>, width: number, height: number): Float32Array;
733
- /** Grows coverage (0..1) by `r` pixels: covered when the nearest selected centre is ≤ r away (fractional r → partial). */
734
- declare function expandCoverage(m: ArrayLike<number>, w: number, h: number, r: number): Float32Array;
735
- /** Shrinks coverage by `r` pixels (expands the inverse). */
736
- declare function contractCoverage(m: ArrayLike<number>, w: number, h: number, r: number): Float32Array;
737
- /**
738
- * Select › Modify › Border: a soft band `2r` wide centred on the edge. A pixel `D` away (centre
739
- * to centre) from the nearest pixel on the other side of the edge is selected `1 − (D − 1) / r`.
740
- */
741
- declare function borderCoverage(m: ArrayLike<number>, w: number, h: number, r: number): Float32Array;
742
- /**
743
- * Select › Modify › Smooth: box average of radius `round(r)` with replicated edges, then
744
- * re-thresholded at ½ — specks drop, corners round, straight edges stay hard.
745
- */
746
- declare function smoothCoverage(m: ArrayLike<number>, w: number, h: number, r: number): Float32Array;
747
- /** Select › Modify › Feather: Gaussian blur with σ = radius (as Photoshop), zero beyond the image. */
748
- declare function featherCoverage(m: ArrayLike<number>, w: number, h: number, radius: number): Float32Array;
749
- /** Grey dilation (`grow`) or erosion with a square of radius `r`, separable, O(1) per pixel. */
750
- declare function greyMorphology(src: ArrayLike<number>, w: number, h: number, r: number, grow: boolean): Float32Array;
751
- /**
752
- * Grows (positive) or shrinks (negative) soft coverage by a fractional distance: whole pixels
753
- * use one morphology, the remainder blends with the next pixel, so 0.3 px differs from 1 px.
754
- */
755
- declare function shiftCoverage(src: ArrayLike<number>, w: number, h: number, amount: number): Float32Array;
756
- type SelectionModifyOp = 'grow' | 'shrink' | 'feather' | 'border' | 'smooth';
757
- declare const SELECTION_MODIFY_OPS: readonly SelectionModifyOp[];
758
- /** Select › Modify (grow = Expand, shrink = Contract, feather, border, smooth) by `radius` pixels. */
759
- declare function modifySelection(mask: SelectionMask, op: SelectionModifyOp, radius: number): SelectionMask;
760
-
761
- /**
762
- * Refine Edge / Select and Mask parameters (Photoshop's units). Refinement is edge-aware: within
763
- * `radius` pixels of the mask's edge the coverage is re-estimated from the image with a colour
764
- * guided filter (He et al.), so a coarse or misaligned mask (e.g. an AI segmentation) follows
765
- * the real edges of the image.
766
- */
767
- interface RefineEdgeParams {
768
- /** Edge-detection band radius in pixels (0 = no edge detection). */
769
- radius?: number;
770
- /** Narrow the band where the image edge is sharp (hair stays soft, hard edges stay hard). */
771
- smartRadius?: boolean;
772
- /** 0..100: rounds jagged edges. */
773
- smooth?: number;
774
- /** Pixels of Gaussian softening. */
775
- feather?: number;
776
- /** 0..100: hardens soft edges. */
777
- contrast?: number;
778
- /** −100..100: moves the edge out (positive) or in; 100 % is `max(radius, 4)` pixels. */
779
- shiftEdge?: number;
780
- }
781
- declare const DEFAULT_REFINE_EDGE_PARAMS: Required<RefineEdgeParams>;
782
- /** Guided-filter regulariser (colour guide, samples in 0..1). */
783
- declare const GUIDED_FILTER_EPS = 0.0001;
784
- /** Clamped, complete parameters. */
785
- declare function normalizeRefineEdgeParams(p?: RefineEdgeParams): Required<RefineEdgeParams>;
786
- /** Pixels around the mask's content that refinement can read or write. */
787
- declare function refineEdgeHalo(params?: RefineEdgeParams): number;
788
- /** Box mean of radius `r` (window clipped to the image, divided by its pixel count). O(1) per pixel. */
789
- declare function boxMean(src: ArrayLike<number>, w: number, h: number, r: number): Float32Array;
790
- /**
791
- * Guided filter with a colour guide (He et al., Eq. 19–21: `a_k = (Σ_k + εU)⁻¹ cov_k(I, p)`):
792
- * filters `p` so that it is locally a linear function of the guide's colour, which makes the
793
- * output's edges follow the guide's edges. `guide` is three planes of 0..1 values.
794
- */
795
- declare function guidedFilterColor(guide: readonly [Float32Array, Float32Array, Float32Array], p: Float32Array, w: number, h: number, r: number, eps?: number): Float32Array;
796
- /**
797
- * Per-pixel transition width (pixels) of the guide's luminance: local range over local maximum
798
- * gradient in a window of radius `r` (a sharp step gives about 2, a ramp of width L about L).
799
- */
800
- declare function edgeWidth(guide: readonly [Float32Array, Float32Array, Float32Array], w: number, h: number, r: number): Float32Array;
801
- /**
802
- * Refines soft coverage `m` (`w × h`, 0..1) with `guide` (three 0..1 planes, required when
803
- * `radius > 0`): edge-aware re-estimation in a band around the edge, then smooth, feather,
804
- * contrast and shift edge, in that order.
805
- */
806
- declare function refineCoverage(guide: readonly [Float32Array, Float32Array, Float32Array] | null, m: Float32Array, w: number, h: number, params?: RefineEdgeParams): Float32Array;
807
- /** Three 0..1 planes of a window of an RGBA buffer. */
808
- declare function guidePlanes(pixels: PixelBuffer, win?: CropBox): [Float32Array, Float32Array, Float32Array];
809
- /**
810
- * Refine Edge on a selection (or a coarse AI mask loaded as one) against `pixels` (the image,
811
- * same size). Work is confined to the mask's bounds grown by {@link refineEdgeHalo}, so a small
812
- * selection on a large image stays cheap.
813
- */
814
- declare function refineSelection(pixels: PixelBuffer | null, mask: SelectionMask, params?: RefineEdgeParams): SelectionMask;
815
-
816
- type CropHandle = 'nw' | 'ne' | 'se' | 'sw' | 'n' | 's' | 'e' | 'w' | 'inside' | null;
817
- interface ViewportMetrics {
818
- vpWidth: number;
819
- vpHeight: number;
820
- centerX: number;
821
- centerY: number;
822
- baseW: number;
823
- baseH: number;
824
- fitScale: number;
825
- renderW: number;
826
- renderH: number;
827
- totalScale: number;
828
- imageRect: {
829
- x: number;
830
- y: number;
831
- width: number;
832
- height: number;
833
- };
834
- cropRect: {
835
- x: number;
836
- y: number;
837
- width: number;
838
- height: number;
839
- } | null;
840
- }
841
- /**
842
- * A complete description of the natural-image -> target mapping (see module comment).
843
- */
844
- interface ImageProjection {
845
- /** Visible region in natural image pixels (crop box or full image). */
846
- region: CropBox;
847
- /** Rotation in degrees, normalised to [0, 360). */
848
- angle: number;
849
- flipH: boolean;
850
- flipV: boolean;
851
- /** Uniform scale from image pixels to target pixels. */
852
- scale: number;
853
- /** Target-space point that the centre of `region` maps to. */
854
- originX: number;
855
- originY: number;
856
- }
857
- /** Normalises any rotation in degrees to [0, 360). */
858
- declare function normalizeAngle(degrees: number): number;
859
- /** Whether the rotation swaps the displayed width and height. */
860
- declare function isQuarterTurnSwapped(transform: Pick<ImageTransform, 'rotate'>): boolean;
861
- /** Size of a region once rotated (bounding box for arbitrary angles). */
862
- declare function getRotatedSize(width: number, height: number, transform: Pick<ImageTransform, 'rotate'>): {
863
- width: number;
864
- height: number;
865
- };
866
- /** Maps a natural-image point to target space. */
867
- declare function projectImagePoint(pt: ImagePoint, p: ImageProjection): ImagePoint;
868
- /** Exact inverse of {@link projectImagePoint}. */
869
- declare function unprojectCanvasPoint(pt: ImagePoint, p: ImageProjection): ImagePoint;
870
- /**
871
- * Applies the projection to a 2D context so that subsequent drawing in natural image
872
- * pixels lands exactly where {@link projectImagePoint} says it does.
873
- */
874
- declare function applyImageProjectionToContext(ctx: Pick<CanvasRenderingContext2D, 'translate' | 'scale' | 'rotate'>, p: ImageProjection): void;
875
- /** Projects an image-space rectangle and returns its target-space bounding box. */
876
- declare function projectImageRect(rect: CropBox, p: ImageProjection): {
877
- x: number;
878
- y: number;
879
- width: number;
880
- height: number;
881
- };
882
- /** Clamps a crop box to the image bounds. */
883
- declare function clampCropToImage(crop: CropBox, width: number, height: number): CropBox;
884
- /**
885
- * Returns the natural-image -> canvas projection used by the interactive viewport.
886
- */
887
- declare function getViewportProjection(state: ImageEditorState, vpWidth: number, vpHeight: number, isActivelyCropping?: boolean, cropOverride?: CropBox | null): ImageProjection;
888
- /**
889
- * Calculates current viewport projection metrics for canvas <-> image coordinate mapping.
890
- * `cropRect` is the on-screen (rotated/flipped) rectangle of the crop box.
891
- */
892
- declare function getViewportMetrics(state: ImageEditorState, vpWidth: number, vpHeight: number, isActivelyCropping?: boolean, cropOverride?: CropBox | null): ViewportMetrics;
893
- /**
894
- * Converts a point on the canvas (in internal canvas pixel space) to natural image pixel
895
- * space, accounting for zoom, pan, fit scale, crop offset, rotation and flips.
896
- */
897
- declare function canvasToImagePoint(canvasPt: ImagePoint, state: ImageEditorState, vpWidth: number, vpHeight: number, isActivelyCropping?: boolean): ImagePoint;
898
- /**
899
- * Converts a point in natural image pixel space to internal canvas pixel space.
900
- * Exact inverse of {@link canvasToImagePoint}.
901
- */
902
- declare function imageToCanvasPoint(imgPt: ImagePoint, state: ImageEditorState, vpWidth: number, vpHeight: number, isActivelyCropping?: boolean): ImagePoint;
903
- /**
904
- * Converts a crop handle in screen orientation to the equivalent edge/corner of the crop
905
- * box in natural image space, or the reverse with `toScreen = true`.
906
- */
907
- declare function mapCropHandle(handle: CropHandle, transform: ImageTransform, toScreen?: boolean): CropHandle;
908
- /**
909
- * Hit-tests the crop box and its corner/edge handles given a canvas point.
910
- * The returned handle names the edge/corner of the crop box in natural image space
911
- * (what {@link calculateCropDrag} expects); use `getCropCursor(handle, state.transform)`
912
- * to obtain the matching on-screen cursor.
913
- */
914
- declare function hitTestCrop(canvasPt: ImagePoint, state: ImageEditorState, vpWidth: number, vpHeight: number, handleThreshold?: number, cropOverride?: CropBox | null): CropHandle;
915
- /**
916
- * Returns CSS cursor style corresponding to a crop handle. Pass the current transform when
917
- * the handle comes from {@link hitTestCrop} (image space) so the cursor matches the
918
- * on-screen orientation under rotation/flip.
919
- */
920
- declare function getCropCursor(handle: CropHandle, transform?: ImageTransform): string;
921
- /**
922
- * Calculates updated crop rectangle given a drag interaction.
923
- */
924
- declare function calculateCropDrag(startCrop: CropBox, handle: CropHandle, startImgPt: ImagePoint, currentImgPt: ImagePoint, imgWidth: number, imgHeight: number, aspectRatio?: number | null, transform?: ImageTransform): CropBox;
925
- /**
926
- * Calculates bounding box of an annotation.
927
- */
928
- declare function getAnnotationBounds(ann: Annotation): {
929
- x: number;
930
- y: number;
931
- width: number;
932
- height: number;
933
- };
934
- /**
935
- * Hit tests if a point in image space is within an annotation's bounds.
936
- */
937
- declare function hitTestAnnotation(imgPt: ImagePoint, ann: Annotation, padding?: number): boolean;
938
-
939
- /** Properties of a layer mask that leave its pixels intact (Photoshop's Properties › Masks). */
940
- interface LayerMaskProps {
941
- /** 0..1 (default 1): at 0.5 the masked-out areas still get half of the adjustment. */
942
- density?: number;
943
- /** Gaussian feather σ in pixels, 0..1000 (default 0). */
944
- feather?: number;
945
- /** Disabled masks are kept but ignored (the layer applies everywhere). Default true. */
946
- enabled?: boolean;
947
- /**
948
- * Layer masks only: `false` unlinks the mask, so moving or transforming the layer's pixels leaves
949
- * it in place. Default true. Adjustment-layer masks in canvas space ignore it.
950
- */
951
- linked?: boolean;
952
- }
953
- /**
954
- * A clean layer mask from stored data, or `null` when it is unusable. Defaults are left out
955
- * (density 1, feather 0, enabled), so a plain mask serializes as `{width, height, rle}`. The
956
- * RLE is only decoded when rendering.
957
- */
958
- declare function normalizeLayerMask(raw: unknown): AdjustmentLayerMask | null;
959
- /** A layer mask holding the selection's pixels (Add Layer Mask › Reveal Selection). */
960
- declare function layerMaskFromSelection(selection: SelectionMask, props?: LayerMaskProps): AdjustmentLayerMask;
961
- /** Applies property changes; `undefined` fields keep their value. */
962
- declare function updateLayerMaskProps(mask: AdjustmentLayerMask, props: LayerMaskProps): AdjustmentLayerMask;
963
- /** The mask's pixels as a selection (Load Selection from mask), or `null` when the data is damaged. */
964
- declare function decodeLayerMask(mask: AdjustmentLayerMask): SelectionMask | null;
965
- /** Cache key of everything about a mask that changes pixels. */
966
- declare function layerMaskKey(mask: AdjustmentLayerMask | undefined): string;
967
- /**
968
- * The mask's effective coverage (0..1, mask resolution): feathered (σ = feather, borders
969
- * replicated), then density applied as `1 − density·(1 − v)`. `null` for a disabled or damaged
970
- * mask, meaning "no mask".
971
- */
972
- declare function layerMaskCoverage(mask: AdjustmentLayerMask): Float32Array | null;
973
- /**
974
- * Resamples mask coverage (natural-image aligned, any resolution) into a target raster drawn
975
- * through `projection` (the base canvas of the renderer: crop, rotation, flips): each target
976
- * pixel centre is unprojected to natural pixels and sampled bilinearly.
977
- */
978
- declare function projectMaskCoverage(coverage: Float32Array, maskWidth: number, maskHeight: number, naturalWidth: number, naturalHeight: number, projection: ImageProjection, targetWidth: number, targetHeight: number): Float32Array;
979
- /**
980
- * Per-layer mask coverage for a render target, keyed by layer id; `undefined` when no layer has
981
- * an enabled, valid mask (so mask-free stacks take the exact same path as before).
982
- */
983
- declare function buildLayerMaskPlanes(layers: readonly AdjustmentLayer[] | undefined, naturalWidth: number, naturalHeight: number, projection: ImageProjection, targetWidth: number, targetHeight: number): Map<string, Float32Array> | undefined;
984
-
985
- /** A refused layer operation; the message says why and how to fix it. */
986
- declare class LayerOperationError extends Error {
987
- constructor(message: string);
988
- }
989
- /** Where a layer goes: above or below a layer (in its group), or at a position in a group. */
990
- interface LayerPlacement {
991
- /** Directly above this layer, in the same group. */
992
- aboveId?: string;
993
- /** Directly below this layer, in the same group. */
994
- belowId?: string;
995
- /** Inside this group (at `index`, default the top). */
996
- parentId?: string;
997
- /** Index in the parent's children (or the top level), 0 = bottom. */
998
- index?: number;
999
- }
1000
- /** The layer with `id`, or a `LayerOperationError` listing the ids that exist. */
1001
- declare function requireLayer(layers: readonly ImageLayer[], id: string): LayerLocation$1<ImageLayer>;
1002
- /** Refuses when the layer is locked for `what` (and always for `all`). */
1003
- declare function requireUnlocked(layer: ImageLayer, what: keyof LayerLocks, action: string): void;
1004
- /** Inserts `layer` at `placement` (default: the top level at `defaultIndex`, or the top). */
1005
- declare function placeLayer(layers: readonly ImageLayer[], layer: ImageLayer, placement?: LayerPlacement, defaultIndex?: number): ImageLayer[];
1006
- /** Removes a layer (refused when it is locked). */
1007
- declare function removeLayer(layers: readonly ImageLayer[], id: string): ImageLayer[];
1008
- /** Moves a layer to `placement`. A group cannot go inside itself. Returns the new stack. */
1009
- declare function moveLayer(layers: readonly ImageLayer[], id: string, placement: LayerPlacement): ImageLayer[];
1010
- /** Every id in a subtree gets a fresh one (for duplicates). */
1011
- declare function withNewIds<T extends ImageLayer>(layer: T): T;
1012
- /** Duplicates a layer (and its children) directly above it. Returns the stack and the copy's id. */
1013
- declare function duplicateLayer(layers: readonly ImageLayer[], id: string, name?: string): {
1014
- layers: ImageLayer[];
1015
- id: string;
1016
- };
1017
- /** Properties `setLayerProperties` changes. */
1018
- interface LayerProperties {
1019
- name?: string;
1020
- visible?: boolean;
1021
- /** 0..1 */
1022
- opacity?: number;
1023
- /** 0..1, pixel layers only. */
1024
- fillOpacity?: number;
1025
- blend?: LayerBlendMode;
1026
- clipped?: boolean;
1027
- locks?: LayerLocks;
1028
- /** Groups only (UI state). */
1029
- collapsed?: boolean;
1030
- }
1031
- /** Validates and applies property changes to one layer. */
1032
- declare function setLayerProperties(layers: readonly ImageLayer[], id: string, props: LayerProperties): ImageLayer[];
1033
- /**
1034
- * Puts layers (siblings in one group or the top level) into a new group at the position of the
1035
- * topmost one, keeping their order. Returns the stack and the group id.
1036
- */
1037
- declare function groupLayers(layers: readonly ImageLayer[], ids: string[], name?: string): {
1038
- layers: ImageLayer[];
1039
- id: string;
1040
- };
1041
- /** Replaces a group by its children (the group's own opacity, blend and mask are dropped). */
1042
- declare function ungroupLayer(layers: readonly ImageLayer[], id: string): {
1043
- layers: ImageLayer[];
1044
- ids: string[];
1045
- };
1046
- /** Sets a pixel layer's offset (refused when its position is locked). An unlinked mask stays in place. */
1047
- declare function offsetLayer(layers: readonly ImageLayer[], id: string, offset: {
1048
- x: number;
1049
- y: number;
1050
- }): ImageLayer[];
1051
- /** Sets or removes (`null`) a layer's mask. */
1052
- declare function setLayerMask(layers: readonly ImageLayer[], id: string, mask: RasterMask | null): ImageLayer[];
1053
- /** A clean filter from loose input (for tools and the UI). */
1054
- declare function normalizeFilter(raw: Partial<LayerFilter> & {
1055
- kind: LayerFilter['kind'];
1056
- }, id?: string): LayerFilter;
1057
- /** Adds a filter on top of a pixel layer's filters. A layer has at most one filter of each kind. */
1058
- declare function addLayerFilter(layers: readonly ImageLayer[], id: string, filter: LayerFilter): ImageLayer[];
1059
- /** Changes one filter of a pixel layer (`changes` merged and validated). */
1060
- declare function updateLayerFilter(layers: readonly ImageLayer[], id: string, filterId: string, changes: Record<string, unknown>): ImageLayer[];
1061
- declare function removeLayerFilter(layers: readonly ImageLayer[], id: string, filterId: string): ImageLayer[];
1062
- /** A layer's effects, or an empty, enabled list when it has none. */
1063
- declare function layerEffectsOf(layer: ImageLayer): LayerEffects;
1064
- /** Replaces a layer's effects (validated); `null` or an empty list without a PSD block removes them. */
1065
- declare function setLayerEffects(layers: readonly ImageLayer[], id: string, effects: LayerEffects | null): ImageLayer[];
1066
- /**
1067
- * Adds an effect of `kind` (Photoshop's defaults with `params` applied) to a layer's effects, at
1068
- * `index` in the list (default: the end; the first listed of a kind is on top). Returns the stack
1069
- * and the new effect.
1070
- */
1071
- declare function addLayerEffect(layers: readonly ImageLayer[], id: string, kind: LayerEffectKind, params?: Record<string, unknown>, index?: number): {
1072
- layers: ImageLayer[];
1073
- effect: LayerEffect;
1074
- };
1075
- /** Changes one effect (only the given fields; nested objects replace whole, `null` removes an optional one). */
1076
- declare function updateLayerEffect(layers: readonly ImageLayer[], id: string, effectId: string, changes: Record<string, unknown>): ImageLayer[];
1077
- declare function removeLayerEffect(layers: readonly ImageLayer[], id: string, effectId: string): ImageLayer[];
1078
- /** Sets the master switch and, when given, Scale Effects (0.01..10, 1 = 100 %). */
1079
- declare function setLayerEffectsEnabled(layers: readonly ImageLayer[], id: string, enabled: boolean, scale?: number): ImageLayer[];
1080
- /** A blend mode check for tools. */
1081
- declare function parseBlend(value: unknown, allowPassThrough?: boolean): BlendMode | 'pass-through' | undefined;
1082
- /** The union of two rectangles (either may be null). */
1083
- declare function unionRect(a: CropBox | null, b: CropBox | null): CropBox | null;
1084
-
1085
- interface PlaneLayout {
1086
- planes: number;
1087
- width: number;
1088
- height: number;
1089
- depth: number;
1090
- /** PSB: RLE row counts are 4 bytes. */
1091
- psb: boolean;
1092
- }
1093
- /** Decodes planar channel data (`planes` planes of `height` rows each). */
1094
- declare function decodePlanes(compression: number, data: Uint8Array, l: PlaneLayout): Uint8Array;
1095
- /** RLE-encodes planar data: row counts (u16, or u32 in PSB), then the packed rows. */
1096
- declare function encodeRle(decoded: Uint8Array, l: PlaneLayout): Uint8Array;
1097
-
1098
- interface PsdHeader {
1099
- psb: boolean;
1100
- channels: number;
1101
- height: number;
1102
- width: number;
1103
- depth: number;
1104
- colorMode: number;
1105
- }
1106
- interface PsdRect {
1107
- top: number;
1108
- left: number;
1109
- bottom: number;
1110
- right: number;
1111
- }
1112
- interface PsdChannel {
1113
- id: number;
1114
- /** `null` for a zero-length channel. */
1115
- compression: number | null;
1116
- /** Encoded bytes, without the compression field. */
1117
- data: Uint8Array;
1118
- }
1119
- interface PsdLayerMask {
1120
- rect: PsdRect;
1121
- defaultColor: number;
1122
- flags: number;
1123
- userDensity?: number;
1124
- userFeather?: number;
1125
- vectorDensity?: number;
1126
- vectorFeather?: number;
1127
- /** The real (vector-combined) user mask, when present. */
1128
- real?: {
1129
- flags: number;
1130
- background: number;
1131
- rect: PsdRect;
1132
- };
1133
- }
1134
- interface PsdTaggedBlock {
1135
- key: string;
1136
- data: Uint8Array;
1137
- }
1138
- interface PsdLayerRecord {
1139
- rect: PsdRect;
1140
- channels: PsdChannel[];
1141
- blendKey: string;
1142
- opacity: number;
1143
- clipping: number;
1144
- flags: number;
1145
- mask?: PsdLayerMask;
1146
- /** The legacy (Pascal) name; `layerName` prefers `luni`. */
1147
- legacyName: string;
1148
- blocks: PsdTaggedBlock[];
1149
- }
1150
- interface PsdResource {
1151
- id: number;
1152
- name: string;
1153
- data: Uint8Array;
1154
- }
1155
- interface PsdFile {
1156
- header: PsdHeader;
1157
- colorModeData: Uint8Array;
1158
- resources: PsdResource[];
1159
- /** Bottom-most first, as stored. */
1160
- layers: PsdLayerRecord[];
1161
- /** The layer count was negative: the merged image's first extra channel is its alpha. */
1162
- mergedAlpha: boolean;
1163
- globalBlocks: PsdTaggedBlock[];
1164
- imageCompression: number;
1165
- imageData: Uint8Array;
1166
- }
1167
- /** Parses a PSD or PSB. Throws `PsdError` with what was wrong. */
1168
- declare function readPsd(bytes: Uint8Array): PsdFile;
1169
- declare function layerName(rec: PsdLayerRecord): string;
1170
- interface PsdTreeNode {
1171
- /** Index into `PsdFile.layers` (the folder record for a group). */
1172
- index: number;
1173
- children?: PsdTreeNode[];
1174
- }
1175
- /** The layer tree, bottom-most first (the stored order, as in our model), from the `lsct` dividers. */
1176
- declare function layerTree(file: PsdFile): PsdTreeNode[];
1177
- /** One layer channel decoded to `depth`-bit planar bytes, or `undefined` if the layer has none. */
1178
- declare function decodeLayerChannel(file: PsdFile, rec: PsdLayerRecord, id: number): Uint8Array | undefined;
1179
- /** The merged image's channels decoded, planar. */
1180
- declare function decodeMergedImage(file: PsdFile): Uint8Array;
1181
- /** Serializes a file. Channel data must already be encoded; `encodeName` writes legacy (Pascal) names. */
1182
- declare function writePsd(file: PsdFile, encodeName: (s: string) => Uint8Array): Uint8Array;
1183
-
1184
- /** PSD blend keys → our blend modes (`diss` is the one we lack). */
1185
- declare const PSD_BLEND_KEYS: Record<string, LayerBlendMode>;
1186
- /** What happened to one PSD layer on import. */
1187
- interface PsdLayerSummary {
1188
- name: string;
1189
- /** Our layer type, or `null` when the layer was dropped. */
1190
- type: 'pixel' | 'adjustment' | 'group' | null;
1191
- /** `mapped`: held exactly; `approximated`: imported with losses; `dropped`: left out. */
1192
- status: 'mapped' | 'approximated' | 'dropped';
1193
- /** What Photoshop calls it (`pixel`, `type`, `smart-object`, `fill`, `shape`, `Levels` …). */
1194
- psdKind: string;
1195
- /** Why it is not `mapped`. */
1196
- notes: string[];
1197
- /** Our layer id (when imported). */
1198
- id?: string;
1199
- depth: number;
1200
- }
1201
- interface PsdImportResult {
1202
- width: number;
1203
- height: number;
1204
- /** Bottom to top, as in our model. */
1205
- layers: ImageLayer[];
1206
- /** One sentence per problem, naming the affected layers. */
1207
- warnings: string[];
1208
- /** Every PSD layer, bottom first, a group before its children. */
1209
- summary: PsdLayerSummary[];
1210
- /** Pixels per inch, when the file says. */
1211
- resolution?: number;
1212
- /** The patterns embedded in the file (`Patt` / `Pat2` / `Pat3`), which pattern effects use. */
1213
- patterns: EffectPattern[];
1214
- /** The global light (image resources 1037 and 1049), when the file has one. */
1215
- globalLight?: GlobalLight;
1216
- info: {
1217
- psb: boolean;
1218
- depth: number;
1219
- colorMode: string;
1220
- channels: number;
1221
- };
1222
- }
1223
- interface PsdImportOptions {
1224
- /** Makes layer ids (defaults to `psd-<n>`). */
1225
- newId?: (hint: string) => string;
1226
- /** Skip decoding pixels (inspection only). */
1227
- skipPixels?: boolean;
1228
- }
1229
- /** Maps a parsed PSD to our layers. */
1230
- declare function psdToLayers(file: PsdFile, options?: PsdImportOptions): PsdImportResult;
1231
- /** Parses and maps PSD / PSB bytes. Throws `PsdError` for files that cannot be read at all. */
1232
- declare function importPsd(bytes: Uint8Array, options?: PsdImportOptions): PsdImportResult;
1233
-
1234
- /**
1235
- * Free Transform geometry for the image editor, as pure functions both the UI bindings and the
1236
- * agent tools use: a transform is the frame being transformed (`box`, document pixels), where its
1237
- * four corners land (`corners`, TL, TR, BR, BL) and an optional warp mesh over the box. Scale,
1238
- * rotate, skew and flips keep the corners a parallelogram (an affine map); Distort and Perspective
1239
- * move them freely (a projective map); Warp bends the box through a Bézier mesh before the corner
1240
- * map.
1241
- *
1242
- * The maths (homographies, meshes, presets) is shared with the vector editor in `src/geom`.
1243
- */
1244
-
1245
- /** Free Transform modes (Edit › Transform). Scale, rotate and skew stay affine. */
1246
- type FreeTransformMode = 'scale' | 'rotate' | 'skew' | 'distort' | 'perspective' | 'warp';
1247
- declare const FREE_TRANSFORM_MODES: readonly FreeTransformMode[];
1248
- /** The nine reference-point positions of the options bar's locator, over the transformed box. */
1249
- type TransformAnchor = 'top-left' | 'top' | 'top-right' | 'left' | 'center' | 'right' | 'bottom-left' | 'bottom' | 'bottom-right';
1250
- declare const TRANSFORM_ANCHORS: readonly TransformAnchor[];
1251
- declare function isTransformAnchor(value: unknown): value is TransformAnchor;
1252
- /** A transform in progress: the frame, where its corners go and an optional warp over the frame. */
1253
- interface FreeTransformGeometry {
1254
- /** The frame being transformed, in document pixels (the content bounds when it began). */
1255
- box: CropBox;
1256
- /** Where the frame's corners land: top-left, top-right, bottom-right, bottom-left (document pixels). */
1257
- corners: Quad;
1258
- /**
1259
- * A warp applied in the frame's own space before the corner map: its control points are in
1260
- * document pixels of the untransformed frame (`identityWarpMesh(box)` is no warp).
1261
- */
1262
- warp?: WarpMesh | null;
1263
- }
1264
- /** The untransformed geometry of a box. */
1265
- declare function identityTransform(box: CropBox): FreeTransformGeometry;
1266
- /** Where `box`'s corners go under the affine `m`. */
1267
- declare function cornersFromMatrix(box: CropBox, m: AffineMatrix): Quad;
1268
- /** The affine matrix taking `box` onto `corners` when they form a parallelogram, else `null`. */
1269
- declare function matrixFromCorners(box: CropBox, corners: Quad, eps?: number): AffineMatrix | null;
1270
- /** The projective map of the corner move (box → corners), or `null` when the corners are degenerate. */
1271
- declare function transformHomography(geometry: FreeTransformGeometry): Homography | null;
1272
- /** Whether a warp mesh changes anything (not the identity over the box). */
1273
- declare function hasWarp(geometry: FreeTransformGeometry): boolean;
1274
- /** Whether the geometry changes nothing. */
1275
- declare function isIdentityTransform(geometry: FreeTransformGeometry): boolean;
1276
- /**
1277
- * The forward map of the whole transform (document pixels of the source → document pixels of the
1278
- * result): the warp over the box, then the corner map. `null` where it is undefined.
1279
- */
1280
- declare function transformMap(geometry: FreeTransformGeometry): ((p: Vec2) => Vec2 | null) | null;
1281
- /** A point of the transformed box at box fractions (`fx`, `fy`), warp included. */
1282
- declare function transformedPoint(geometry: FreeTransformGeometry, fx: number, fy: number): Vec2 | null;
1283
- /** Where an anchor of the box is after the corner map (the warp ignored). */
1284
- declare function anchorPoint(geometry: FreeTransformGeometry, anchor: TransformAnchor): Vec2;
1285
- /** Bounds of the transformed result's outline (document pixels, not rounded). */
1286
- declare function transformedBox(geometry: FreeTransformGeometry): CropBox | null;
1287
- /** Free Transform as numbers, as Photoshop's options bar shows it. */
1288
- interface TransformParams {
1289
- /** Width in percent of the frame (default 100; negative flips). */
1290
- scaleX?: number;
1291
- /** Height in percent of the frame (default 100; negative flips). */
1292
- scaleY?: number;
1293
- /** Rotation in degrees, clockwise (default 0). */
1294
- rotate?: number;
1295
- /** Horizontal skew in degrees: vertical edges lean right for positive angles (default 0). */
1296
- skewX?: number;
1297
- /** Vertical skew in degrees: horizontal edges lean down for positive angles (default 0). */
1298
- skewY?: number;
1299
- /** Move after scaling and rotating, in document pixels (default 0). */
1300
- dx?: number;
1301
- dy?: number;
1302
- /** The fixed point of scale, skew and rotation: an anchor of the frame or a document point (default the centre). */
1303
- reference?: TransformAnchor | Vec2;
1304
- }
1305
- /** The reference point of params over a box (default its centre). */
1306
- declare function referencePoint(box: CropBox, reference: TransformParams['reference']): Vec2;
1307
- /**
1308
- * The affine matrix of `params` over `box`: about the reference point, skew, then scale, then
1309
- * rotate; then the move.
1310
- */
1311
- declare function matrixFromParams(box: CropBox, params: TransformParams): AffineMatrix;
1312
- /** What the options bar shows for a transform. */
1313
- interface TransformReadout {
1314
- /** False for Distort, Perspective and Warp: only `bounds` and `corners` then mean anything. */
1315
- affine: boolean;
1316
- /** Width and height in percent of the frame. */
1317
- scaleX: number;
1318
- scaleY: number;
1319
- /** Rotation in degrees, clockwise, in (−180, 180]. */
1320
- rotate: number;
1321
- /** Horizontal skew in degrees (vertical skew is folded into rotation and scale). */
1322
- skewX: number;
1323
- /** Where the reference point is now (document pixels). */
1324
- x: number;
1325
- y: number;
1326
- /** Bounds of the transformed outline. */
1327
- bounds: CropBox | null;
1328
- corners: Quad;
1329
- }
1330
- /**
1331
- * Decomposes a transform for the options bar: the linear part as rotate · scale · skew (QR) with
1332
- * the given reference point. Non-affine geometry reports its bounds and corners only.
1333
- */
1334
- declare function describeTransform(geometry: FreeTransformGeometry, reference?: TransformParams['reference']): TransformReadout;
1335
- /**
1336
- * Corners for a transform given as numbers relative to the current corners: `params` are applied
1337
- * after the current affine part (when the corners are a parallelogram) about the reference point
1338
- * of the current geometry, so typing "rotate 15" rotates the box as it is now.
1339
- */
1340
- declare function applyParams(geometry: FreeTransformGeometry, params: TransformParams): Quad;
1341
- /** Flip of the corners about the box's centre line (horizontal: left ↔ right). */
1342
- declare function flipCorners(geometry: FreeTransformGeometry, axis: 'horizontal' | 'vertical'): Quad;
1343
- /** Inverse of `matrixFromCorners` (box space → document) for mapping a document point back into the box. */
1344
- declare function boxPointOf(geometry: FreeTransformGeometry, p: Vec2): Vec2 | null;
1345
- /** A warp mesh from a preset over the box (null when it changes nothing). */
1346
- declare function presetWarp(box: CropBox, preset: WarpPreset): WarpMesh | null;
1347
- /** Validates a warp mesh for a box: well formed, finite, the right number of points. */
1348
- declare function isValidWarp(mesh: unknown): mesh is WarpMesh;
1349
- /** The geometry's affine map when it is one (no warp, a parallelogram), as a homography; else the projective map. */
1350
- declare function geometryHomography(geometry: FreeTransformGeometry): Homography | null;
1351
-
1352
- /**
1353
- * Free Transform sessions: what a transform moves (a layer's pixels with its linked mask, a lone
1354
- * unlinked mask, the selected pixels as a floating piece, a copy of them on a new layer, or just
1355
- * the selection outline), a live preview while the geometry changes, and one undo step when it is
1356
- * committed with full-quality resampling.
1357
- */
1358
-
1359
- /**
1360
- * What a Free Transform moves:
1361
- * - `layer`: the layer's pixels with its linked mask (or, with `channel: 'mask'` on an unlinked
1362
- * mask, the mask alone);
1363
- * - `selection`: the selected pixels (and the same part of a linked mask), lifted and committed
1364
- * back into the layer; the selection outline moves with them;
1365
- * - `selection-copy`: Layer via Copy, then the copy is transformed on a new layer above;
1366
- * - `selection-outline`: Transform Selection, only the outline;
1367
- * - `auto` (default): `selection` when something is selected, else `layer`.
1368
- */
1369
- type FreeTransformContent = 'auto' | 'layer' | 'selection' | 'selection-copy' | 'selection-outline';
1370
- declare const FREE_TRANSFORM_CONTENTS: readonly FreeTransformContent[];
1371
- interface FreeTransformInit {
1372
- /** The layer (default the active one); not needed for `selection-outline`. */
1373
- layerId?: string;
1374
- content?: FreeTransformContent;
1375
- /**
1376
- * `pixels` (default) moves the pixels with a linked mask; `mask` moves an unlinked mask alone (a
1377
- * linked one moves with its pixels). Defaults to the active target on the active layer.
1378
- */
1379
- channel?: LayerTarget;
1380
- /** Resampling of the committed result (default bicubic). */
1381
- interpolation?: Interpolation;
1382
- }
1383
- /** How a live preview is drawn (the UI knows these, the controller doesn't). */
1384
- interface FreeTransformPreview {
1385
- /** Screen pixels per document pixel: below 1 the preview samples a reduced copy in blocks. */
1386
- scale?: number;
1387
- /** Only this part of the document (the visible area) is resampled. */
1388
- clip?: CropBox;
1389
- }
1390
- /** What a committed transform changed. */
1391
- interface FreeTransformResult {
1392
- /** The layer that holds the result (the new layer for `selection-copy`; `null` for `selection-outline`). */
1393
- layerId: string | null;
1394
- content: Exclude<FreeTransformContent, 'auto'>;
1395
- /** What moved. */
1396
- moved: Array<'pixels' | 'mask' | 'selection'>;
1397
- /** The frame the transform started from (document pixels). */
1398
- box: CropBox;
1399
- /** Where the frame's corners went. */
1400
- corners: FreeTransformGeometry['corners'];
1401
- /** Document bounds of the moved content after the transform (pixels, or the mask or the outline). */
1402
- bounds: CropBox | null;
1403
- /** False when the geometry was the identity and nothing was recorded. */
1404
- changed: boolean;
1405
- }
1406
- /** @internal What the session needs from the controller. */
1407
- interface FreeTransformHost {
1408
- layers(): ImageLayer[];
1409
- activeLayerId(): string | null;
1410
- activeTarget(): LayerTarget;
1411
- selection(): SelectionMask | null;
1412
- canvas(): {
1413
- width: number;
1414
- height: number;
1415
- };
1416
- /** The pixels a pixel layer composites (the decoded source for the Background). */
1417
- pixelsOf(layer: PixelLayer): TiledSurface;
1418
- /** Opaque pre-transform snapshot. */
1419
- capture(): unknown;
1420
- /** Shows a live state (no history). */
1421
- show(layers: ImageLayer[], selection: SelectionMask | null, activeLayerId: string | null): void;
1422
- /** Records `before` as the undo step of the state now shown. */
1423
- record(before: unknown): void;
1424
- /** Puts `before` back (no history). */
1425
- restore(before: unknown): void;
1426
- }
1427
- /** Preview block size for a screen scale: 1 at 100 % and above, then powers of two up to 8. */
1428
- declare function previewStep(scale: number | undefined): number;
1429
- /**
1430
- * A Free Transform in progress (see `ImageEditorController.beginFreeTransform`). Change the
1431
- * geometry with `update` (each change shows a live preview without history), then `commit()`
1432
- * (one undo step, resampled at full quality) or `cancel()` (everything back as it was).
1433
- */
1434
- declare class FreeTransformSession {
1435
- private readonly host;
1436
- readonly content: Exclude<FreeTransformContent, 'auto'>;
1437
- /** The layer being transformed (`null` for `selection-outline`). */
1438
- readonly layerId: string | null;
1439
- /** The new layer of a `selection-copy`. */
1440
- readonly copyId: string | null;
1441
- /** The frame (document pixels). */
1442
- readonly box: CropBox;
1443
- /** What moves. */
1444
- readonly moves: ReadonlyArray<'pixels' | 'mask' | 'selection'>;
1445
- private geometryValue;
1446
- private interp;
1447
- private readonly parts;
1448
- private readonly before;
1449
- private readonly startLayers;
1450
- private readonly startSelection;
1451
- private readonly startActive;
1452
- /** The stack this session last showed: anything else means the document changed under it. */
1453
- private shown;
1454
- private closed;
1455
- constructor(host: FreeTransformHost, init?: FreeTransformInit);
1456
- /** The current geometry. */
1457
- get geometry(): FreeTransformGeometry;
1458
- get interpolation(): Interpolation;
1459
- get isOpen(): boolean;
1460
- private check;
1461
- /**
1462
- * Changes the geometry (`corners`, `warp`) or the interpolation and, unless `preview` is `false`,
1463
- * shows the result live (no history). Returns the geometry.
1464
- */
1465
- update(changes: {
1466
- corners?: FreeTransformGeometry['corners'];
1467
- warp?: FreeTransformGeometry['warp'];
1468
- interpolation?: Interpolation;
1469
- }, preview?: FreeTransformPreview | false): FreeTransformGeometry;
1470
- /** Resamples every part for the current geometry and shows it (or returns it, for commit). */
1471
- private resample;
1472
- private render;
1473
- /** Finishes the transform with full-quality resampling, as one undo step. */
1474
- commit(): FreeTransformResult;
1475
- /** Abandons the transform and puts everything back (no history). */
1476
- cancel(): void;
1477
- private result;
1478
- }
1479
-
1480
- /** Latest serialized schema version (`3`: layers). Documents with the old shape still write 1 or 2. */
1481
- declare const IMAGE_EDITOR_SCHEMA_VERSION: 3;
1482
- /** Changes to an adjustment layer; `params` is merged into the current parameters. */
1483
- interface AdjustmentLayerUpdate<K extends AdjustmentKind = AdjustmentKind> {
1484
- params?: Partial<AdjustmentParamsMap[K]>;
1485
- enabled?: boolean;
1486
- opacity?: number;
1487
- blend?: BlendMode;
1488
- name?: string;
1489
- /** A layer mask, or `null` to remove it. */
1490
- mask?: AdjustmentLayerMask | null;
1491
- }
1492
- /** Options shared by the selection commands. */
1493
- interface SelectionCommandOptions {
1494
- /** How the result combines with the current selection (default `replace`). */
1495
- mode?: SelectionMode;
1496
- /** Feather the new shape by this many pixels before combining (default 0). */
1497
- feather?: number;
1498
- }
1499
- /** Where an AI result goes (see `applyInpaintedImage`, `applyBackgroundRemovedImage`). */
1500
- interface AIResultOptions {
1501
- /** `new-layer`: a new layer (inpainting) or a mask (background removal); `replace`: the Background's pixels. Default: by `isMultiLayer`. */
1502
- target?: 'new-layer' | 'replace';
1503
- }
1504
- /** Where the selection tools read colours from. */
1505
- interface SampleOptions {
1506
- /**
1507
- * `composite` (default): the image, as before (with several layers: the composite of the pixel
1508
- * layers, or with `sampleMerged` of every layer); `active-layer`: only the active pixel layer.
1509
- */
1510
- sample?: 'composite' | 'active-layer';
1511
- /** Sample the adjusted image (base adjustments and layers) instead of the source pixels. */
1512
- sampleMerged?: boolean;
1513
- /** Pixels to use instead of reading the source image (natural size, RGBA). */
1514
- pixels?: PixelBuffer;
1515
- }
1516
- /** A new adjustment layer: its kind plus optional initial values and position. */
1517
- interface AdjustmentLayerInit<K extends AdjustmentKind = AdjustmentKind> extends AdjustmentLayerUpdate<K> {
1518
- kind: K;
1519
- id?: string;
1520
- /** Put the new layer directly above this layer (in its group). */
1521
- aboveId?: string;
1522
- /** Put the new layer at the top of this group. */
1523
- parentId?: string;
1524
- }
1525
- /** A new pixel layer: empty, a solid colour over the canvas, or given pixels, plus its properties and position. */
1526
- interface PixelLayerInit extends LayerPlacement {
1527
- id?: string;
1528
- name?: string;
1529
- /** Fill the canvas with this colour (`#rgb`, `#rrggbb`, `#rrggbbaa` or `[r, g, b, a?]` 0..255). */
1530
- color?: string | number[];
1531
- /** RGBA pixels placed at `x`, `y` (document pixels). */
1532
- pixels?: PixelBuffer;
1533
- x?: number;
1534
- y?: number;
1535
- visible?: boolean;
1536
- /** 0..1 (default 1). */
1537
- opacity?: number;
1538
- fillOpacity?: number;
1539
- blend?: BlendMode;
1540
- }
1541
- /** The paint tools' options (view state). */
1542
- interface PaintOptions {
1543
- brush: BrushSettings;
1544
- /** `#rrggbb`: what the brush and Fill paint. */
1545
- foreground: string;
1546
- /** `#rrggbb`: what the eraser paints on transparency-locked layers and masks. */
1547
- background: string;
1548
- /** Mixer Brush options (wet, load, mix, load / clean each stroke, RGB or pigment mixing). */
1549
- mixer: MixerSettings;
1550
- /** What the Mixer Brush carries now: its reservoir, how much is left and the picked-up colour. */
1551
- mixerLoad: MixerLoad;
1552
- }
1553
- /** Paint tools a stroke can use. */
1554
- type StrokeTool = 'brush' | 'eraser' | 'mixer';
1555
- /** A stroke: tool, target (default the active layer and target) and brush / colour overrides. */
1556
- interface StrokeInit {
1557
- tool?: StrokeTool;
1558
- layerId?: string;
1559
- channel?: LayerTarget;
1560
- /** Overrides of the paint options' brush. */
1561
- brush?: Partial<BrushSettings>;
1562
- /**
1563
- * Paint colour (default the foreground). Masks take its grey value. For the mixer, the colour
1564
- * the reservoir is loaded with: given, it loads the brush whatever `loadEachStroke` says.
1565
- */
1566
- color?: string | number[];
1567
- /** Overrides of the paint options' Mixer Brush settings (tool `mixer`). */
1568
- mixer?: Partial<MixerSettings>;
1569
- /** Eraser colour on locked transparency / masks (default the background). */
1570
- background?: string | number[];
1571
- /** Kept with the stroke for replays (v1 brushes have no jitter). */
1572
- seed?: number;
1573
- }
1574
- interface FillOptions {
1575
- layerId?: string;
1576
- channel?: LayerTarget;
1577
- /** Default the foreground colour. */
1578
- color?: string | number[];
1579
- /** 0..1 (default 1). */
1580
- opacity?: number;
1581
- blend?: BlendMode;
1582
- /** Limit to the selection when there is one (default true). */
1583
- useSelection?: boolean;
1584
- }
1585
- /** What a stroke, fill or clear changed. */
1586
- interface PaintStrokeResult {
1587
- layerId: string;
1588
- channel: LayerTarget;
1589
- /** Document rectangle that changed (null when nothing did). */
1590
- bounds: CropBox | null;
1591
- dabs: number;
1592
- /** The Mixer Brush's load after the stroke (tool `mixer` only). */
1593
- mixerLoad?: MixerLoad;
1594
- }
1595
- /** An opaque pre-stroke history snapshot. */
1596
- type HistoryEntryHandle = {
1597
- readonly __historyEntry: unique symbol;
1598
- };
1599
- /** How a Mixer Brush stroke starts (see `PaintStrokeSession`). */
1600
- interface MixerStrokeInit {
1601
- /** Makes the stroke over the session's live pixels. */
1602
- create(pixels: MixerTarget): MixerStroke;
1603
- /** Stores the brush load when the stroke ends and returns it (after any clean). */
1604
- end(load: MixerLoad): MixerLoad;
1605
- }
1606
- /**
1607
- * A stroke in progress (see `beginStroke`): `push` input points as they arrive, then `end` (one
1608
- * undo step) or `cancel`. Brush and eraser strokes build up a coverage map composited over the
1609
- * pre-stroke pixels; Mixer Brush strokes paint dab by dab into the live pixels, so each dab picks
1610
- * up what the dabs before it laid down.
1611
- */
1612
- declare class PaintStrokeSession {
1613
- private readonly controller;
1614
- readonly target: {
1615
- id: string;
1616
- channel: LayerTarget;
1617
- surface: TiledSurface;
1618
- };
1619
- private readonly apply;
1620
- private readonly before;
1621
- private readonly base;
1622
- private readonly live;
1623
- private readonly touched;
1624
- private readonly stroke;
1625
- private readonly mixer;
1626
- private readonly mixerInit;
1627
- /** Mixer tiles written since the last update: they get new tile objects so the compositor sees them change. */
1628
- private readonly fresh;
1629
- private last;
1630
- private closed;
1631
- constructor(controller: ImageEditorController, target: {
1632
- id: string;
1633
- channel: LayerTarget;
1634
- surface: TiledSurface;
1635
- }, stroke: StrokeCoverage | MixerStrokeInit, apply: StrokeApply);
1636
- /** The live pixels a mixer stroke reads and writes; base tiles are copied on first write. */
1637
- private mixerPixels;
1638
- get layerId(): string;
1639
- /** Adds input points (document pixels); the stack shows the stroke so far. */
1640
- push(points: readonly StrokePoint[]): void;
1641
- private update;
1642
- /** Finishes the stroke (one undo step) and returns what changed. */
1643
- end(): PaintStrokeResult;
1644
- /** Abandons the stroke and restores the layer. */
1645
- cancel(): void;
1646
- }
1647
- /** Where a new annotation goes. */
1648
- interface AnnotationPlacement {
1649
- /** Put the annotation layer directly above this layer (default: the top of the stack). */
1650
- aboveId?: string;
1651
- }
1652
- declare const DEFAULT_ADJUSTMENTS: ImageAdjustments;
1653
- /**
1654
- * Fills in defaults for stored adjustments. A stored object without `process` was saved before
1655
- * process versions existed and keeps the legacy rendering.
1656
- */
1657
- declare function normalizeStoredAdjustments(stored: Partial<ImageAdjustments> | undefined | null): ImageAdjustments;
1658
- /**
1659
- * Brings a stored editor state of any schema version to a clean state of the same family:
1660
- * version 1 (and a missing version) has no adjustment layers, version 2 has them, and both stay
1661
- * in the document-level schema so old states load and render exactly as before. Version 3
1662
- * (layers) is returned with its document fields cleaned. To lift a v1 / v2 state into layers,
1663
- * use {@link migrateToLayeredState}.
1664
- */
1665
- declare function migrateSerializedImageEditorState(data: Partial<SerializedImageEditorState> & {
1666
- version?: number;
1667
- }): SerializedImageEditorState;
1668
- /**
1669
- * Lifts a stored state of any version into the layered schema (v3) for a canvas of
1670
- * `width × height`: the source becomes the Background layer with the base sliders as its
1671
- * `develop` filter and the depth mask as its parametric mask, adjustment layers go above it and
1672
- * annotations on top (see `layersFromLegacy`).
1673
- */
1674
- declare function migrateToLayeredState(data: Partial<SerializedImageEditorState> & {
1675
- version?: number;
1676
- }, size: ImageDimensions): SerializedLayeredImageEditorState;
1677
- declare const DEFAULT_TRANSFORM: ImageTransform;
1678
- declare const DEFAULT_DEPTH_MASK: DepthMaskOptions;
1679
- /**
1680
- * ImageEditorController manages the complete lifecycle, canvas rendering pipeline,
1681
- * tool interaction states, undo/redo history, serialization, and image export.
1682
- */
1683
- declare class ImageEditorController {
1684
- private state;
1685
- private renderer;
1686
- private imageElement;
1687
- private listeners;
1688
- private histogramListeners;
1689
- private onStateChange?;
1690
- private undoStack;
1691
- private redoStack;
1692
- private maxHistoryDepth;
1693
- private maxHistoryBytes;
1694
- private isApplyingHistory;
1695
- private initialSnapshot;
1696
- /** Pixels the selection tools sample (host-provided or read back from the source). */
1697
- private samplePixels;
1698
- private samplePixelsOverride;
1699
- /** Decoded source pixels (the Background's surface), by the buffer or element they came from. */
1700
- private sourceSurfaces;
1701
- private viewKey;
1702
- /** For `compositePixels` and mask evaluation (the renderer keeps its own for the viewport). */
1703
- private compositor;
1704
- constructor(options?: ImageEditorOptions);
1705
- /**
1706
- * Loads a new source image and makes it the baseline that `reset()` returns to.
1707
- * Does not record history; use `applyInpaintedImage` / `applyBackgroundRemovedImage`
1708
- * for undoable source replacement.
1709
- */
1710
- loadImage(src: string | HTMLImageElement): Promise<void>;
1711
- private resolveSource;
1712
- getImageElement(): CanvasImageSource | null;
1713
- getState(): ImageEditorState;
1714
- subscribe(listener: (state: ImageEditorState) => void): () => void;
1715
- /**
1716
- * Where layer pixels changed since the last viewport render, when only strokes changed them
1717
- * (the renderer then recomposites just those rectangles); `'all'` after any other change.
1718
- */
1719
- private pendingDirty;
1720
- private notify;
1721
- /** Recomputes the compatibility views (`adjustments`, `depthMask`, `annotations`) when the stack changed. */
1722
- private syncViews;
1723
- private stack;
1724
- private captureHistoryEntry;
1725
- private restoreHistoryEntry;
1726
- private recordHistory;
1727
- /**
1728
- * Bytes of pixel tiles held only by undo / redo steps (not by the current state). The oldest
1729
- * undo steps are dropped while it exceeds `maxHistoryBytes`.
1730
- */
1731
- get historyBytes(): number;
1732
- private trimHistoryBytes;
1733
- get canUndo(): boolean;
1734
- get canRedo(): boolean;
1735
- undo(): boolean;
1736
- redo(): boolean;
1737
- reset(): void;
1738
- setTool(tool: ImageEditorTool): void;
1739
- setCrop(crop: CropBox | null, addToHistory?: boolean): void;
1740
- applyCropPreset(ratio: AspectRatio): void;
1741
- resetCrop(): void;
1742
- rotate(degrees: number): void;
1743
- setRotation(degrees: number): void;
1744
- flipHorizontal(): void;
1745
- flipVertical(): void;
1746
- /** The layer stack, bottom to top (immutable objects). */
1747
- getLayers(): ImageLayer[];
1748
- getLayer(id: string): ImageLayer | undefined;
1749
- /** The active layer, or `undefined`. */
1750
- getActiveLayer(): ImageLayer | undefined;
1751
- /**
1752
- * Makes a layer the active one (or none) and chooses whether painting targets its pixels or
1753
- * its mask. View state: no undo step. Returns false for an unknown id.
1754
- */
1755
- setActiveLayer(id: string | null, target?: LayerTarget): boolean;
1756
- /**
1757
- * The pixels of a pixel layer, in document space (`x`, `y` is the top-left of the returned
1758
- * buffer), or `null` for an unknown or empty layer. Resolves the Background's source pixels.
1759
- */
1760
- getLayerPixels(id: string): (PixelBuffer & {
1761
- x: number;
1762
- y: number;
1763
- }) | null;
1764
- private boundsCache;
1765
- /**
1766
- * Document bounds of a layer's non-transparent pixels (pixel layers; the Background's source
1767
- * included), or `null` for an empty or non-pixel layer.
1768
- */
1769
- getLayerBounds(id: string): CropBox | null;
1770
- /**
1771
- * Composites the layer stack in document space without a canvas (annotation layers need one
1772
- * and are left out): `rect` (default: the canvas) as RGBA, straight alpha. Crop, rotation and
1773
- * output opacity are not applied. With `layerIds`, only those layers are composited.
1774
- */
1775
- compositePixels(rect?: CropBox, options?: {
1776
- layerIds?: string[];
1777
- }): PixelBuffer;
1778
- private compositorSources;
1779
- private sourceIds;
1780
- private nextSourceId;
1781
- /** Changes whenever the Background's source pixels can have changed. */
1782
- private sourceVersion;
1783
- /** The pixels a pixel layer composites (the decoded source for the Background). */
1784
- private surfaceOf;
1785
- /**
1786
- * The source image as a surface (cached): host-supplied sample pixels first, then the decoded
1787
- * element, then pixels read back for the selection tools.
1788
- */
1789
- private sourceSurface;
1790
- private opaqueCache;
1791
- /** Whether every source pixel is opaque (some legacy renders depend on it). */
1792
- private sourceIsOpaque;
1793
- /** Synchronously reads the source element's pixels through a canvas, or `null`. */
1794
- private decodeSource;
1795
- /** Records one undo step and applies a new stack (and any other state change in `extra`). */
1796
- private commitLayers;
1797
- /** The default position of a new layer: above the active layer, else the top of the stack. */
1798
- private newLayerPlacement;
1799
- /**
1800
- * Adds a pixel layer (one undo step) and makes it active: empty, filled with `color` over the
1801
- * canvas, or holding `pixels` placed at `x`, `y`. Goes above the active layer unless placed.
1802
- * Returns its id.
1803
- */
1804
- addPixelLayer(init?: PixelLayerInit): string;
1805
- /**
1806
- * `addPixelLayer` from an image: a PNG data URL or base64 PNG is decoded without a canvas;
1807
- * other formats and URLs need a browser. Returns the new layer id.
1808
- */
1809
- addPixelLayerFromImage(image: string, init?: Omit<PixelLayerInit, 'pixels' | 'color'>): Promise<string>;
1810
- /** RGBA pixels of an image given as a data URL, base64 PNG or URL. */
1811
- decodeImage(image: string): Promise<PixelBuffer>;
1812
- private nextLayerName;
1813
- /** Duplicates a layer (with its children) directly above it, as one undo step. Returns the copy's id. */
1814
- duplicateLayer(id: string, name?: string): string;
1815
- /** Deletes a layer (refused when locked), as one undo step. */
1816
- removeLayer(id: string): void;
1817
- /** Moves a layer above / below another, or into a group, as one undo step. Returns its new parent and index. */
1818
- moveLayer(id: string, placement: LayerPlacement): {
1819
- parentId: string | null;
1820
- index: number;
1821
- };
1822
- /**
1823
- * Changes name, visibility, opacity, fill, blend, clipping, locks or (groups) collapsed state, as
1824
- * one undo step (`commitToHistory = false` for the moves of a slider drag). Returns the layer.
1825
- */
1826
- setLayerProperties(id: string, props: LayerProperties, commitToHistory?: boolean): ImageLayer;
1827
- /** Adds an empty pass-through group above the active layer (or at `placement`) and makes it active. Returns its id. */
1828
- addGroup(init?: LayerPlacement & {
1829
- name?: string;
1830
- blend?: LayerBlendMode;
1831
- }): string;
1832
- /** Puts sibling layers into a new group (one undo step). Returns the group id. */
1833
- groupLayers(ids: string[], name?: string): string;
1834
- /** Replaces a group by its children (one undo step). Returns the child ids, bottom to top. */
1835
- ungroupLayer(id: string): string[];
1836
- /**
1837
- * Moves a pixel layer to an absolute offset (`x`, `y`) or by `dx`, `dy`, as one undo step
1838
- * (`commitToHistory = false` for the moves of a drag). Returns the offset and document bounds.
1839
- */
1840
- offsetLayer(id: string, move: {
1841
- x?: number;
1842
- y?: number;
1843
- dx?: number;
1844
- dy?: number;
1845
- }, commitToHistory?: boolean): {
1846
- offset: {
1847
- x: number;
1848
- y: number;
1849
- };
1850
- bounds: CropBox | null;
1851
- };
1852
- /**
1853
- * Adds a mask to a layer (one undo step): `reveal-all` (white), `hide-all` (black) or
1854
- * `selection` (the selection's coverage). Replaces an existing mask. Makes the mask the paint
1855
- * target when the layer is active.
1856
- */
1857
- addLayerMask(id: string, from?: 'reveal-all' | 'hide-all' | 'selection', props?: LayerMaskProps): RasterMask;
1858
- /** Removes a layer's mask (one undo step). */
1859
- removeLayerMask(id: string): void;
1860
- /** Changes any layer mask's density, feather, enabled or linked flag (pixels kept). Returns the mask. */
1861
- setLayerMaskProps(id: string, props: LayerMaskProps, commitToHistory?: boolean): RasterMask;
1862
- /**
1863
- * Bakes a pixel layer's mask into its pixels (alpha × coverage, including density, feather or
1864
- * the depth map) and removes the mask, as one undo step.
1865
- */
1866
- applyLayerMask(id: string): Promise<void>;
1867
- /**
1868
- * Layer via Copy (or via Cut): a new pixel layer with the selected pixels of a pixel layer (the
1869
- * active one by default), directly above it, as one undo step. Returns the new id.
1870
- */
1871
- layerViaCopy(options?: {
1872
- layerId?: string;
1873
- cut?: boolean;
1874
- name?: string;
1875
- }): string;
1876
- private openTransform;
1877
- /** The Free Transform in progress (see `beginFreeTransform`), or `null`. */
1878
- getFreeTransform(): FreeTransformSession | null;
1879
- private transformHost;
1880
- /**
1881
- * Starts a Free Transform (Edit › Free Transform, Transform Selection, or a transform of a Layer
1882
- * via Copy): of the layer's pixels with its linked mask, an unlinked mask alone, the selected
1883
- * pixels or just the selection outline (see `FreeTransformInit`). Change the geometry with
1884
- * `session.update` (live preview, no history), then `commit()` (one undo step) or `cancel()`.
1885
- * Refused while another transform is open.
1886
- */
1887
- beginFreeTransform(init?: FreeTransformInit): FreeTransformSession;
1888
- /**
1889
- * Transforms in one step (agents, scripts): begins a Free Transform for `spec`, sets its corners
1890
- * from exactly one of `matrix` (document-space affine), `corners` (where the frame's corners go:
1891
- * distort / perspective) or `params` (scale, rotate, skew and move about a reference point), and
1892
- * commits it as one undo step. Returns what changed and the new bounds.
1893
- */
1894
- transformLayer(spec: FreeTransformInit & {
1895
- matrix?: AffineMatrix;
1896
- corners?: Quad;
1897
- params?: TransformParams;
1898
- warp?: WarpMesh | WarpPreset | null;
1899
- }): FreeTransformResult;
1900
- /** Flips the layer (or its selected pixels, or the outline) about the frame's centre, exactly (one undo step). */
1901
- flipLayer(axis: 'horizontal' | 'vertical', init?: FreeTransformInit): FreeTransformResult;
1902
- /**
1903
- * Rotates by a quarter turn (90 clockwise, −90 counter-clockwise) or 180 about the frame's
1904
- * centre, snapped so pixels land on whole pixels: exact, no resampling (one undo step).
1905
- */
1906
- rotateLayer90(turn: 90 | -90 | 180, init?: FreeTransformInit): FreeTransformResult;
1907
- /** Adds a `develop` or `blur` filter to a pixel layer (one undo step). Returns the layer's filters. */
1908
- addLayerFilter(id: string, filter: Partial<LayerFilter> & {
1909
- kind: LayerFilter['kind'];
1910
- }): LayerFilter[];
1911
- /** Changes one filter (one undo step, or none with `commitToHistory = false` during a drag). Returns the filters. */
1912
- updateLayerFilter(id: string, filterId: string, changes: Record<string, unknown>, commitToHistory?: boolean): LayerFilter[];
1913
- /** Removes one filter (one undo step). Returns the remaining filters. */
1914
- removeLayerFilter(id: string, filterId: string): LayerFilter[];
1915
- /** A layer's effects (an empty, enabled list when it has none). */
1916
- getLayerEffects(id: string): LayerEffects;
1917
- /**
1918
- * Adds an effect of `kind` with Photoshop's defaults and `params` applied (one undo step), at
1919
- * `index` in the layer's effect list (default the end). Returns the new effect and the effects.
1920
- */
1921
- addLayerEffect(id: string, kind: LayerEffectKind, params?: Record<string, unknown>, index?: number): {
1922
- effect: LayerEffect;
1923
- effects: LayerEffects;
1924
- };
1925
- /** Changes one effect (one undo step, or none with `commitToHistory = false` during a drag). Returns the effects. */
1926
- updateLayerEffect(id: string, effectId: string, changes: Record<string, unknown>, commitToHistory?: boolean): LayerEffects;
1927
- /** Removes one effect (one undo step). Returns the remaining effects. */
1928
- removeLayerEffect(id: string, effectId: string): LayerEffects;
1929
- /** Turns a layer's effects on or off as a whole and, when given, sets Scale Effects (one undo step). */
1930
- setLayerEffectsEnabled(id: string, enabled: boolean, scale?: number, commitToHistory?: boolean): LayerEffects;
1931
- /** Replaces a layer's effects (one undo step; `null` removes them). Returns the effects. */
1932
- setLayerEffects(id: string, effects: LayerEffects | null, commitToHistory?: boolean): LayerEffects;
1933
- private patternIds;
1934
- /** Changes whenever the document's pattern list is replaced (the compositor then drops its caches). */
1935
- private patternsVersion;
1936
- /** The document's patterns (from an opened PSD), besides the built-in ones. */
1937
- getDocumentPatterns(): EffectPattern[];
1938
- /** The light effects with "use global light" follow. */
1939
- getGlobalLight(): GlobalLight;
1940
- /** Sets the global light (one undo step). `angle` -360..360°, `altitude` 0..90°. Returns it. */
1941
- setGlobalLight(light: Partial<GlobalLight>, commitToHistory?: boolean): GlobalLight;
1942
- /** Composites `layers` (in isolation) over `rect` into a surface, loading depth maps first. */
1943
- private compositeToSurface;
1944
- /** Document bounds a layer can paint into (pixel content, annotations, or the canvas for the rest). */
1945
- private paintBounds;
1946
- /**
1947
- * Merge Down: composites a layer onto the pixel layer directly below it (which keeps its name,
1948
- * opacity and blend; masks, fill, filters and both layers' effects are baked), as one undo step.
1949
- * Returns the merged id.
1950
- */
1951
- mergeDown(id: string): Promise<string>;
1952
- /**
1953
- * Merge Visible: the visible top-level layers become one normal pixel layer (at the position of
1954
- * the lowest of them); hidden layers stay. One undo step. Returns the merged id.
1955
- */
1956
- mergeVisible(): Promise<string>;
1957
- /** Flatten Image: every visible layer composited into one Background layer; hidden layers are discarded. One undo step. */
1958
- flattenImage(): Promise<string>;
1959
- private thumbCache;
1960
- /**
1961
- * A small RGBA preview of a pixel layer over the canvas (or of its mask with `mask: true`),
1962
- * longest side `maxSide` px, point-sampled; `null` for layers without pixels.
1963
- */
1964
- getLayerThumbnail(id: string, options?: {
1965
- maxSide?: number;
1966
- mask?: boolean;
1967
- }): PixelBuffer | null;
1968
- /** Brush settings, colours and tool options of the paint tools (view state, no undo). */
1969
- setPaintOptions(options: Partial<Omit<PaintOptions, 'brush' | 'mixer' | 'mixerLoad'>> & {
1970
- brush?: Partial<BrushSettings>;
1971
- mixer?: Partial<MixerSettings>;
1972
- }): PaintOptions;
1973
- /**
1974
- * Loads the Mixer Brush's reservoir full with `color` (default the foreground); the picked-up
1975
- * colour is kept. View state, no undo. Returns the brush load.
1976
- */
1977
- loadMixerBrush(color?: string | number[]): MixerLoad;
1978
- /** Cleans the Mixer Brush: empties the pickup well (the reservoir is kept). Returns the brush load. */
1979
- cleanMixerBrush(): MixerLoad;
1980
- /** Empties the Mixer Brush entirely (no reservoir, nothing picked up). Returns the brush load. */
1981
- emptyMixerBrush(): MixerLoad;
1982
- /** D: black foreground, white background. */
1983
- resetPaintColors(): void;
1984
- /** X: swaps the foreground and background colours. */
1985
- swapPaintColors(): void;
1986
- /** Resolves and validates what a stroke, fill or clear paints into. */
1987
- private paintTarget;
1988
- /** The layer with its pixels (or mask) replaced by `surface`. */
1989
- private withSurface;
1990
- /**
1991
- * Starts a brush or eraser stroke on a layer's pixels or mask (default: the active layer and
1992
- * target, the paint options' brush and colours). Feed points with `push`, finish with `end()`
1993
- * (one undo step for the whole stroke) or `cancel()`. While it runs, the stack shows the stroke
1994
- * without recording history.
1995
- */
1996
- beginStroke(init?: StrokeInit): PaintStrokeSession;
1997
- /** A Mixer Brush stroke's start: the settings, and the load (refilled when asked or set to). */
1998
- private mixerStroke;
1999
- /** @internal Shows a stroke's live surface (no history). */
2000
- _strokeUpdate(layerId: string, channel: LayerTarget, surface: TiledSurface, rects: CropBox[]): void;
2001
- /** @internal Commits a finished stroke as one undo step (`before` is the pre-stroke state). */
2002
- _strokeCommit(before: HistoryEntryHandle, layerId: string, channel: LayerTarget, surface: TiledSurface | null): void;
2003
- /** @internal The pre-stroke snapshot. */
2004
- _captureForStroke(): HistoryEntryHandle;
2005
- /**
2006
- * Paints a whole stroke in one call (agents, replays): `points` in document pixels with optional
2007
- * pressure, through the brush, eraser or Mixer Brush. One undo step. Returns the layer, channel, the changed
2008
- * document bounds and the number of dabs.
2009
- */
2010
- paintStroke(init: StrokeInit & {
2011
- points: StrokePoint[];
2012
- }): PaintStrokeResult;
2013
- /**
2014
- * Edit › Fill: fills the selection (or, without one or with `useSelection: false`, the whole
2015
- * canvas) on a layer's pixels or mask with a colour (default the foreground), at `opacity` with
2016
- * `blend`. One undo step. Returns the changed bounds.
2017
- */
2018
- fillPixels(options?: FillOptions): PaintStrokeResult;
2019
- /**
2020
- * Edit › Clear: removes the selected pixels (alpha to 0; on a transparency-locked layer or a mask
2021
- * it fills with the background colour). Without a selection (or with `useSelection: false`) the
2022
- * whole canvas. One undo step. Returns the changed bounds.
2023
- */
2024
- clearPixels(options?: Omit<FillOptions, 'color' | 'blend'>): PaintStrokeResult;
2025
- private fillOrClear;
2026
- /** The pixel layer the base sliders edit: the active pixel layer, else the Background. */
2027
- private developLayer;
2028
- /**
2029
- * Sets base adjustment values as one undo step (unless `commitToHistory` is false). The base
2030
- * sliders edit the `develop` filter of the active pixel layer (or the Background), `blur` its
2031
- * blur filter (or `legacyOutputBlur` in migrated documents), `opacity` the output opacity, and
2032
- * `layers` replaces the adjustment layers.
2033
- */
2034
- setAdjustments(partial: Partial<ImageAdjustments>, commitToHistory?: boolean): void;
2035
- /** True when the adjustments use an older rendering process than {@link LATEST_PROCESS_VERSION}. */
2036
- get isProcessOutdated(): boolean;
2037
- /**
2038
- * Update to Current Process: re-interprets the current adjustment values with the latest
2039
- * rendering process (one undo step). Returns false when already current.
2040
- */
2041
- upgradeProcess(): boolean;
2042
- /** Resets the base sliders (latest process). Adjustment layers are kept; see `clearAdjustmentLayers`. */
2043
- resetAdjustments(): void;
2044
- /** The adjustment layers in stack order, bottom (first) to top (last). */
2045
- getAdjustmentLayers(): AdjustmentLayer[];
2046
- getAdjustmentLayer(id: string): AdjustmentLayer | undefined;
2047
- private adjustmentNodes;
2048
- /**
2049
- * Where a new layer goes when no position is given: directly above the topmost layer that is
2050
- * not an annotation, so it adjusts what adjustment layers always adjusted (annotations stay on top).
2051
- */
2052
- private defaultInsertIndex;
2053
- /** Inserts `node` by `aboveId` / `parentId` / adjustment index / default position. */
2054
- private placeLayer;
2055
- /** `setAdjustments({ layers })`: updates nodes by id in place, removes missing ones, adds new ones. */
2056
- private replaceAdjustmentNodes;
2057
- /**
2058
- * Adds an adjustment layer and returns its id, as one undo step. With no position it goes
2059
- * above the other adjustment layers (or, without any, above the topmost non-annotation layer,
2060
- * so annotations stay on top); `index` counts adjustment layers (0 = below the others);
2061
- * `aboveId` / `parentId` place it anywhere in the stack. `kind` alone gives neutral parameters.
2062
- */
2063
- addAdjustmentLayer<K extends AdjustmentKind>(init: K | AdjustmentLayerInit<K>, index?: number): string;
2064
- /**
2065
- * Updates a layer (`params` merged into the current ones, then normalised). Pass
2066
- * `commitToHistory = false` for the moves of a drag after recording its start once.
2067
- * Returns false for an unknown id.
2068
- */
2069
- updateAdjustmentLayer(id: string, update: AdjustmentLayerUpdate, commitToHistory?: boolean): boolean;
2070
- /** Removes a layer as one undo step. Returns false for an unknown id. */
2071
- removeAdjustmentLayer(id: string): boolean;
2072
- private moveAdjustmentNode;
2073
- /** Moves a layer to `toIndex` among the adjustment layers (0 = bottom) as one undo step. Returns false if nothing moved. */
2074
- moveAdjustmentLayer(id: string, toIndex: number): boolean;
2075
- /** Shows or hides a layer (flips it without `enabled`) as one undo step. */
2076
- toggleAdjustmentLayer(id: string, enabled?: boolean): boolean;
2077
- /** Removes every adjustment layer as one undo step. */
2078
- clearAdjustmentLayers(): void;
2079
- /** The active selection, or `null`. */
2080
- getSelection(): SelectionMask | null;
2081
- get hasSelection(): boolean;
2082
- private get naturalSize();
2083
- private dropMismatchedSelection;
2084
- /**
2085
- * Replaces the selection, or combines `mask` with it by `mode`, as one undo step. A mask of a
2086
- * different size (e.g. an AI segmentation at another resolution) is resampled to the image.
2087
- * Returns false when nothing changed.
2088
- */
2089
- setSelection(mask: SelectionMask | null, mode?: SelectionMode): boolean;
2090
- /** Select › All. */
2091
- selectAll(): boolean;
2092
- /** Select › Deselect. */
2093
- deselect(): boolean;
2094
- /** Select › Inverse (with nothing selected, selects everything). */
2095
- invertSelection(): boolean;
2096
- private shapeCommand;
2097
- /** Rectangular marquee in natural image pixels. */
2098
- selectRect(rect: CropBox, options?: SelectionCommandOptions & ShapeSelectionOptions): boolean;
2099
- /** Elliptical marquee inscribed in `rect`. */
2100
- selectEllipse(rect: CropBox, options?: SelectionCommandOptions & ShapeSelectionOptions): boolean;
2101
- /** Lasso / polygonal lasso. */
2102
- selectPolygon(points: ImagePoint[], options?: SelectionCommandOptions & ShapeSelectionOptions): boolean;
2103
- /**
2104
- * Supplies the pixels the selection tools sample (natural size RGBA), e.g. decoded in a worker
2105
- * or in a test; `null` goes back to reading the source image. Without a canvas (Node, workers)
2106
- * these are also the Background layer's pixels.
2107
- */
2108
- setSamplePixels(pixels: PixelBuffer | null): void;
2109
- /**
2110
- * The pixels the selection tools sample: the source image at natural size, or with
2111
- * `sampleMerged` the composite of the layers (no crop, rotation or annotations). `null`
2112
- * without pixel access (no DOM, tainted canvas).
2113
- */
2114
- getSamplePixels(options?: SampleOptions): Promise<PixelBuffer | null>;
2115
- private requirePixels;
2116
- /**
2117
- * Magic wand at `point` (natural image pixels). Resolves to the resulting selection (null when
2118
- * nothing is selected).
2119
- */
2120
- magicWand(point: ImagePoint, options?: MagicWandOptions & SelectionCommandOptions & SampleOptions): Promise<SelectionMask | null>;
2121
- /** Select › Color Range with colour samples (`#rrggbb` or `[r, g, b]`, optionally where they were picked). */
2122
- selectColorRange(samples: ColorRangeSample[], options?: ColorRangeOptions & SelectionCommandOptions & SampleOptions): Promise<SelectionMask | null>;
2123
- /** Select › Modify: grow, shrink, feather, border or smooth by `radius` pixels (one undo step). */
2124
- modifySelection(op: SelectionModifyOp, radius: number): boolean;
2125
- /**
2126
- * Refine Edge: snaps the selection (e.g. a coarse AI mask loaded with `loadSelectionFromImage`)
2127
- * to the image's edges with a guided filter, then smooth / feather / contrast / shift edge.
2128
- */
2129
- refineSelection(params: RefineEdgeParams, options?: SampleOptions): Promise<boolean>;
2130
- /**
2131
- * Loads a selection from a mask image (an AI segmentation, a saved mask): a data URL / URL or
2132
- * RGBA pixels, by luminance (white = selected) or a channel. Any size; it is resampled.
2133
- */
2134
- loadSelectionFromImage(source: string | PixelBuffer, options?: {
2135
- channel?: SelectionChannel;
2136
- invert?: boolean;
2137
- threshold?: number;
2138
- mode?: SelectionMode;
2139
- }): Promise<SelectionMask | null>;
2140
- /** Quick Mask view (tints the unselected area). View state: no undo step. */
2141
- setQuickMask(on: boolean): void;
2142
- private maskFromSelection;
2143
- /**
2144
- * Adds the selection as the layer's mask (Reveal Selection), replacing any mask, as one undo
2145
- * step. Without a selection, returns false.
2146
- */
2147
- applySelectionAsLayerMask(layerId: string, props?: LayerMaskProps): boolean;
2148
- private setLayerMask;
2149
- /** Sets (from a selection-shaped mask) or removes (`null`) a layer's mask as one undo step. */
2150
- setAdjustmentLayerMask(layerId: string, mask: SelectionMask | null, props?: LayerMaskProps): boolean;
2151
- /** Changes a layer mask's density (0..1), feather (px) or enabled flag; the mask pixels are kept. */
2152
- setAdjustmentLayerMaskProps(layerId: string, props: LayerMaskProps, commitToHistory?: boolean): boolean;
2153
- /** Load Selection from a layer mask (its pixels; density and feather are not applied). */
2154
- selectionFromLayerMask(layerId: string, mode?: SelectionMode): boolean;
2155
- /**
2156
- * Histogram of the last rendered preview (after adjustments and layers, before annotations),
2157
- * or `null` before the first render or without canvas pixel access.
2158
- */
2159
- getHistogram(): ImageHistogram | null;
2160
- /** Calls `listener` now and whenever a render produces a new preview histogram. */
2161
- subscribeHistogram(listener: (histogram: ImageHistogram | null) => void): () => void;
2162
- /** Sets the depth mask (a parametric mask on the active pixel layer, or the Background) as one undo step. */
2163
- setDepthMask(partial: Partial<DepthMaskOptions>): void;
2164
- resetDepthMask(): void;
2165
- private annotationLayer;
2166
- /** Adds an annotation as its own layer (top of the stack unless `aboveId` is given). */
2167
- addAnnotation(annotation: CreateAnnotationPayload, placement?: AnnotationPlacement): string;
2168
- updateAnnotation(id: string, partial: Partial<Annotation>, commitToHistory?: boolean): void;
2169
- removeAnnotation(id: string): void;
2170
- clearAnnotations(): void;
2171
- selectAnnotation(id: string | null): void;
2172
- setZoom(zoom: number): void;
2173
- zoomIn(factor?: number): void;
2174
- zoomOut(factor?: number): void;
2175
- resetZoom(): void;
2176
- setPan(pan: ImagePoint): void;
2177
- setComparing(comparing: boolean): void;
2178
- setFit(fit: ImageEditorFit): void;
2179
- private blankSource;
2180
- /**
2181
- * What the renderer draws from: the source image, or, for a document without one (an opened
2182
- * PSD, a v3 document loaded on its own), a transparent canvas of the document size, since every
2183
- * pixel then comes from the layers. `null` when there is nothing to draw.
2184
- */
2185
- private drawSource;
2186
- render(targetCanvas: HTMLCanvasElement, options?: RenderOptions): Promise<void>;
2187
- renderExport(options?: ExportOptions): Promise<HTMLCanvasElement>;
2188
- /**
2189
- * Renders the edited image (adjustments, layers and, by default, annotations) in the
2190
- * source image's own orientation and frame, ignoring crop, rotation and flips, so it lines
2191
- * up with natural-pixel coordinates (selections, `select_region`). `scale` ≤ 1 shrinks it.
2192
- * Returns `null` when no image is loaded.
2193
- */
2194
- renderSourceView(options?: {
2195
- scale?: number;
2196
- includeAnnotations?: boolean;
2197
- }): Promise<HTMLCanvasElement | null>;
2198
- toDataURL(options?: ExportOptions): Promise<string>;
2199
- toBlob(options?: ExportOptions): Promise<Blob>;
2200
- renderMask(options?: {
2201
- useAnnotations?: boolean;
2202
- useCrop?: boolean;
2203
- useSelection?: boolean;
2204
- }): Promise<HTMLCanvasElement>;
2205
- toMaskDataURL(options?: {
2206
- useAnnotations?: boolean;
2207
- useCrop?: boolean;
2208
- useSelection?: boolean;
2209
- }): Promise<string>;
2210
- /**
2211
- * Renders the current source image at natural size with no crop, rotation, flip,
2212
- * adjustments or annotations. This is the image that `toMaskDataURL()` is aligned with
2213
- * and the space that `applyInpaintedImage` / `applyBackgroundRemovedImage` expect back.
2214
- */
2215
- renderSource(): Promise<HTMLCanvasElement>;
2216
- /**
2217
- * The image an AI hook should edit: the source (`toSourceDataURL`) when results replace the
2218
- * Background, or the composite of the layers without annotations, in the source frame, when
2219
- * they go to a new layer or mask (see `applyInpaintedImage`).
2220
- */
2221
- toAIInputDataURL(options?: AIResultOptions): Promise<string>;
2222
- toSourceDataURL(options?: Pick<ExportOptions, 'format' | 'quality'>): Promise<string>;
2223
- /**
2224
- * Whether AI results go to layers: the document has more than one pixel layer or group (adjustment
2225
- * and annotation layers are edits of the image, not images of their own).
2226
- */
2227
- /** `new-layer` in multi-layer documents and documents without a source image, else `replace`. */
2228
- private defaultAITarget;
2229
- /** No source image, and no layer reading one (an opened PSD): the layers are the whole document. */
2230
- private isSourceless;
2231
- get isMultiLayer(): boolean;
2232
- /**
2233
- * Applies an inpainted result (natural image space, see `toSourceDataURL`) as ONE undoable step.
2234
- * In a document with several layers (see `isMultiLayer`), or with `target: 'new-layer'`, the
2235
- * result goes to a new pixel layer above the active layer, limited to the selection. Otherwise
2236
- * (`target: 'replace'`, the single-layer default) it replaces the Background's pixels and clears
2237
- * the mask annotations, as before. Resolves to the new layer's id in new-layer mode.
2238
- */
2239
- applyInpaintedImage(newDataUrl: string, options?: AIResultOptions): Promise<string | void>;
2240
- /**
2241
- * Applies a background-removed result as ONE undoable step. In a document with several layers
2242
- * (or with `target: 'new-layer'`) the result's alpha becomes the mask of the active pixel layer
2243
- * (or the Background), replacing its mask. Otherwise (`target: 'replace'`, the single-layer
2244
- * default) it replaces the Background's pixels; crop and annotations are kept (rescaled if the
2245
- * new image has different dimensions). Resolves to the masked layer's id in mask mode.
2246
- */
2247
- applyBackgroundRemovedImage(newDataUrl: string, options?: AIResultOptions): Promise<string | void>;
2248
- /**
2249
- * Rasterize Layer: an annotation layer becomes a pixel layer with the same id, name and
2250
- * properties (needs a canvas), and a pixel layer's filters are baked into its pixels. One undo
2251
- * step. Returns the layer id.
2252
- */
2253
- rasterizeLayer(id: string): Promise<string>;
2254
- /** Pixels per inch of the last opened PSD (written back by `toPsd`). */
2255
- private psdResolution;
2256
- /**
2257
- * Opens PSD / PSB bytes as the document (one undo step): the layers replace the stack and the
2258
- * document has no source image afterwards (every pixel comes from the layers). What the model
2259
- * cannot hold is approximated or left out; `warnings` says what, naming the layers.
2260
- * Throws `PsdError` for files that cannot be read at all.
2261
- */
2262
- loadPsd(bytes: Uint8Array): {
2263
- layerIds: string[];
2264
- warnings: string[];
2265
- width: number;
2266
- height: number;
2267
- summary: PsdImportResult['summary'];
2268
- };
2269
- /**
2270
- * The document as an 8-bit RGB PSD (PSB above 30 000 px) with real layers, groups, adjustment
2271
- * layers and masks, in the source frame. Layer filters and parametric (depth) masks are baked
2272
- * into pixels and masks, annotation layers are rasterized (in a browser; elsewhere they are left
2273
- * out), and the merged image is our composite. `warnings` lists every such change.
2274
- */
2275
- toPsd(): Promise<{
2276
- bytes: Uint8Array;
2277
- warnings: string[];
2278
- psb: boolean;
2279
- width: number;
2280
- height: number;
2281
- }>;
2282
- private replaceSource;
2283
- /**
2284
- * The serializable state. A document whose layers still have the v1 / v2 shape (the
2285
- * Background with its sliders and depth mask, adjustment layers, annotations) is written as
2286
- * v1 / v2 exactly as before; anything else is written as v3 with the layer pixels as PNG
2287
- * assets. `selection` is included (run-length encoded) only when something is selected.
2288
- */
2289
- toJSON(): SerializedImageEditorState;
2290
- /**
2291
- * With `assets: 'external'`, layer pixels go to `store` (each PNG uploaded once per store) and
2292
- * the v3 document holds the store's references. Old-shape documents have no assets either way.
2293
- */
2294
- toJSON(options: {
2295
- assets: 'external';
2296
- store: ImageEditorAssetStore;
2297
- }): Promise<SerializedImageEditorState>;
2298
- /**
2299
- * Loads a stored state whose v3 assets may live in an asset store (references other than data
2300
- * URLs are fetched with `store.get`), as one undo step. Assets that cannot be fetched are left
2301
- * out and listed in `lastLoadProblems`.
2302
- */
2303
- loadJSONAsync(data: SerializedImageEditorState, options?: {
2304
- store?: ImageEditorAssetStore;
2305
- }): Promise<void>;
2306
- /** Loads a stored state of any version (one undo step). */
2307
- loadJSON(data: SerializedImageEditorState): void;
2308
- /** Problems found by the last `loadJSON` / `initialState` of a v3 document (unreadable layers or assets). */
2309
- lastLoadProblems: string[];
2310
- private applyStored;
2311
- private serializeState;
2312
- }
2313
- /** Bilinear resample of RGBA pixels to `width × height`. */
2314
- declare function resizePixels(px: PixelBuffer, width: number, height: number): PixelBuffer;
2315
- /** A colour as RGBA bytes: `#rgb`, `#rrggbb`, `#rrggbbaa` or `[r, g, b, a?]` (0..255). */
2316
- declare function parseColor(value: string | number[]): [number, number, number, number];
2317
- /** `#rrggbb` of RGBA bytes (alpha dropped). */
2318
- declare function toHex(c: readonly number[]): string;
2319
-
2320
- interface ImageDimensions {
2321
- width: number;
2322
- height: number;
2323
- }
2324
- interface ImagePoint {
2325
- x: number;
2326
- y: number;
2327
- }
2328
- interface CropBox {
2329
- x: number;
2330
- y: number;
2331
- width: number;
2332
- height: number;
2333
- }
2334
- type AspectRatio = number | null;
2335
- interface ImageTransform {
2336
- rotate: number;
2337
- flipH: boolean;
2338
- flipV: boolean;
2339
- }
2340
- interface ImageAdjustments {
2341
- brightness: number;
2342
- contrast: number;
2343
- saturation: number;
2344
- exposure: number;
2345
- temperature: number;
2346
- /**
2347
- * -100 (green) to 100 (magenta), 0 is default. White-balance tint correction in Duv × 3000
2348
- * (process 2 only; the legacy process ignores it).
2349
- */
2350
- tint?: number;
2351
- blur: number;
2352
- opacity: number;
2353
- /**
2354
- * Rendering process the values are interpreted by. `2` (the latest; new edits and Reset get
2355
- * it): linear-light exposure, Bradford white balance, LUT tone curve without intermediate
2356
- * clipping. `1` or missing: the legacy 8-bit rendering, so edits saved before process
2357
- * versions existed look exactly as they did. See `normalizeProcessVersion`.
2358
- */
2359
- process?: 1 | 2;
2360
- /**
2361
- * Non-destructive adjustment layers, evaluated bottom (first) to top (last) after the base
2362
- * adjustments above, on the encoded sRGB result. Missing or empty: no layers (edits saved
2363
- * before layers existed render exactly as before).
2364
- */
2365
- layers?: AdjustmentLayer[];
2366
- }
2367
- type AdjustmentKind = 'curves' | 'levels' | 'hueSaturation' | 'vibrance' | 'colorBalance' | 'blackWhite' | 'invert' | 'posterize' | 'threshold' | 'photoFilter';
2368
- /** A Curves point; `input` and `output` are levels, 0..255. */
2369
- interface CurvePoint {
2370
- input: number;
2371
- output: number;
2372
- }
2373
- /** Curves: each channel's curve first, then the master (composite) curve, as in Photoshop. */
2374
- interface CurvesParams {
2375
- master: CurvePoint[];
2376
- red: CurvePoint[];
2377
- green: CurvePoint[];
2378
- blue: CurvePoint[];
2379
- }
2380
- /** One Levels record. Black / white points are levels (0..255); `gamma` is the midtone slider (0.1..9.99). */
2381
- interface LevelsChannel {
2382
- inBlack: number;
2383
- inWhite: number;
2384
- gamma: number;
2385
- outBlack: number;
2386
- outWhite: number;
2387
- }
2388
- /** Levels: each channel's record first, then the master record, as in Photoshop. */
2389
- interface LevelsParams {
2390
- master: LevelsChannel;
2391
- red: LevelsChannel;
2392
- green: LevelsChannel;
2393
- blue: LevelsChannel;
2394
- }
2395
- /** One of Hue/Saturation's six colour ranges (reds, yellows, greens, cyans, blues, magentas). */
2396
- interface HueRange {
2397
- /** Hue shift in degrees (-180..180). */
2398
- hue: number;
2399
- /** Saturation change in percent (-100..100). */
2400
- saturation: number;
2401
- /** Lightness change in percent (-100..100). */
2402
- lightness: number;
2403
- /** Hue degrees where the range starts fading in, is fully on, starts fading out and ends (may wrap). */
2404
- bounds: [number, number, number, number];
2405
- }
2406
- interface HueSaturationParams {
2407
- /** Master hue shift in degrees (-180..180), or the hue when colorizing (0..360). */
2408
- hue: number;
2409
- /** Percent, -100..100 (0..100 when colorizing). */
2410
- saturation: number;
2411
- /** Percent, -100..100. */
2412
- lightness: number;
2413
- colorize: boolean;
2414
- /** Six ranges: reds, yellows, greens, cyans, blues, magentas. */
2415
- ranges: HueRange[];
2416
- }
2417
- interface VibranceParams {
2418
- /** -100..100 */
2419
- vibrance: number;
2420
- /** -100..100 */
2421
- saturation: number;
2422
- }
2423
- /** Cyan–red, magenta–green, yellow–blue sliders, -100..100 each. */
2424
- type ColorBalanceTone = [number, number, number];
2425
- interface ColorBalanceParams {
2426
- shadows: ColorBalanceTone;
2427
- midtones: ColorBalanceTone;
2428
- highlights: ColorBalanceTone;
2429
- preserveLuminosity: boolean;
2430
- }
2431
- /** Black & White: percent weights of the six colours (Photoshop defaults 40 60 40 60 20 80). */
2432
- interface BlackWhiteParams {
2433
- reds: number;
2434
- yellows: number;
2435
- greens: number;
2436
- cyans: number;
2437
- blues: number;
2438
- magentas: number;
2439
- /** Tint colour (`#rrggbb`), applied like the Color blend mode, or `null` for none. */
2440
- tint: string | null;
2441
- }
2442
- interface PhotoFilterParams {
2443
- /** Filter colour, `#rrggbb`. */
2444
- color: string;
2445
- /** Percent, 0..100. */
2446
- density: number;
2447
- preserveLuminosity: boolean;
2448
- }
2449
- interface PosterizeParams {
2450
- /** 2..255 */
2451
- levels: number;
2452
- }
2453
- interface ThresholdParams {
2454
- /** 1..255: luma at or above it becomes white. */
2455
- level: number;
2456
- }
2457
- type InvertParams = Record<string, never>;
2458
- interface AdjustmentParamsMap {
2459
- curves: CurvesParams;
2460
- levels: LevelsParams;
2461
- hueSaturation: HueSaturationParams;
2462
- vibrance: VibranceParams;
2463
- colorBalance: ColorBalanceParams;
2464
- blackWhite: BlackWhiteParams;
2465
- invert: InvertParams;
2466
- posterize: PosterizeParams;
2467
- threshold: ThresholdParams;
2468
- photoFilter: PhotoFilterParams;
2469
- }
2470
- interface AdjustmentLayerBase {
2471
- id: string;
2472
- /** Optional display name. */
2473
- name?: string;
2474
- enabled: boolean;
2475
- /** 0..1 */
2476
- opacity: number;
2477
- /** How the adjusted colour is blended over the layers below. */
2478
- blend: BlendMode;
2479
- /**
2480
- * Optional layer mask (natural image pixels): where it is 0 the layer has no effect. Missing:
2481
- * the layer applies everywhere (layers saved before masks existed are unchanged).
2482
- */
2483
- mask?: AdjustmentLayerMask;
2484
- }
2485
- /**
2486
- * A layer mask: 8-bit coverage of the source image, run-length encoded (see
2487
- * `encodeSelectionRle`), plus non-destructive density and feather.
2488
- */
2489
- interface AdjustmentLayerMask {
2490
- width: number;
2491
- height: number;
2492
- /** `r1:` run-length encoding of the mask bytes. */
2493
- rle: string;
2494
- /** 0..1 (missing = 1). */
2495
- density?: number;
2496
- /** Gaussian σ in pixels (missing = 0). */
2497
- feather?: number;
2498
- /** `false` keeps the mask but ignores it. */
2499
- enabled?: boolean;
2500
- }
2501
- /** A non-destructive adjustment layer (Photoshop's Layer › New Adjustment Layer). */
2502
- type AdjustmentLayer = {
2503
- [K in AdjustmentKind]: AdjustmentLayerBase & {
2504
- kind: K;
2505
- params: AdjustmentParamsMap[K];
2506
- };
2507
- }[AdjustmentKind];
2508
- type AdjustmentLayerOf<K extends AdjustmentKind> = Extract<AdjustmentLayer, {
2509
- kind: K;
2510
- }>;
2511
- interface DepthMaskOptions {
2512
- enabled: boolean;
2513
- maskSource: string | null;
2514
- mode: 'threshold' | 'brightness';
2515
- depthRange: [number, number];
2516
- softness: number;
2517
- invert: boolean;
2518
- }
2519
- type AnnotationType = 'pen' | 'rect' | 'circle' | 'arrow' | 'line' | 'text' | 'image';
2520
- interface BaseAnnotation {
2521
- id: string;
2522
- type: AnnotationType;
2523
- x: number;
2524
- y: number;
2525
- rotation?: number;
2526
- opacity?: number;
2527
- /** Blend mode the annotation is drawn with (default `normal`). */
2528
- blend?: BlendMode;
2529
- }
2530
- interface PenAnnotation extends BaseAnnotation {
2531
- type: 'pen';
2532
- points: ImagePoint[];
2533
- strokeColor: string;
2534
- strokeWidth: number;
2535
- }
2536
- interface RectAnnotation extends BaseAnnotation {
2537
- type: 'rect';
2538
- width: number;
2539
- height: number;
2540
- strokeColor: string;
2541
- strokeWidth: number;
2542
- fillColor?: string;
2543
- cornerRadius?: number;
2544
- }
2545
- interface CircleAnnotation extends BaseAnnotation {
2546
- type: 'circle';
2547
- radiusX: number;
2548
- radiusY: number;
2549
- strokeColor: string;
2550
- strokeWidth: number;
2551
- fillColor?: string;
2552
- }
2553
- interface ArrowAnnotation extends BaseAnnotation {
2554
- type: 'arrow';
2555
- endX: number;
2556
- endY: number;
2557
- strokeColor: string;
2558
- strokeWidth: number;
2559
- }
2560
- interface LineAnnotation extends BaseAnnotation {
2561
- type: 'line';
2562
- endX: number;
2563
- endY: number;
2564
- strokeColor: string;
2565
- strokeWidth: number;
2566
- }
2567
- interface TextAnnotation extends BaseAnnotation {
2568
- type: 'text';
2569
- text: string;
2570
- fontSize: number;
2571
- fontFamily?: string;
2572
- color: string;
2573
- fontWeight?: string | number;
2574
- }
2575
- interface ImageAnnotation extends BaseAnnotation {
2576
- type: 'image';
2577
- src: string;
20
+ interface PlaneLayout {
21
+ planes: number;
2578
22
  width: number;
2579
23
  height: number;
24
+ depth: number;
25
+ /** PSB: RLE row counts are 4 bytes. */
26
+ psb: boolean;
2580
27
  }
2581
- type Annotation = PenAnnotation | RectAnnotation | CircleAnnotation | ArrowAnnotation | LineAnnotation | TextAnnotation | ImageAnnotation;
2582
- type CreateAnnotationPayload = Omit<PenAnnotation, 'id'> | Omit<RectAnnotation, 'id'> | Omit<CircleAnnotation, 'id'> | Omit<ArrowAnnotation, 'id'> | Omit<LineAnnotation, 'id'> | Omit<TextAnnotation, 'id'> | Omit<ImageAnnotation, 'id'>;
2583
- type ImageEditorTool = 'select' | 'crop' | 'pen' | 'rect' | 'circle' | 'arrow' | 'line' | 'text' | 'watermark' | 'move' | 'brush' | 'eraser' | 'mixer';
2584
- type ImageEditorFit = 'contain' | 'margin';
2585
- interface ImageEditorState {
2586
- sourceUrl: string | null;
2587
- /** Canvas (document) size in pixels: the source image's natural size. */
2588
- imageDimensions: ImageDimensions;
2589
- crop: CropBox | null;
2590
- transform: ImageTransform;
2591
- /**
2592
- * Compatibility view of the layer stack: the develop filter of the active pixel layer (or the
2593
- * Background), its blur (or `legacyOutputBlur`), the output opacity and every adjustment layer
2594
- * in stack order. Edit it with `setAdjustments` and the adjustment-layer methods.
2595
- */
2596
- adjustments: ImageAdjustments;
2597
- /** Compatibility view: the parametric depth mask of the active pixel layer (or the Background). */
2598
- depthMask: DepthMaskOptions;
2599
- /** Compatibility view: the annotation of every annotation layer, bottom to top. */
2600
- annotations: Annotation[];
2601
- selectedAnnotationId: string | null;
2602
- activeTool: ImageEditorTool;
2603
- zoom: number;
2604
- pan: ImagePoint;
2605
- isOriginalCompared: boolean;
2606
- /** Viewport fit mode: 'contain' scales to full viewport bounds; 'margin' scales to 85% with 1.0 cap (default). */
2607
- fit?: ImageEditorFit;
2608
- /**
2609
- * The active selection (8-bit coverage over the source image), or null/missing when nothing is
2610
- * selected. Recorded in undo history and saved as `selection` in `toJSON()`.
2611
- */
2612
- selection?: SelectionMask | null;
2613
- /** Quick Mask view: tint the unselected area instead of drawing marching ants (view state). */
2614
- quickMask?: boolean;
2615
- /**
2616
- * The layer stack, bottom to top. Opening an image gives one pixel layer, "Background", whose
2617
- * pixels are the source image. Layers are immutable: compare them by identity.
2618
- */
2619
- layers: ImageLayer[];
2620
- /** The layer that layer commands, painting and `setAdjustments` act on, or `null`. */
2621
- activeLayerId: string | null;
2622
- /** Whether painting targets the active layer's pixels or its mask. */
2623
- activeTarget: LayerTarget;
2624
- /** Export alpha (0..1), applied after compositing; `adjustments.opacity` mirrors it. */
2625
- outputOpacity: number;
2626
- /**
2627
- * Blur that runs after the adjustment layers, kept from v1 / v2 documents that had both so
2628
- * they render as before. New edits blur a layer instead (`blur` filter).
2629
- */
2630
- legacyOutputBlur?: number;
2631
- /** Brush settings and foreground / background colours of the paint tools (view state). */
2632
- paint: PaintOptions;
2633
- /**
2634
- * The light layer effects use when they follow the global light (Photoshop's Global Light);
2635
- * missing = angle 120°, altitude 30°. Recorded in undo history and saved in `toJSON()`.
2636
- */
2637
- globalLight?: GlobalLight;
2638
- /**
2639
- * The document's patterns (from an opened PSD), which pattern effects use by id besides the
2640
- * built-in ones. Recorded in undo history and saved in `toJSON()`.
2641
- */
2642
- patterns?: EffectPattern[];
2643
- }
2644
- /**
2645
- * A stored editor state in the document-level schema (versions 1 and 2). Documents whose layer
2646
- * stack has exactly this shape are still written this way, byte for byte.
2647
- */
2648
- interface LegacySerializedImageEditorState {
2649
- /**
2650
- * Schema version. `2` adds `adjustments.layers`; states without layers are still written as
2651
- * `1` so they round-trip unchanged. See `migrateSerializedImageEditorState`.
2652
- */
2653
- version: 1 | 2;
2654
- crop: CropBox | null;
2655
- transform: ImageTransform;
2656
- adjustments: ImageAdjustments;
2657
- depthMask: DepthMaskOptions;
2658
- annotations: Annotation[];
2659
- /** The active selection, run-length encoded. Missing when nothing is selected. */
2660
- selection?: SerializedSelection;
2661
- }
2662
- /**
2663
- * A stored editor state: the document-level schema (v1 / v2) or the layered schema (v3, see
2664
- * `SerializedLayeredImageEditorState`). `toJSON()` writes v1 / v2 while the layer stack still
2665
- * has the shape those versions describe.
2666
- */
2667
- type SerializedImageEditorState = LegacySerializedImageEditorState | SerializedLayeredImageEditorState;
2668
- interface ExportOptions {
2669
- format?: 'image/png' | 'image/jpeg' | 'image/webp';
2670
- quality?: number;
2671
- width?: number;
2672
- height?: number;
2673
- includeAnnotations?: boolean;
2674
- /** Render only these layers (groups with their children). */
2675
- layerIds?: string[];
2676
- }
2677
- interface ImageEditorOptions {
2678
- image?: string | HTMLImageElement;
2679
- initialState?: Partial<SerializedImageEditorState>;
2680
- onStateChange?: (state: ImageEditorState) => void;
2681
- maxHistoryDepth?: number;
2682
- /**
2683
- * Upper bound for the pixel data held only by undo / redo steps (tiles shared with the
2684
- * current state are free). The oldest steps are dropped first. Default 512 MiB.
2685
- */
2686
- maxHistoryBytes?: number;
2687
- /** Viewport fit mode: 'contain' scales to full viewport bounds; 'margin' scales to 85% with 1.0 cap (default). */
2688
- fit?: ImageEditorFit;
2689
- }
2690
- interface InpaintOptions {
2691
- prompt: string;
2692
- imageDataUrl: string;
2693
- maskDataUrl?: string;
2694
- cropBox?: CropBox | null;
2695
- }
2696
- interface RemoveBackgroundOptions {
2697
- imageDataUrl: string;
2698
- }
2699
- type InpaintHook = (options: InpaintOptions) => Promise<string | void> | string | void;
2700
- type RemoveBackgroundHook = (options: RemoveBackgroundOptions) => Promise<string | void> | string | void;
2701
- interface ImageEditorAIHooks {
2702
- onInpaint?: InpaintHook;
2703
- onRemoveBackground?: RemoveBackgroundHook;
2704
- }
28
+ /** Decodes planar channel data (`planes` planes of `height` rows each). */
29
+ declare function decodePlanes(compression: number, data: Uint8Array, l: PlaneLayout): Uint8Array;
30
+ /** RLE-encodes planar data: row counts (u16, or u32 in PSB), then the packed rows. */
31
+ declare function encodeRle(decoded: Uint8Array, l: PlaneLayout): Uint8Array;
2705
32
 
2706
33
  /**
2707
34
  * Applies color and tone adjustments (brightness, contrast, saturation, exposure, temperature, tint,
@@ -3141,6 +468,12 @@ interface ImageEditorToolProviderOptions {
3141
468
  * `flip_image`, `undo_image`, `redo_image` (see `createImageEditTools`).
3142
469
  * - Free Transform: `get_transform_frame`, `transform_layer`, `warp_layer`, `transform_selection`,
3143
470
  * `flip_layer`, `rotate_layer_90` (see `createImageTransformTools`).
471
+ * - Smart objects and smart filters: `get_smart_object`, `convert_to_smart_object`,
472
+ * `rasterize_smart_object`, `set_smart_object_transform`, `replace_smart_object_contents`,
473
+ * `export_smart_object_contents`, `copy_smart_object`, `edit_smart_object_contents`,
474
+ * `close_smart_object_contents`, `add_smart_filter`, `update_smart_filter`, `remove_smart_filter`,
475
+ * `move_smart_filter`, `set_smart_filters_enabled`, `set_smart_filter_mask` (see
476
+ * `createImageSmartObjectTools`).
3144
477
  */
3145
478
  declare function createImageEditorToolProvider(controller: ImageEditorController, options?: ImageEditorToolProviderOptions): AgentToolProvider;
3146
479
 
@@ -3520,6 +853,187 @@ declare function addToHistogram(h: ImageHistogram, data: ArrayLike<number>, stri
3520
853
  /** Sums histograms (and recomputes `max`). */
3521
854
  declare function sumHistograms(parts: Iterable<ImageHistogram>): ImageHistogram;
3522
855
 
856
+ /**
857
+ * How far beyond the canvas a smart object is rendered (document pixels): enough for any layer
858
+ * effect to see the parts just outside the canvas. Further out a smart object is not drawn.
859
+ */
860
+ declare const SMART_RENDER_MARGIN = 512;
861
+ /** The document canvas a smart object renders for. */
862
+ interface SmartCanvas {
863
+ width: number;
864
+ height: number;
865
+ }
866
+ /** A fresh contents id (independent contents). */
867
+ declare function newContentsId(): string;
868
+ /** The contents' rectangle in its own pixels. */
869
+ declare function contentsBox(contents: SmartContents): CropBox;
870
+ /** A smart object's placement as Free Transform geometry (the frame is the contents' rectangle). */
871
+ declare function placementGeometry(layer: Pick<SmartObjectLayer, 'contents' | 'placement'>): FreeTransformGeometry;
872
+ /** The placement that draws the contents 1:1 with their top-left corner at (`x`, `y`). */
873
+ declare function placementAt(contents: Pick<SmartContents, 'width' | 'height'>, x: number, y: number): SmartPlacement;
874
+ /** Whether the contents can be rendered here (decoded pixels or a layer document). */
875
+ declare function isContentsDecoded(contents: SmartContents): boolean;
876
+ /** The layer with `id`, which must be a smart object. */
877
+ declare function requireSmartObject(layers: readonly ImageLayer[], id: string): SmartObjectLayer;
878
+ /**
879
+ * The contents as pixels at (0, 0) in their own space: the raster, or the nested document
880
+ * composited at its size (annotation layers inside need a canvas and are left out). Memoised.
881
+ */
882
+ declare function contentsSurface(contents: SmartContents): PixelSurface;
883
+ /** Raster contents from RGBA pixels. */
884
+ declare function rasterContents(pixels: {
885
+ width: number;
886
+ height: number;
887
+ data: ArrayLike<number>;
888
+ }, name: string, id?: string): SmartContents;
889
+ /** Document contents from layers on a `width × height` canvas. */
890
+ declare function documentContents(document: SmartDocument, width: number, height: number, name: string, id?: string): SmartContents;
891
+ /** How a render runs: full quality (default), or a fast preview. */
892
+ interface SmartRenderOptions {
893
+ /** Preview block size (a power of two): sample a reduced copy of the contents once per block. */
894
+ step?: number;
895
+ /** Only this part of the document (the visible area). */
896
+ clip?: RasterRect;
897
+ /** Leave the smart filters out (previews while transforming). */
898
+ skipFilters?: boolean;
899
+ /** Reduced copies of the contents by factor, kept by the caller between previews. */
900
+ reduced?: Map<number, PixelSurface>;
901
+ }
902
+ /** The contents placed in the document (no filters), clipped to the canvas grown by the render margin. */
903
+ declare function placeContents(layer: Pick<SmartObjectLayer, 'contents' | 'placement'>, canvas: SmartCanvas, options?: SmartRenderOptions): PixelSurface;
904
+ /** The filters of a stack that change pixels (the stack enabled, each filter active, a modelled kind). */
905
+ declare function activeSmartFilters(stack: SmartFilterStack | undefined): Array<SmartFilter & LayerFilter>;
906
+ /** A filter mask's coverage over the canvas (0..1), after density and feather; `null` reveals all. */
907
+ declare function filterMaskCoverage(mask: RasterMask | undefined, canvas: SmartCanvas): Float32Array | null;
908
+ /**
909
+ * Runs a smart filter stack over the placed contents, over the canvas (spatial filters clamp at
910
+ * its edges, as a pixel layer's filters do): each filter filters the result below it, and its own
911
+ * blend mode and opacity mix its result with that input. The filter mask then mixes the filtered
912
+ * result with the unfiltered contents. Returns `placed` itself when no filter is active.
913
+ */
914
+ declare function applySmartFilters(placed: PixelSurface, stack: SmartFilterStack | undefined, canvas: SmartCanvas): PixelSurface;
915
+ /** A smart object's pixels: the contents through the placement, then the smart filters. */
916
+ declare function renderSmartObject(layer: Pick<SmartObjectLayer, 'contents' | 'placement' | 'smartFilters'>, canvas: SmartCanvas, options?: SmartRenderOptions): PixelSurface;
917
+ /** The layer with its pixels rendered again (refused when the contents are not decoded). */
918
+ declare function rerender(layer: SmartObjectLayer, canvas: SmartCanvas, action?: string): SmartObjectLayer;
919
+ /** Validates a placement for contents of `width × height`; returns a clean copy. */
920
+ declare function normalizePlacement(raw: SmartPlacement, contents: Pick<SmartContents, 'width' | 'height'>): SmartPlacement;
921
+ /**
922
+ * Sets a smart object's placement (corners, warp, interpolation) and renders it again from its
923
+ * contents. A linked layer mask and filter mask follow a warp-free change. Returns the stack and
924
+ * whether the masks moved.
925
+ */
926
+ declare function setSmartPlacement(layers: readonly ImageLayer[], id: string, placement: SmartPlacement, canvas: SmartCanvas): {
927
+ layers: ImageLayer[];
928
+ layer: SmartObjectLayer;
929
+ masksMoved: boolean;
930
+ };
931
+ /**
932
+ * Moves a smart object by whole pixels (the move tool): its corners, a linked mask and filter mask
933
+ * move with it. Without spatial smart filters the rendered pixels are shifted, not resampled.
934
+ */
935
+ declare function offsetSmartObject(layers: readonly ImageLayer[], id: string, dx: number, dy: number, canvas: SmartCanvas): ImageLayer[];
936
+ interface ConvertOptions {
937
+ /** The pixels of a pixel layer (resolves the Background's document source). */
938
+ surfaceOf(layer: PixelLayer): PixelSurface;
939
+ /** Name of the new layer (default: the top layer's name). */
940
+ name?: string;
941
+ }
942
+ /**
943
+ * Layer › Smart Objects › Convert to Smart Object: sibling layers become one smart object at the
944
+ * position of the topmost one.
945
+ *
946
+ * - One pixel layer becomes raster contents (its pixels, cropped to their bounds) and keeps its
947
+ * id, name, visibility, opacity, fill, blend, clipping, mask and effects; its filters become
948
+ * smart filters. It renders exactly as before.
949
+ * - Anything else (several layers, a group, an adjustment, a smart object) becomes a nested
950
+ * document holding the layers as they were, sized to their bounds (effects included), and the
951
+ * new layer is a plain Normal layer named after the top one, rendering the isolated composite.
952
+ *
953
+ * Returns the stack, the new layer and its contents.
954
+ */
955
+ declare function convertToSmartObject(layers: readonly ImageLayer[], ids: readonly string[], canvas: SmartCanvas, options: ConvertOptions): {
956
+ layers: ImageLayer[];
957
+ layer: SmartObjectLayer;
958
+ };
959
+ /**
960
+ * Layer › Smart Objects › Rasterize: the smart object becomes a pixel layer holding what it
961
+ * renders (filters baked), with its mask, effects, blend, opacity and fill. Same id.
962
+ */
963
+ declare function rasterizeSmartObject(layers: readonly ImageLayer[], id: string): {
964
+ layers: ImageLayer[];
965
+ layer: PixelLayer;
966
+ };
967
+ /**
968
+ * Layer › Smart Objects › New Smart Object via Copy (`linked: false`, fresh contents that edit
969
+ * independently) or a linked duplicate (`linked: true`, shared contents), directly above.
970
+ */
971
+ declare function copySmartObject(layers: readonly ImageLayer[], id: string, linked: boolean, name?: string): {
972
+ layers: ImageLayer[];
973
+ layer: SmartObjectLayer;
974
+ };
975
+ /** Ids of the smart objects in the stack placed from contents `contentsId` (linked instances), bottom first. */
976
+ declare function instancesOf(layers: readonly ImageLayer[], contentsId: string): string[];
977
+ /**
978
+ * Puts new contents into every instance of `contentsId` and renders them again. With
979
+ * `keepPlacement` false (Replace Contents of a different size), each instance keeps its scale and
980
+ * rotation about the contents' centre, and a warp is stretched to the new size.
981
+ */
982
+ declare function replaceContents(layers: readonly ImageLayer[], contentsId: string, contents: SmartContents, canvas: SmartCanvas): {
983
+ layers: ImageLayer[];
984
+ ids: string[];
985
+ };
986
+ /** A clean smart filter from loose input: a `develop` or `blur` filter plus blend and opacity. */
987
+ declare function normalizeSmartFilter(raw: Record<string, unknown> & {
988
+ kind: string;
989
+ }, id?: string): SmartFilter;
990
+ /** Adds a smart filter at `index` (default the top). Returns the stack and the filter. */
991
+ declare function addSmartFilter(layers: readonly ImageLayer[], id: string, filter: SmartFilter, canvas: SmartCanvas, index?: number): {
992
+ layers: ImageLayer[];
993
+ layer: SmartObjectLayer;
994
+ filter: SmartFilter;
995
+ };
996
+ /** Changes one smart filter (settings, enabled, blend, opacity; validated). */
997
+ declare function updateSmartFilter(layers: readonly ImageLayer[], id: string, filterId: string, changes: Record<string, unknown>, canvas: SmartCanvas): {
998
+ layers: ImageLayer[];
999
+ layer: SmartObjectLayer;
1000
+ filter: SmartFilter;
1001
+ };
1002
+ /** Removes one smart filter. */
1003
+ declare function removeSmartFilter(layers: readonly ImageLayer[], id: string, filterId: string, canvas: SmartCanvas): {
1004
+ layers: ImageLayer[];
1005
+ layer: SmartObjectLayer;
1006
+ };
1007
+ /** Moves one smart filter to `index` (0 = bottom, applied first). */
1008
+ declare function moveSmartFilter(layers: readonly ImageLayer[], id: string, filterId: string, index: number, canvas: SmartCanvas): {
1009
+ layers: ImageLayer[];
1010
+ layer: SmartObjectLayer;
1011
+ };
1012
+ /** Turns the whole smart filter stack on or off (each filter keeps its own switch). */
1013
+ declare function setSmartFiltersEnabled(layers: readonly ImageLayer[], id: string, enabled: boolean, canvas: SmartCanvas): {
1014
+ layers: ImageLayer[];
1015
+ layer: SmartObjectLayer;
1016
+ };
1017
+ /** Sets or removes (`null`) the smart filter mask. */
1018
+ declare function setSmartFilterMask(layers: readonly ImageLayer[], id: string, mask: RasterMask | null, canvas: SmartCanvas): {
1019
+ layers: ImageLayer[];
1020
+ layer: SmartObjectLayer;
1021
+ };
1022
+ /** A smart object's filter mask surface replaced (painting it), rendered again. */
1023
+ declare function withFilterMaskSurface(layer: SmartObjectLayer, surface: PixelSurface, canvas: SmartCanvas): SmartObjectLayer;
1024
+ /** The transformed outline of a smart object's contents (document bounds, warp included). */
1025
+ declare function placementBounds(layer: Pick<SmartObjectLayer, 'contents' | 'placement'>): CropBox | null;
1026
+
1027
+ /**
1028
+ * Agent tools for smart objects in the image editor: `get_smart_object`, `convert_to_smart_object`,
1029
+ * `rasterize_smart_object`, `set_smart_object_transform`, `replace_smart_object_contents`,
1030
+ * `export_smart_object_contents`, `copy_smart_object`, `edit_smart_object_contents`,
1031
+ * `close_smart_object_contents`, and the smart filter stack: `add_smart_filter`,
1032
+ * `update_smart_filter`, `remove_smart_filter`, `move_smart_filter`, `set_smart_filters_enabled`,
1033
+ * `set_smart_filter_mask`. Every write is one undo step, validates first and returns what changed.
1034
+ */
1035
+ declare function createImageSmartObjectTools(controller: ImageEditorController): AgentTool[];
1036
+
3523
1037
  /**
3524
1038
  * The layers panel's view model, shared by the React and Svelte panels: the rows to show (top of
3525
1039
  * the stack first, groups indented, collapsed groups hiding their children), where a drop lands,
@@ -3550,7 +1064,7 @@ type DropZone = 'above' | 'below' | 'inside';
3550
1064
  declare function dropZone(fraction: number, isGroup: boolean): DropZone;
3551
1065
  /** The placement for `move_layer` when `dragId` is dropped on row `targetId` in `zone`, or `null` for a no-op. */
3552
1066
  declare function dropPlacement(layers: readonly ImageLayer[], dragId: string, targetId: string, zone: DropZone): LayerPlacement | null;
3553
- type LayerMenuAction = 'new-layer' | 'new-group' | 'duplicate' | 'delete' | 'group-selected' | 'ungroup' | 'merge-down' | 'merge-visible' | 'flatten' | 'via-copy' | 'via-cut' | 'add-mask' | 'add-mask-selection' | 'apply-mask' | 'delete-mask' | 'toggle-mask' | 'toggle-mask-link' | 'toggle-clip' | 'rasterize';
1067
+ type LayerMenuAction = 'new-layer' | 'new-group' | 'duplicate' | 'delete' | 'group-selected' | 'ungroup' | 'merge-down' | 'merge-visible' | 'flatten' | 'via-copy' | 'via-cut' | 'add-mask' | 'add-mask-selection' | 'apply-mask' | 'delete-mask' | 'toggle-mask' | 'toggle-mask-link' | 'toggle-clip' | 'rasterize' | 'convert-smart' | 'edit-contents' | 'smart-via-copy' | 'add-filter-mask';
3554
1068
  interface LayerMenuItem {
3555
1069
  action: LayerMenuAction;
3556
1070
  label: string;
@@ -3560,6 +1074,18 @@ interface LayerMenuItem {
3560
1074
  declare function layerMenu(controller: ImageEditorController): LayerMenuItem[];
3561
1075
  /** Runs a menu action on the active layer. Resolves to the error message when it was refused. */
3562
1076
  declare function runLayerMenuAction(controller: ImageEditorController, action: LayerMenuAction): Promise<string | null>;
1077
+ /** One row of a smart object's filter list (Photoshop shows them under the layer, top filter first). */
1078
+ interface SmartFilterRow {
1079
+ filter: SmartFilter;
1080
+ /** Display name: Develop, Blur (radius), or the Photoshop filter's name. */
1081
+ label: string;
1082
+ /** Index in the stack, 0 = bottom (applied first). */
1083
+ index: number;
1084
+ /** False for Photoshop filters we keep but do not draw. */
1085
+ drawn: boolean;
1086
+ }
1087
+ /** The filter rows of a smart object, top filter first (empty when it has none). */
1088
+ declare function smartFilterRows(layer: ImageLayer): SmartFilterRow[];
3563
1089
 
3564
1090
  /**
3565
1091
  * The layer effects section's view model, shared by the React and Svelte panels: whether a layer
@@ -3857,31 +1383,6 @@ declare function writeAdjustmentBlock<K extends AdjustmentKind>(kind: K, params:
3857
1383
  data: Uint8Array;
3858
1384
  };
3859
1385
 
3860
- interface PsdExportInput {
3861
- width: number;
3862
- height: number;
3863
- /** Prepared stack, bottom to top. */
3864
- layers: readonly ImageLayer[];
3865
- /** The composite, `width × height` RGBA, written as the merged image. */
3866
- merged: ArrayLike<number>;
3867
- /** Pixels per inch (default 72). */
3868
- resolution?: number;
3869
- /** The document's patterns; those the effects use are embedded (built-in ones too). */
3870
- patterns?: readonly EffectPattern[];
3871
- /** Written as image resources 1037 and 1049. */
3872
- globalLight?: GlobalLight;
3873
- }
3874
- interface PsdExportResult {
3875
- bytes: Uint8Array;
3876
- psb: boolean;
3877
- /** Layer records written (group folders and dividers included). */
3878
- records: number;
3879
- /** One sentence per loss, naming the layers. */
3880
- warnings: string[];
3881
- }
3882
- /** Writes the prepared stack as PSD (or PSB) bytes. */
3883
- declare function exportPsd(input: PsdExportInput): PsdExportResult;
3884
-
3885
1386
  interface ParsedLayerEffects {
3886
1387
  effects: LayerEffects;
3887
1388
  /** What could not be held exactly (empty when the mapping is exact). */
@@ -4192,4 +1693,4 @@ declare class FreeTransformTool {
4192
1693
  key(e: ShortcutEvent): boolean;
4193
1694
  }
4194
1695
 
4195
- export { ADJUSTMENT_KEYS, ADJUSTMENT_KINDS, ADJUSTMENT_LAYER_CONTROLS, ADJUSTMENT_LAYER_OPACITY_CONTROL, ADJUSTMENT_LUT_SIZE, type AIResultOptions, AS_SHOT_KELVIN, type AdjustmentKind, type AdjustmentKindInfo, type AdjustmentLayer, type AdjustmentLayerBase, type AdjustmentLayerInit, type AdjustmentLayerMask, type AdjustmentLayerNode, type AdjustmentLayerOf, type AdjustmentLayerUpdate, type AdjustmentParamsMap, AffineMatrix, type Annotation, type AnnotationLayer, type AnnotationPlacement, type AnnotationType, type ArrowAnnotation, type AspectRatio, BACKGROUND_LAYER_ID, BACKGROUND_LAYER_NAME, BLUR_FILTER_ID, BRUSH_OPTION_CONTROLS, type BaseAnnotation, type BlackWhiteParams, BlendMode, type BlurFilter, BrushSettings, type Chromaticity, type CircleAnnotation, type ColorBalanceParams, type ColorBalanceTone, type ColorDistance, type ColorRangeOptions, type ColorRangeSample, CompositorOptions, type CompositorSources, type ControlSection, type ControlSpec, type ControlTrack, type CreateAnnotationPayload, type CropBox, type CropHandle, type CurvePoint, type CurvesParams, D50, D65, DEFAULT_ADJUSTMENTS, DEFAULT_DEPTH_MASK, DEFAULT_REFINE_EDGE_PARAMS, DEFAULT_SELECTION_TOOL_OPTIONS, DEFAULT_TRANSFORM, DEVELOP_FILTER_ID, type DepthMaskOptions, type DescValue, type Descriptor, type DeserializeContext, type DevelopFilter, type DevelopSettings, type DropZone, EMPTY_DISTANCE, type EffectControl, EffectPattern, type ExportOptions, FREE_TRANSFORM_CONTENTS, FREE_TRANSFORM_FIELDS, FREE_TRANSFORM_MODES, FREE_TRANSFORM_MODE_OPTIONS, type FillOptions, type FreeTransformBar, type FreeTransformContent, type FreeTransformField, type FreeTransformGeometry, type FreeTransformHost, type FreeTransformInit, type FreeTransformMode, type FreeTransformPreview, type FreeTransformResult, FreeTransformSession, FreeTransformTool, type FreeTransformToolOptions, GUIDED_FILTER_EPS, type GestureModifiers, GlobalLight, type GroupLayer, HISTOGRAM_BINS, HUE_RANGE_LABELS, type HistogramChannel, type HistoryEntryHandle, Homography, type HueRange, type HueSaturationParams, IDENTITY_MATRIX3, IMAGE_ADJUSTMENT_CONTROLS, IMAGE_EDITOR_SCHEMA_VERSION, IMAGE_EDITOR_STATE_VERSION, type ImageAdjustments, type ImageAnnotation, type ImageDimensions, type ImageEditorAIHooks, type ImageEditorAssetStore, ImageEditorController, type ImageEditorDocumentLoad, type ImageEditorFit, type ImageEditorOptions, ImageEditorRenderer, type ImageEditorState, type ImageEditorTool, type ImageEditorToolProviderOptions, type ImageHistogram, type ImageLayer, type ImageLayerType, type ImagePoint, type ImageProcessVersion, type ImageProjection, type ImageTransform, type InpaintHook, type InpaintOptions, Interpolation, type InvertParams, LATEST_PROCESS_VERSION, LAYERED_SCHEMA_VERSION, LAYER_EFFECT_MENU, LEGACY_PROCESS_VERSION, LUMA_709, type LayerBase, type LayerBlendMode, LayerCompositor, LayerEffect, LayerEffectKind, type LayerEffectRow, LayerEffects, type LayerEffectsPanelModel, type LayerFilter, type LayerFilterKind, type LayerLocation, LayerLocks, type LayerMaskProps, type LayerMenuAction, type LayerMenuItem, LayerOperationError, type LayerPanelRow, type LayerPlacement, type LayerProperties, type LayerSourcesHost, type LayerStack, type LayerTarget, type LegacyParts, type LegacySerializedImageEditorState, type LegacyViewResult, type LevelsChannel, type LevelsParams, type LineAnnotation, MAX_KELVIN, MIN_KELVIN, MIRED_PER_TEMPERATURE_UNIT, MIXER_MIXING_OPTIONS, MIXER_OPTION_CONTROLS, type MagicWandOptions, type Matrix3, MixerLoad, MixerSettings, MixerStroke, type MixerStrokeInit, MixerTarget, type MosaicImageDataLike, type MosaicRegion, PAINT_TOOLS, PATTERN_BLOCK_KEYS, PSD_BLEND_KEYS, PSD_FILE_ACCEPT, PaintGesture, type PaintOptions, type PaintPointerSample, type PaintStrokeResult, PaintStrokeSession, type PaintTool, type ParsedAdjustment, type ParsedLayerEffects, type PenAnnotation, type PhotoFilterParams, type PixelBuffer, type PixelLayer, type PixelLayerInit, type PixelOp, PixelSurface, type PlaneLayout, type PosterizeParams, type PsdChannel, PsdError, type PsdExportInput, type PsdExportResult, type PsdFile, type PsdHeader, type PsdImportOptions, type PsdImportResult, type PsdLayerMask, type PsdLayerRecord, type PsdLayerSummary, type PsdPattern, type PsdRect, type PsdResource, type PsdTaggedBlock, type PsdTreeNode, Quad, type QuickMaskStyle, REFINE_EDGE_CONTROLS, type RasterMask, type RectAnnotation, type ReferenceItem, type RefineEdgeControl, type RefineEdgeParams, type RemoveBackgroundHook, type RemoveBackgroundOptions, type RenderOptions, type RouteInput, SELECTION_MODES, SELECTION_MODE_LABELS, SELECTION_MODIFY_OPS, SELECTION_TOOLS, SUPPORTED_ADJUSTMENT_KEYS, type SampleOptions, type SelectionChannel, type SelectionCommandOptions, SelectionGesture, type SelectionMask, type SelectionMode, type SelectionModifyOp, type SelectionToolKind, type SelectionToolOptions, type SerializeContext, type SerializedAdjustmentLayer, type SerializedAnnotationLayer, type SerializedGroupLayer, type SerializedImageEditorState, type SerializedLayer, type SerializedLayerEffects, type SerializedLayeredImageEditorState, type SerializedPattern, type SerializedPixelLayer, type SerializedRasterMask, type SerializedSelection, type ShapeSelectionOptions, type ShortcutEvent, StrokeApply, StrokeCoverage, type StrokeInit, StrokePoint, type StrokeTool, TINT_SCALE, TONE_LUT_SIZE, TONE_RANGE_PRESETS, TRANSFORM_ANCHORS, type TextAnnotation, type ThresholdParams, TiledSurface, type ToneRangePreset, type TransformAnchor, type TransformHandle, type TransformModifiers, type TransformOverlay, type TransformParams, type TransformReadout, type UnitLevels, VIBRANCE_GREY, Vec2, type VibranceParams, type ViewportMetrics, WARP_GRID_OPTIONS, WARP_STYLE_OPTIONS, type WarpBar, WarpMesh, WarpPreset, WarpStyle, XYZ_D50_TO_SRGB, activeAdjustmentLayers, addLayerEffect, addLayerFilter, addToHistogram, adjustmentKindLabel, adjustmentLayersKey, adjustmentNodeAsLayer, adjustmentNodeFromLegacy, anchorPoint, annotationLayerFor, annotationLayerName, applyAdjustmentLayers, applyAdjustments, applyBoxBlur, applyDepthMask, applyImageProjectionToContext, applyLegacyAdjustments, applyMatrix3, applyOutputStage, applyParams, applyProcess2Adjustments, applyRegionBlur, applyRegionMosaic, backgroundLayer, baseProjection, blackWhiteGray, blurFilter, borderCoverage, boxMean, boxPointOf, boxToCurvePoint, bradfordAdaptation, buildLayerMaskPlanes, buildToneLut, calculateCropDrag, canvasToImagePoint, clampControlValue, clampCropToImage, colorBalanceChannel, colorRange, combineSelections, compileAdjustmentLayer, computeHistogram, computeSelectionBounds, contractCoverage, controlPosition, controlTrackBackground, cornersFromMatrix, coverageToByte, coveringRect, createAdjustmentLayer, createImageCaptureSurface, createImageEditTools, createImageEditorToolProvider, createImageEffectTools, createImageLayerTools, createImagePaintTools, createImagePsdTools, createImageSelectionTools, createImageTransformTools, createSelectionMask, curveLutFromLevels, curvePointToBox, curveSvgPath, decodeLayerChannel, decodeLayerMask, decodeMergedImage, decodePlanes, decodePngDataUrl, decodeSelectionRle, defaultAdjustmentParams, depthMaskAlpha, depthRasterMask, describeLayer, describeLayerEffects, describeSelection, describeTransform, deserializeEffects, deserializeLayer, deserializeLayers, deserializePatterns, deserializeSelection, developFilter, developFromAdjustments, developTarget, distanceTransform, downloadPsd, dropPlacement, dropZone, duplicateLayer, edgeWidth, effectControlChange, ellipsePoints, ellipseSelection, emptyHistogram, encodeRle, encodeSelectionRle, encodeSurface, evaluateAdjustmentLayers, expandCoverage, exportPsd, featherCoverage, findAdjustmentControl, findLayerControl, flipCorners, formatControlValue, fullSelection, geometryHomography, getAnnotationBounds, getControlPath, getCropCursor, getRotatedSize, getViewportMetrics, getViewportProjection, globalImageCache, greyMorphology, groupLayers, guidePlanes, guidedFilterColor, handlePaintShortcut, hasResampledLegacyMask, hasWarp, hashMaskContent, hexToRgb, histogramPath, hitTestAnnotation, hitTestCrop, hitTestCurvePoint, hslToRgb, hueRange, hueRangeTables, hueRangeWeight, hueSaturation, identityCurve, identityLevels, identityTransform, imageEditorStateMigrations, imageToCanvasPoint, importPsd, insertCurvePoint, invertMatrix3, invertSelection, isActiveFilter, isAdjustmentKind, isDefaultDepthMask, isIdentityTransform, isLegacyShape, isPaintTool, isQuarterTurn, isQuarterTurnSwapped, isSelectionEmpty, isSelectionMode, isSpatialFilter, isTransformAnchor, isValidWarp, kelvinToTemperature, layerBadge, layerEffectControls, layerEffectsBadge, layerEffectsOf, layerEffectsPanel, layerLabel, layerMaskCoverage, layerMaskFromSelection, layerMaskKey, layerMenu, layerName, layerPanelRows, layerTree, layerTypeLabel, layersFromLegacy, legacyAdjustmentLayer, legacyMaskOf, legacyView, levelsValue, linearSrgbToXy, linearToSrgb, loadImageEditorDocument, magicWand, mapCropHandle, maskSummary, matrixFromCorners, matrixFromParams, migrateSerializedImageEditorState, migrateToLayeredState, mixerLoadResult, modifySelection, moveCurvePoint, moveLayer, mulMatrix3, needsLegacyBase, neutralHueRange, newLayerId, normalizeAdjustmentLayer, normalizeAdjustmentLayers, normalizeAngle, normalizeFilter, normalizeLayerMask, normalizeProcessVersion, normalizeRect, normalizeRefineEdgeParams, normalizeStoredAdjustments, offsetLayer, openPsdFile, parseAdjustmentBlock, parseBlend, parseColor, parseLfx2, parseLrfx, parsePatternBlock, parseSelectionMode, parseVersionedDescriptor, photoFilterMatrix, pixelLayerBounds, pixelLayers, placeLayer, pointerPressure, polygonCoverage, polygonSelection, posterizeValue, presetWarp, previewStep, projectImagePoint, projectImageRect, projectMaskCoverage, projectQuarterTurn, psdBytesFromBase64, psdFileName, psdPatternToEffectPattern, psdToLayers, quickMaskPixels, rangeLightness, rasterMaskFromLegacy, readAdjustmentControls, readPsd, rectSelection, referencePoint, refineCoverage, refineEdgeHalo, refineSelection, removeAlpha, removeCurvePoint, removeLayer, removeLayerEffect, removeLayerFilter, renderLayeredBase, requireLayer, requireUnlocked, resizePixels, resizeSelection, resolveExternalAssets, resolveMosaicRegionBounds, rgbToGray, rgbToHsl, rgbUnitToHex, runLayerMenuAction, sampleLut, sampleToneLut, selectionArea, selectionFromCoverage, selectionFromPixels, selectionModeFromModifiers, selectionOutline, selectionToCoverage, selectionToPixels, selectionValueAt, serializeEffects, serializeLayer, serializeLayers, serializeLayersExternal, serializePatterns, serializeSelection, setControlPath, setLayerEffects, setLayerEffectsEnabled, setLayerMask, setLayerProperties, shiftCoverage, smoothCoverage, splitOverlayAnnotations, srgb8ToLab, srgbToLinear, sumHistograms, tempTintToXy, temperatureToKelvin, toHex, toneCurve, toneLuts, toneRange, transformHomography, transformMap, transformedBox, transformedPoint, ungroupLayer, unionRect, unprojectCanvasPoint, updateLayerEffect, updateLayerFilter, updateLayerMaskProps, uvToXy, versionedDescriptorBytes, vibranceLinear, vibrancePixel, wbMatrix, whiteBalanceFromSample, whiteBalanceMatrix, withNewIds, writeAdjustmentBlock, writeLfx2, writePatternBlock, writePsd, xyToTempTint, xyToUv };
1696
+ export { ADJUSTMENT_KEYS, ADJUSTMENT_KINDS, ADJUSTMENT_LAYER_CONTROLS, ADJUSTMENT_LAYER_OPACITY_CONTROL, ADJUSTMENT_LUT_SIZE, AS_SHOT_KELVIN, AdjustmentKind, type AdjustmentKindInfo, AdjustmentLayer, AdjustmentLayerMask, AdjustmentLayerNode, AdjustmentLayerOf, AdjustmentParamsMap, Annotation, AnnotationLayer, BACKGROUND_LAYER_ID, BACKGROUND_LAYER_NAME, BLUR_FILTER_ID, BRUSH_OPTION_CONTROLS, BlendMode, type Chromaticity, ColorDistance, CompositorSources, type ControlSection, type ControlSpec, type ControlTrack, type ConvertOptions, CropBox, CurvePoint, D50, D65, DEFAULT_SELECTION_TOOL_OPTIONS, DEVELOP_FILTER_ID, DepthMaskOptions, type DescValue, type Descriptor, DevelopFilter, type DropZone, type EffectControl, EffectPattern, FREE_TRANSFORM_FIELDS, FREE_TRANSFORM_MODE_OPTIONS, type FreeTransformBar, type FreeTransformField, FreeTransformGeometry, FreeTransformInit, FreeTransformMode, FreeTransformResult, FreeTransformSession, FreeTransformTool, type FreeTransformToolOptions, type GestureModifiers, HUE_RANGE_LABELS, HueRange, IDENTITY_MATRIX3, IMAGE_ADJUSTMENT_CONTROLS, IMAGE_EDITOR_STATE_VERSION, ImageAdjustments, ImageEditorController, type ImageEditorDocumentLoad, type ImageEditorToolProviderOptions, ImageHistogram, ImageLayer, ImagePoint, type ImageProcessVersion, ImageProjection, ImageTransform, Interpolation, LATEST_PROCESS_VERSION, LAYER_EFFECT_MENU, LEGACY_PROCESS_VERSION, LUMA_709, LayerCompositor, LayerEffect, LayerEffectKind, type LayerEffectRow, LayerEffects, type LayerEffectsPanelModel, LayerFilter, type LayerMenuAction, type LayerMenuItem, type LayerPanelRow, LayerPlacement, type LayerStack, type LegacyParts, type LegacyViewResult, LevelsChannel, MAX_KELVIN, MIN_KELVIN, MIRED_PER_TEMPERATURE_UNIT, MIXER_MIXING_OPTIONS, MIXER_OPTION_CONTROLS, type Matrix3, MixerLoad, MixerSettings, type MosaicImageDataLike, type MosaicRegion, PAINT_TOOLS, PATTERN_BLOCK_KEYS, PSD_FILE_ACCEPT, PaintGesture, type PaintPointerSample, type PaintTool, type ParsedAdjustment, type ParsedLayerEffects, PixelLayer, type PixelOp, PixelSurface, type PlaneLayout, PsdError, type PsdPattern, Quad, type QuickMaskStyle, REFINE_EDGE_CONTROLS, RasterMask, RasterRect, type ReferenceItem, type RefineEdgeControl, RefineEdgeParams, type RouteInput, SELECTION_MODE_LABELS, SELECTION_TOOLS, SMART_RENDER_MARGIN, SUPPORTED_ADJUSTMENT_KEYS, SelectionGesture, SelectionMask, SelectionMode, type SelectionToolKind, type SelectionToolOptions, SerializedImageEditorState, type ShortcutEvent, type SmartCanvas, SmartContents, SmartDocument, SmartFilter, type SmartFilterRow, SmartFilterStack, SmartObjectLayer, SmartPlacement, type SmartRenderOptions, TINT_SCALE, TONE_LUT_SIZE, TransformAnchor, type TransformHandle, type TransformModifiers, type TransformOverlay, type UnitLevels, VIBRANCE_GREY, Vec2, WARP_GRID_OPTIONS, WARP_STYLE_OPTIONS, type WarpBar, WarpMesh, WarpStyle, XYZ_D50_TO_SRGB, activeAdjustmentLayers, activeSmartFilters, addSmartFilter, addToHistogram, adjustmentKindLabel, adjustmentLayersKey, adjustmentNodeFromLegacy, annotationLayerFor, annotationLayerName, applyAdjustmentLayers, applyAdjustments, applyBoxBlur, applyDepthMask, applyLegacyAdjustments, applyMatrix3, applyOutputStage, applyProcess2Adjustments, applyRegionBlur, applyRegionMosaic, applySmartFilters, backgroundLayer, baseProjection, blackWhiteGray, boxToCurvePoint, bradfordAdaptation, buildToneLut, clampControlValue, colorBalanceChannel, compileAdjustmentLayer, contentsBox, contentsSurface, controlPosition, controlTrackBackground, convertToSmartObject, copySmartObject, coveringRect, createAdjustmentLayer, createImageCaptureSurface, createImageEditTools, createImageEditorToolProvider, createImageEffectTools, createImageLayerTools, createImagePaintTools, createImagePsdTools, createImageSelectionTools, createImageSmartObjectTools, createImageTransformTools, curveLutFromLevels, curvePointToBox, curveSvgPath, decodePlanes, defaultAdjustmentParams, depthRasterMask, describeLayer, describeLayerEffects, describeSelection, developFromAdjustments, developTarget, documentContents, downloadPsd, dropPlacement, dropZone, effectControlChange, emptyHistogram, encodeRle, evaluateAdjustmentLayers, filterMaskCoverage, findAdjustmentControl, findLayerControl, formatControlValue, getControlPath, handlePaintShortcut, hasResampledLegacyMask, hexToRgb, hitTestCurvePoint, hslToRgb, hueRangeTables, hueRangeWeight, hueSaturation, identityCurve, identityLevels, imageEditorStateMigrations, insertCurvePoint, instancesOf, invertMatrix3, isAdjustmentKind, isContentsDecoded, isDefaultDepthMask, isLegacyShape, isPaintTool, isQuarterTurn, kelvinToTemperature, layerBadge, layerEffectControls, layerEffectsBadge, layerEffectsPanel, layerLabel, layerMenu, layerPanelRows, layersFromLegacy, legacyAdjustmentLayer, legacyMaskOf, legacyView, levelsValue, linearSrgbToXy, linearToSrgb, loadImageEditorDocument, maskSummary, mixerLoadResult, moveCurvePoint, moveSmartFilter, mulMatrix3, needsLegacyBase, neutralHueRange, newContentsId, normalizeAdjustmentLayer, normalizeAdjustmentLayers, normalizePlacement, normalizeProcessVersion, normalizeSmartFilter, offsetSmartObject, openPsdFile, parseAdjustmentBlock, parseLfx2, parseLrfx, parsePatternBlock, parseVersionedDescriptor, photoFilterMatrix, placeContents, placementAt, placementBounds, placementGeometry, pointerPressure, posterizeValue, projectQuarterTurn, psdBytesFromBase64, psdFileName, psdPatternToEffectPattern, quickMaskPixels, rangeLightness, rasterContents, rasterMaskFromLegacy, rasterizeSmartObject, readAdjustmentControls, removeAlpha, removeCurvePoint, removeSmartFilter, renderLayeredBase, renderSmartObject, replaceContents, requireSmartObject, rerender, resolveMosaicRegionBounds, rgbToGray, rgbToHsl, rgbUnitToHex, runLayerMenuAction, sampleLut, sampleToneLut, selectionModeFromModifiers, selectionOutline, setControlPath, setSmartFilterMask, setSmartFiltersEnabled, setSmartPlacement, smartFilterRows, splitOverlayAnnotations, srgbToLinear, sumHistograms, tempTintToXy, temperatureToKelvin, toneCurve, toneLuts, updateSmartFilter, uvToXy, versionedDescriptorBytes, vibranceLinear, vibrancePixel, wbMatrix, whiteBalanceFromSample, whiteBalanceMatrix, withFilterMaskSurface, writeAdjustmentBlock, writeLfx2, writePatternBlock, xyToTempTint, xyToUv };