@pixerate/editor 0.266.2 → 0.268.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/index.cjs +2 -2
- package/dist/agent/index.js +1 -1
- package/dist/animation-editor/controller.d.cts +8 -0
- package/dist/animation-editor/controller.d.ts +8 -0
- package/dist/animation-editor/effect-tools.d.cts +1 -1
- package/dist/animation-editor/effect-tools.d.ts +1 -1
- package/dist/animation-editor/index.cjs +175 -108
- package/dist/animation-editor/index.js +94 -27
- package/dist/brushes/index.cjs +201 -75
- package/dist/brushes/index.d.cts +4 -3
- package/dist/brushes/index.d.ts +4 -3
- package/dist/brushes/index.js +138 -12
- package/dist/brushes/library.d.cts +27 -1
- package/dist/brushes/library.d.ts +27 -1
- package/dist/brushes/profiles.d.cts +10 -1
- package/dist/brushes/profiles.d.ts +10 -1
- package/dist/brushes/schema.d.cts +4 -0
- package/dist/brushes/schema.d.ts +4 -0
- package/dist/brushes/sources.d.cts +114 -0
- package/dist/brushes/sources.d.ts +114 -0
- package/dist/brushes/types.d.cts +37 -5
- package/dist/brushes/types.d.ts +37 -5
- package/dist/brushes/ui.d.cts +40 -4
- package/dist/brushes/ui.d.ts +40 -4
- package/dist/{brushstrokeRender-KD453OBX.js → brushstrokeRender-A727TTNQ.js} +7 -7
- package/dist/{brushstrokeRender-FSUWXUZY.cjs → brushstrokeRender-WR2N5HHY.cjs} +23 -23
- package/dist/canvas/brushTypes.d.cts +12 -0
- package/dist/canvas/brushTypes.d.ts +12 -0
- package/dist/canvas/brushstroke.d.cts +1 -1
- package/dist/canvas/brushstroke.d.ts +1 -1
- package/dist/canvas/drawController.d.cts +19 -4
- package/dist/canvas/drawController.d.ts +19 -4
- package/dist/canvas/index.cjs +144 -105
- package/dist/canvas/index.js +46 -7
- package/dist/{chunk-TOID45I2.cjs → chunk-2WOGXEDX.cjs} +1 -1
- package/dist/{chunk-XORJ7UZO.cjs → chunk-3VHH6V67.cjs} +13 -12
- package/dist/{chunk-3C33YTNN.js → chunk-3XDSNIGF.js} +73 -6
- package/dist/chunk-62MFUHSI.cjs +802 -0
- package/dist/{chunk-R44Y3EFS.js → chunk-74ODPZLX.js} +17 -345
- package/dist/{chunk-GCVFEPJG.js → chunk-ACTHSQOI.js} +182 -0
- package/dist/chunk-ADMRNWR7.js +340 -0
- package/dist/{chunk-MVUQSK5J.cjs → chunk-B3G7BKUV.cjs} +111 -439
- package/dist/{chunk-DXYHQ2VN.js → chunk-BAZMCFVL.js} +1 -1
- package/dist/{chunk-VRK322ZC.cjs → chunk-BPJSI4NT.cjs} +2 -2
- package/dist/{chunk-RFJZGTHA.cjs → chunk-EU2ZZA6L.cjs} +400 -69
- package/dist/{chunk-XC6DPRYI.js → chunk-GSTSZPSR.js} +154 -949
- package/dist/{chunk-EZOJBP4D.js → chunk-HFY5LG5J.js} +1 -1
- package/dist/chunk-HVO6XCI4.js +802 -0
- package/dist/{chunk-YHDHFJUC.cjs → chunk-J5VQYK7T.cjs} +217 -1012
- package/dist/{chunk-XRXFVRGY.cjs → chunk-JBB3GDBB.cjs} +2483 -208
- package/dist/{chunk-ACFSFUQH.js → chunk-JL6YH5WD.js} +4 -0
- package/dist/{chunk-CIJBSUM5.js → chunk-KZI3YWKW.js} +353 -22
- package/dist/{chunk-4ODRXQRW.js → chunk-LETF75CA.js} +1 -1
- package/dist/{chunk-FQPUF2W2.cjs → chunk-NIBFKXMD.cjs} +217 -35
- package/dist/{chunk-AQZQWXEU.cjs → chunk-NPWWSCWT.cjs} +35 -35
- package/dist/{chunk-DOZ6F2K2.js → chunk-NSETJI74.js} +3 -2
- package/dist/{chunk-PE6YJMQT.cjs → chunk-PFHJS4HE.cjs} +20 -19
- package/dist/{chunk-7KNW3WXZ.cjs → chunk-QEVLRLUN.cjs} +63 -0
- package/dist/{chunk-LK4SXL3V.js → chunk-QNY7BDFP.js} +1 -1
- package/dist/{chunk-OTN6VB5S.cjs → chunk-RDFHWAHL.cjs} +5 -1
- package/dist/{chunk-PXDIAYB6.cjs → chunk-STLTOISW.cjs} +34 -214
- package/dist/{chunk-T2LDTEXK.js → chunk-UVTO3D4E.js} +2333 -58
- package/dist/{chunk-6JL2D5SG.js → chunk-VE6UKYQ2.js} +3 -2
- package/dist/{chunk-TXFWZ5ZJ.js → chunk-W6JDUXP3.js} +4 -184
- package/dist/{chunk-3SBLVGOM.cjs → chunk-YOVXQHA3.cjs} +23 -23
- package/dist/{chunk-WLUVZKVD.cjs → chunk-YXP6X3SY.cjs} +103 -36
- package/dist/chunk-YZWM6ZIP.cjs +340 -0
- package/dist/{chunk-472INMWH.js → chunk-ZA7L5YJB.js} +63 -0
- package/dist/commands/builtins.d.cts +12 -1
- package/dist/commands/builtins.d.ts +12 -1
- package/dist/commands/index.cjs +2 -2
- package/dist/commands/index.js +1 -1
- package/dist/image-editor/controller.d.cts +1 -1
- package/dist/image-editor/controller.d.ts +1 -1
- package/dist/image-editor/index.cjs +868 -864
- package/dist/image-editor/index.js +123 -119
- package/dist/paint/index.cjs +8 -6
- package/dist/paint/index.js +56 -54
- package/dist/paint-editor/brush-library-tools.d.cts +12 -2
- package/dist/paint-editor/brush-library-tools.d.ts +12 -2
- package/dist/paint-editor/brush-model.d.cts +29 -1
- package/dist/paint-editor/brush-model.d.ts +29 -1
- package/dist/paint-editor/brush-source-art.d.cts +32 -0
- package/dist/paint-editor/brush-source-art.d.ts +32 -0
- package/dist/paint-editor/controller.d.cts +11 -4
- package/dist/paint-editor/controller.d.ts +11 -4
- package/dist/paint-editor/dab-stroke.d.cts +2 -0
- package/dist/paint-editor/dab-stroke.d.ts +2 -0
- package/dist/paint-editor/engine.d.cts +11 -2
- package/dist/paint-editor/engine.d.ts +11 -2
- package/dist/paint-editor/index.cjs +967 -2335
- package/dist/paint-editor/index.d.cts +3 -1
- package/dist/paint-editor/index.d.ts +3 -1
- package/dist/paint-editor/index.js +394 -1762
- package/dist/paint-editor/path-samples.d.cts +2 -0
- package/dist/paint-editor/path-samples.d.ts +2 -0
- package/dist/paint-editor/presence.d.cts +20 -1
- package/dist/paint-editor/presence.d.ts +20 -1
- package/dist/paint-editor/stamp-tip.d.cts +8 -5
- package/dist/paint-editor/stamp-tip.d.ts +8 -5
- package/dist/paint-editor/thumbnails.d.cts +6 -0
- package/dist/paint-editor/thumbnails.d.ts +6 -0
- package/dist/paint-editor/tip-grain.d.cts +34 -0
- package/dist/paint-editor/tip-grain.d.ts +34 -0
- package/dist/raster/index.cjs +2 -2
- package/dist/raster/index.js +9 -9
- package/dist/stickers/helpers.d.cts +2 -0
- package/dist/stickers/helpers.d.ts +2 -0
- package/dist/stickers/index.cjs +41 -35
- package/dist/stickers/index.js +22 -16
- package/dist/stickers/types.d.cts +4 -2
- package/dist/stickers/types.d.ts +4 -2
- package/dist/vector/backdrop.d.cts +13 -0
- package/dist/vector/backdrop.d.ts +13 -0
- package/dist/vector/brushstroke.d.cts +54 -7
- package/dist/vector/brushstroke.d.ts +54 -7
- package/dist/vector/brushstrokeMedia.d.cts +96 -0
- package/dist/vector/brushstrokeMedia.d.ts +96 -0
- package/dist/vector/controller.d.cts +17 -3
- package/dist/vector/controller.d.ts +17 -3
- package/dist/vector/index.cjs +1850 -1390
- package/dist/vector/index.d.cts +2 -0
- package/dist/vector/index.d.ts +2 -0
- package/dist/vector/index.js +520 -60
- package/dist/vector/render.d.cts +6 -0
- package/dist/vector/render.d.ts +6 -0
- package/dist/vector/types.d.cts +14 -0
- package/dist/vector/types.d.ts +14 -0
- package/package.json +1 -1
- package/skills/pixerate-animation-editor/SKILL.md +1 -0
- package/skills/pixerate-brushes/SKILL.md +37 -10
- package/skills/pixerate-brushes-design/SKILL.md +15 -5
- package/skills/pixerate-brushes-design/evals/port-to-vector.json +8 -8
- package/skills/pixerate-canvas/SKILL.md +11 -1
- package/skills/pixerate-image-editor/SKILL.md +19 -64
- package/skills/pixerate-image-editor/references/color-management.md +2 -1
- package/skills/pixerate-image-editor/references/free-transform.md +12 -0
- package/skills/pixerate-image-editor/references/layer-effects.md +10 -0
- package/skills/pixerate-image-editor/references/painting.md +17 -0
- package/skills/pixerate-image-editor/references/photoshop-files.md +1 -1
- package/skills/pixerate-image-editor/references/shapes-and-type.md +14 -0
- package/skills/pixerate-image-editor/references/smart-objects.md +10 -0
- package/skills/pixerate-paint-editor/SKILL.md +14 -4
- package/skills/pixerate-paint-editor/references/brush-facets.md +3 -1
- package/skills/pixerate-paint-editor/references/wet-media.md +9 -0
- package/skills/pixerate-paint-sketch-to-finish/SKILL.md +1 -0
- package/skills/pixerate-vector/SKILL.md +16 -6
- package/skills/pixerate-vector/references/best-practices.md +1 -0
- package/skills/pixerate-vector/references/commands.md +19 -0
package/dist/vector/render.d.cts
CHANGED
|
@@ -571,6 +571,12 @@ export interface VectorSceneRenderOptions {
|
|
|
571
571
|
};
|
|
572
572
|
/** With `viewportSize`: groups, text and instances smaller than this many screen pixels draw as one rectangle in their main colour (default 2; 0 turns it off). */
|
|
573
573
|
lod?: number;
|
|
574
|
+
/**
|
|
575
|
+
* `live` (default): wet brushstrokes show the paint as laid until they settle (re-render when
|
|
576
|
+
* `onVectorBrushstrokesSettled` fires; the controller notifies then). `settled`: settle them
|
|
577
|
+
* first, as exports must.
|
|
578
|
+
*/
|
|
579
|
+
brushstrokes?: 'live' | 'settled';
|
|
574
580
|
}
|
|
575
581
|
/**
|
|
576
582
|
* The document layer. Render the nodes inside `<g transform={transform}>` and `defs` in a
|
package/dist/vector/render.d.ts
CHANGED
|
@@ -571,6 +571,12 @@ export interface VectorSceneRenderOptions {
|
|
|
571
571
|
};
|
|
572
572
|
/** With `viewportSize`: groups, text and instances smaller than this many screen pixels draw as one rectangle in their main colour (default 2; 0 turns it off). */
|
|
573
573
|
lod?: number;
|
|
574
|
+
/**
|
|
575
|
+
* `live` (default): wet brushstrokes show the paint as laid until they settle (re-render when
|
|
576
|
+
* `onVectorBrushstrokesSettled` fires; the controller notifies then). `settled`: settle them
|
|
577
|
+
* first, as exports must.
|
|
578
|
+
*/
|
|
579
|
+
brushstrokes?: 'live' | 'settled';
|
|
574
580
|
}
|
|
575
581
|
/**
|
|
576
582
|
* The document layer. Render the nodes inside `<g transform={transform}>` and `defs` in a
|
package/dist/vector/types.d.cts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { GenerationProvenance } from '../generation/provenance.cjs';
|
|
2
2
|
import type { CanvasGradientDef } from '../canvas/gradient.cjs';
|
|
3
|
+
import type { CanvasBrushPaint } from '../canvas/brushTypes.cjs';
|
|
3
4
|
import type { WarpMesh, WarpStyle } from '../geom/types.cjs';
|
|
4
5
|
import type { GrainPattern } from '../paint/grain.cjs';
|
|
5
6
|
import type { Brush } from '../brushes/types.cjs';
|
|
@@ -282,7 +283,20 @@ export interface VectorBrushstroke {
|
|
|
282
283
|
seed?: number;
|
|
283
284
|
/** The paper the grain comes from (with `seed`); `null` for no grain. */
|
|
284
285
|
paper?: VectorBrushstrokePaper | null;
|
|
286
|
+
/**
|
|
287
|
+
* Gradient paint sampled dab by dab along the path, instead of the layer's colour (which still
|
|
288
|
+
* gives the alpha and fills `paint` stops): by distance travelled (document units), pressure,
|
|
289
|
+
* tilt, direction, across the tip or at random. Without it, a gradient layer paint is laid
|
|
290
|
+
* along, across or within the stroke (its `strokeMode`), and a brush with its own gradient
|
|
291
|
+
* paints that.
|
|
292
|
+
*/
|
|
293
|
+
paint?: VectorBrushstrokePaint;
|
|
285
294
|
}
|
|
295
|
+
/**
|
|
296
|
+
* A brushstroke's gradient paint (the paint engine's `PaintSource`, as canvas brushed strokes take
|
|
297
|
+
* it: `CanvasBrushPaint`). The `velocity` and `time` mappings are not allowed: paths have no timing.
|
|
298
|
+
*/
|
|
299
|
+
export type VectorBrushstrokePaint = CanvasBrushPaint;
|
|
286
300
|
/** One stroke of a path's stroke stack (`VectorStyle.strokes`): a paint plus its own stroke settings. */
|
|
287
301
|
export interface VectorStrokeLayer extends VectorPaintLayer, VectorStrokeSettings {
|
|
288
302
|
/** Default `paint`. See `VectorStrokeLayerKind`. */
|
package/dist/vector/types.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { GenerationProvenance } from '../generation/provenance.js';
|
|
2
2
|
import type { CanvasGradientDef } from '../canvas/gradient.js';
|
|
3
|
+
import type { CanvasBrushPaint } from '../canvas/brushTypes.js';
|
|
3
4
|
import type { WarpMesh, WarpStyle } from '../geom/types.js';
|
|
4
5
|
import type { GrainPattern } from '../paint/grain.js';
|
|
5
6
|
import type { Brush } from '../brushes/types.js';
|
|
@@ -282,7 +283,20 @@ export interface VectorBrushstroke {
|
|
|
282
283
|
seed?: number;
|
|
283
284
|
/** The paper the grain comes from (with `seed`); `null` for no grain. */
|
|
284
285
|
paper?: VectorBrushstrokePaper | null;
|
|
286
|
+
/**
|
|
287
|
+
* Gradient paint sampled dab by dab along the path, instead of the layer's colour (which still
|
|
288
|
+
* gives the alpha and fills `paint` stops): by distance travelled (document units), pressure,
|
|
289
|
+
* tilt, direction, across the tip or at random. Without it, a gradient layer paint is laid
|
|
290
|
+
* along, across or within the stroke (its `strokeMode`), and a brush with its own gradient
|
|
291
|
+
* paints that.
|
|
292
|
+
*/
|
|
293
|
+
paint?: VectorBrushstrokePaint;
|
|
285
294
|
}
|
|
295
|
+
/**
|
|
296
|
+
* A brushstroke's gradient paint (the paint engine's `PaintSource`, as canvas brushed strokes take
|
|
297
|
+
* it: `CanvasBrushPaint`). The `velocity` and `time` mappings are not allowed: paths have no timing.
|
|
298
|
+
*/
|
|
299
|
+
export type VectorBrushstrokePaint = CanvasBrushPaint;
|
|
286
300
|
/** One stroke of a path's stroke stack (`VectorStyle.strokes`): a paint plus its own stroke settings. */
|
|
287
301
|
export interface VectorStrokeLayer extends VectorPaintLayer, VectorStrokeSettings {
|
|
288
302
|
/** Default `paint`. See `VectorStrokeLayerKind`. */
|
package/package.json
CHANGED
|
@@ -162,6 +162,7 @@ refuse.
|
|
|
162
162
|
| `update_effect` | Make an applied effect again with new `values`, in the same place (`effect` is its instance id). |
|
|
163
163
|
| `remove_effect` | Remove an applied effect: its commands, shots it alone filled and a vector effect's group. |
|
|
164
164
|
| `add_vector_effect` | Add a vector effect's own picture as an artwork group (fitted into `box`) with its motion as new shots. For an effect that draws along a path (`search_effects` `accepts: ["path"]`: a signature, a route), `path: { node }` runs it along a path node and lands it on the node, `path: { text }` writes words. Use it when the effect should trace the path itself; use `follow` or a draw-on to move or reveal your own art. Returns the instance and group ids. |
|
|
165
|
+
| `set_vector_effect_path` | Give a vector effect already added (`instance` from `add_vector_effect` or `list_applied_effects`) a new path in place: `path: { node }` runs it along a path node and lands it on the node, `path: { text }` writes words and keeps the picture where it was. Call it after reshaping the node an effect runs along (the path is a copy), or to switch between a node and words; clear the path with `update_effect` setting the path control to `""`. One undo step. Returns the instance, the `control` set and its new path data `value`. |
|
|
165
166
|
| `list_camera_moves` | List the provider's camera moves for a `role` (`transition`: how the camera gets into a shot; `hold`: how it moves while the shot holds), with `durationMs` and `cut`. Returns `available: false` without camera moves. Call before `set_shot_camera_move`; `describe_effect` gives a move's controls and presets. |
|
|
166
167
|
| `set_shot_camera_move` | Give a shot a camera move (`shot`, `role`, `move`, optional `ms` for a transition, `preset`, `values`): it is saved on the shot's camera as `in` or `during`. Returns the shot's camera and the `window` (ms) the move plays in. A wrong-role id is refused naming the moves that fit. |
|
|
167
168
|
| `clear_shot_camera_move` | Remove a shot's move for a `role`, keeping its framing. Returns the shot's camera (null when nothing is left). |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: pixerate-brushes
|
|
3
|
-
description: How to find, describe, create, change, check and share brushes in the Pixerate brush library through list_brush_presets, describe_brush, create_brush, update_brush, duplicate_brush, remove_brush, check_brush, export_brushes, import_brushes and
|
|
3
|
+
description: How to find, describe, create, change, check and share brushes in the Pixerate brush library through list_brush_presets, describe_brush, create_brush, update_brush, duplicate_brush, remove_brush, check_brush, export_brushes, import_brushes, preview_brush, add_brush_source and list_brush_sources - brushes made of facets (kind, medium and variety or tool, tip, marks, dynamics, behaviour, light, motion, colour), image tips and tip grain made from image sources, the built-in presets, and the host profiles that say what the paint editor, image editor, canvas and vector strokes can render. Use when asked to make, design, tweak, save, copy, delete, export, import or check a brush, make a brush from an image (a scanned mark, a leaf, a texture), give a brush grain, find a brush for a medium (pencil, ink, watercolour, oil, airbrush, highlighter), or make a brush work in another editor.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Brushes
|
|
@@ -15,13 +15,13 @@ built-in presets (read-only) and the user's brushes, shared by every editor that
|
|
|
15
15
|
| Kind | `mark` lays a material; `tool` works on paint already down. |
|
|
16
16
|
| Medium and variety | Marks: what it lays (`paint`, `ink`, `dry`, `spray`) and what kind (`oil`, `watercolor`, `gouache`, `pencil`, `charcoal`, `airbrush`, `marker`, `highlighter`…). Descriptive, for finding brushes; a wet brush whose variety is `watercolor`, `gouache` or `oil` paints that medium. |
|
|
17
17
|
| Tool | Tools: `eraser`, `blender`, `smudge`, and on wet paint `water`, `dryer`, `blow`, `blot`, `wet-blend`, `wet-drag`. |
|
|
18
|
-
| Tip | `shape` (`round`, `flat`, `chisel` are ellipses set by `roundness` and `angle`; `bristle` has a tuft; `stamp` takes the shape of `stamps`: an editor stamp `editor:star
|
|
18
|
+
| Tip | `shape` (`round`, `flat`, `chisel` are ellipses set by `roundness` and `angle`; `bristle` has a tuft; `stamp` takes the shape of `stamps`: an editor stamp `editor:star`, any sticker ref from `find_stickers`, or an image source `source:<id>` from `list_brush_sources`), size in px, hardness (an image tip fades towards its edges below 1), spacing, opacity, flow, blend mode, and `grain`: texture inside each dab (`source`: a pattern such as `rough`, `canvas`, `sanded`, or `source:<id>`; `mode` `texturised` stays put on the canvas, `moving` rolls with the tip; `scale`, `depth`, `contrast`, `invert`). |
|
|
19
19
|
| Marks | `continuous` dabs (default; on a stamp tip every dab is the first stamp's shape, in the paint colour), `scatter` (a spray: droplets across the tip, `density`, `size`), `particles` (strands, springs, ribbons, sparks; textured dots from the stamps) or `objects` (each mark an editable sticker, in its own colours). |
|
|
20
|
-
| Dynamics | Pen feel: pressure to size and opacity, smoothing, tilt, velocity, jitter, rotation. |
|
|
20
|
+
| Dynamics | Pen feel: pressure to size and opacity, smoothing, tilt, velocity, jitter (`sizeJitter`, `angleJitter` for rotation, `opacityJitter`, `scatter`), rotation, `count` (dabs per spacing step, each jittered) and `flip` (mirror dabs at random: `x`, `y`, `xy`). |
|
|
21
21
|
| Behaviour | `surface` `dry`, `wet` (`wet` settings) or `thick` (`thick` impasto settings); paper `grain`; `exchange` (pick-up and mix; a `reservoir` makes a Mixer Brush); tool `strength`. |
|
|
22
22
|
| Light | Light the brush gives off (`amount`), plus suggested layer `spill` and `glow`. |
|
|
23
23
|
| Motion | Animation after painting (live effect paint, particle `waveSpeed`). |
|
|
24
|
-
| Colour | A `default` colour, a `palette` of up to 16, `own` (always its own colour). Each is a hex or `rgba()` colour, a light / dark pair `{ light, dark }`, a gradient or effect paint. A gradient default is always painted; a solid or light / dark default becomes the editor's colour when the brush is chosen (unless the user locked theirs), resolved for the colour scheme. Canvas strokes and vector brushstrokes take it too, when they are given no colour. |
|
|
24
|
+
| Colour | A `default` colour, a `palette` of up to 16, `own` (always its own colour). Each is a hex or `rgba()` colour, a light / dark pair `{ light, dark }`, a gradient or effect paint. A gradient default is always painted; a solid or light / dark default becomes the editor's colour when the brush is chosen (unless the user locked theirs), resolved for the colour scheme. Canvas strokes and vector brushstrokes take it too, when they are given no colour. Canvas and vector have the same lock (`canvas.setColorLocked`, `vector.setColorLocked`), and a canvas colour taken from a light / dark default follows the scheme like the paint editor's; vector strokes already made keep theirs. |
|
|
25
25
|
|
|
26
26
|
How media map to facets: a **pencil** or **charcoal** is `dry` with high `grain` and tilt;
|
|
27
27
|
**ink** is a hard round tip with pressure to size (a pen thins with velocity); **watercolour**
|
|
@@ -31,7 +31,16 @@ and **wet oil** are `paint` on `surface: 'wet'`; **impasto** is `surface: 'thick
|
|
|
31
31
|
pressure to size); **crayon** and **chalk** are `dry` with high `grain`; a **highlighter** is
|
|
32
32
|
`ink` / `highlighter`, a multiply chisel tip with a little light, `spill` radius 0, fluorescent
|
|
33
33
|
yellow by default; a **stamp brush** is a `stamp` tip with continuous marks; **particle** and
|
|
34
|
-
**sticker** brushes are `marks` particles or objects on a `stamp` tip.
|
|
34
|
+
**sticker** brushes are `marks` particles or objects on a `stamp` tip. An **image brush** (a
|
|
35
|
+
scanned charcoal mark, a leaf, a dry-brush texture) is a `stamp` tip whose stamp is an image
|
|
36
|
+
source, usually with `tip.grain`, `angleJitter`, `flip` and a little `scatter` so repeats don't
|
|
37
|
+
show.
|
|
38
|
+
|
|
39
|
+
**Image sources** are the images tips and grain are made from, kept in the library with their
|
|
40
|
+
bytes (a grey mask, at most 512 px) and their licence. `add_brush_source` makes one from a PNG:
|
|
41
|
+
the marks are read from its transparency, its dark parts (a scan on paper) or its light parts
|
|
42
|
+
(white on black). Library files (`export_brushes`) and saved paintings carry the sources their
|
|
43
|
+
brushes name, so they paint and replay the same anywhere.
|
|
35
44
|
|
|
36
45
|
## Host profiles
|
|
37
46
|
|
|
@@ -40,10 +49,10 @@ paints without (warnings), each with a fix; lists and writes use the current hos
|
|
|
40
49
|
|
|
41
50
|
| Host | Renders |
|
|
42
51
|
| --- | --- |
|
|
43
|
-
| Paint editor (`paint`) | Everything. |
|
|
44
|
-
| Image editor (`image`) | Dry dabs on round, flat and chisel tips, the Mixer Brush and the eraser; no wet or thick surface, particles, objects, light or motion
|
|
45
|
-
| Canvas (`canvas`) | Dry dab brushes along a path (no tools, wet, thick, particles, objects or light); velocity
|
|
46
|
-
| Vector strokes (`vector`) | As canvas,
|
|
52
|
+
| Paint editor (`paint`) | Everything, image tips and tip grain included. |
|
|
53
|
+
| Image editor (`image`) | Dry dabs on round, flat and chisel tips, the Mixer Brush and the eraser; no wet or thick surface, particles, objects, stamp or image tips, light or motion; it paints without tip grain and `count`. Pick one with `set_brush_preset`. |
|
|
54
|
+
| Canvas (`canvas`) | Dry dab brushes along a path (no tools, wet, thick, particles, objects, stamp or image tips, or light); velocity, tip grain and `count` are ignored. Draw with one as `canvas.drawFreehand` `brush`. |
|
|
55
|
+
| Vector strokes (`vector`) | As canvas, plus wet paint (watercolour, gouache, wet oils: simulated in the stroke's own area, then dried), the Mixer Brush, and the smudge and blender tools (acting on the shapes beneath the stroke); light brushes paint as plain colour. The wet tools (water, hair dryer, blow, wet blend, wet drag, blot), thick paint, particles, objects and erasers are refused. Draw with one as `vector.addBrushstroke` `brushId`. |
|
|
47
56
|
|
|
48
57
|
Every host lists the presets its profile admits and the library's saved brushes it admits, and
|
|
49
58
|
each registers these tools with its own profile, so `list_brush_presets` shows that host's brushes.
|
|
@@ -66,7 +75,11 @@ drawn.
|
|
|
66
75
|
in the editor (`set_brush` with the new id, then `paint_stroke`).
|
|
67
76
|
5. **Tune it.** `update_brush` with the facets to change, or `unset` to drop whole facets. It
|
|
68
77
|
returns the leaf paths `changed`. Built-in presets can't be changed: `duplicate_brush` first.
|
|
69
|
-
6. **
|
|
78
|
+
6. **From an image.** `add_brush_source` with the PNG (`channel` when `auto` picks the wrong
|
|
79
|
+
part; keep the `licence` it came with), then `create_brush` with `tip: { shape: "stamp",
|
|
80
|
+
stamps: ["source:<id>"] }` for an image tip, or `tip.grain.source` for grain.
|
|
81
|
+
`list_brush_sources` lists them and which brushes use each.
|
|
82
|
+
7. **Share it.** `export_brushes` writes a library file; `import_brushes` adds one (version 1
|
|
70
83
|
files of the paint editor's older brushes are migrated). `check_brush` with `host` before
|
|
71
84
|
handing a brush to another editor.
|
|
72
85
|
|
|
@@ -92,6 +105,13 @@ drawn.
|
|
|
92
105
|
to make its preview visible: choosing the brush makes that default the user's colour.
|
|
93
106
|
- Stamp tips paint the sticker's shape in the paint colour; to keep a sticker's own colours, use
|
|
94
107
|
`marks` objects instead.
|
|
108
|
+
- Image tips: crop the image to the mark and give it a transparent or plain background, so the
|
|
109
|
+
dab is the mark and not its box. Spacing 0.2–0.4 for a continuous mark, above 1 for separate
|
|
110
|
+
prints; add `angleJitter`, `flip` and `scatter` so the same image doesn't repeat visibly.
|
|
111
|
+
- Grain: `texturised` grain (default) is a texture the stroke reveals, like paper; `moving` grain
|
|
112
|
+
belongs to the tip and rolls with it (a sponge, a roller). Depth 0.4–0.7 reads as texture;
|
|
113
|
+
1 leaves only the peaks. Use `tip.grain` for the tool's texture and `behaviour.grain` for the
|
|
114
|
+
paper's.
|
|
95
115
|
|
|
96
116
|
## Pitfalls
|
|
97
117
|
|
|
@@ -107,6 +127,11 @@ drawn.
|
|
|
107
127
|
(`editor:star`…). A ref the host's sticker library can't load is refused with the closest
|
|
108
128
|
refs. Only the paint editor renders stamp tips and scatter marks; canvas, vector and the image
|
|
109
129
|
editor refuse them (`check_brush` says so).
|
|
130
|
+
- **Image sources.** A `source:<id>` the library doesn't have is refused, with the closest ids;
|
|
131
|
+
add it first. Replacing a source's image (`overwrite`) changes every brush that names it, but
|
|
132
|
+
not strokes already painted. Objects marks take stickers only, so an image source there is
|
|
133
|
+
dropped (`problems` says so). Brush packs are often licensed for personal use only: keep the
|
|
134
|
+
`licence` text with the source.
|
|
110
135
|
- **Out-of-range values** are refused by the schema (`tip.size` is 1..2500 px); a stored brush
|
|
111
136
|
is clamped on import and reported in `problems`.
|
|
112
137
|
- **The paint editor paints from this library.** Its `set_brush` picks a brush by id here and
|
|
@@ -133,3 +158,5 @@ drawn.
|
|
|
133
158
|
| `export_brushes` | Library file (pixerate-brushes v2) of the saved brushes or the `ids` given. Returns `file`, for `import_brushes`. |
|
|
134
159
|
| `import_brushes` | Add a library `file` (v2, v1 migrated, or a bare list): built-in ids and taken ids are skipped unless `overwrite`. Returns `added`, `replaced`, `skipped`, `problems`. |
|
|
135
160
|
| `preview_brush` | Only when the host renders previews: a sample stroke with a brush (`id`, `width`, `height`, `color`) as an image. |
|
|
161
|
+
| `add_brush_source` | Add an image (`name`, `image` PNG data: URL, optional `id`, `channel` auto / alpha / darkness / lightness, `invert`, `licence`, `origin`, `overwrite`) as a source for image tips and grain. Returns `id`, `ref` (`source:<id>`), `width`, `height`, `problems`, `replaced`. Then `create_brush` / `update_brush` with the ref in `tip.stamps` or `tip.grain.source`. |
|
|
162
|
+
| `list_brush_sources` | The library's image sources (`text`, `offset`, `limit`). Returns `sources` (id, ref, name, width, height, licence, origin, `usedBy` brush ids) and `total`. Call before naming a `source:` ref. |
|
|
@@ -26,8 +26,9 @@ This skill is the method. `pixerate-brushes` has the full tool reference.
|
|
|
26
26
|
|
|
27
27
|
Ask when you cannot tell from the request; say what you assumed when you can.
|
|
28
28
|
|
|
29
|
-
- **Host:** which editor will use it (paint by default; canvas
|
|
30
|
-
dab brushes, the
|
|
29
|
+
- **Host:** which editor will use it (paint by default; canvas strokes take only dry dab brushes,
|
|
30
|
+
vector strokes dry and wet dab brushes, the Mixer Brush, smudge and blender; the image editor no
|
|
31
|
+
wet, thick or particle brushes).
|
|
31
32
|
- **Medium and character:** what it imitates (pencil, ink, chalk, watercolour, marker…), and
|
|
32
33
|
the size, softness and texture.
|
|
33
34
|
- **Colour:** a default colour or palette, or the user's own colour (the default).
|
|
@@ -53,9 +54,11 @@ Ask when you cannot tell from the request; say what you assumed when you can.
|
|
|
53
54
|
| Situation | Approach |
|
|
54
55
|
| --- | --- |
|
|
55
56
|
| A colour variant of a preset | `basedOn` it, set `colour.default` (and a `palette`), keep everything else. |
|
|
56
|
-
| For canvas
|
|
57
|
+
| For canvas strokes | Base on a dry preset (pencil, pastel, charcoal, marker, ink); no wet surface, particles, stickers or tools; no light. |
|
|
58
|
+
| For vector strokes | As canvas, but a wet surface (watercolour, gouache, wet oil), the Mixer Brush and the smudge and blender tools work too; no thick paint, particles, stickers, erasers or wet tools. |
|
|
57
59
|
| A brush that must work in another editor | `check_brush` with that `host`, then `create_brush` from its `degraded` brush under a new id. |
|
|
58
|
-
| A texture (chalk, charcoal, dry brush) | Raise `behaviour.grain` (0.8..1) and add `dynamics.sizeJitter`; test on rough paper. |
|
|
60
|
+
| A texture (chalk, charcoal, dry brush) | Raise `behaviour.grain` (0.8..1) and add `dynamics.sizeJitter`; test on rough paper. For texture that shows on any paper, give the tip its own grain: `tip.grain` `{ source: "sanded", depth: 0.6 }` (paint editor; other hosts paint without it). |
|
|
61
|
+
| A brush from an image (a scanned mark, a leaf, a texture) | `list_brush_sources`, or `add_brush_source` with the PNG (keep its `licence`); then `tip` `{ shape: "stamp", stamps: ["source:<id>"] }`, spacing 0.2–0.4, `dynamics.angleJitter`, `flip` and a little `scatter`. The image as grain instead: `tip.grain.source`. Paint editor only. |
|
|
59
62
|
| A light brush (neon, glow) | `light.amount`, and paint it on dark paper; a highlighter keeps `light.spill.radius` 0. |
|
|
60
63
|
| A colour that depends on the background (chalk, white ink) | `colour.default` as a light / dark pair `{ light, dark }`: the editor takes the side for its colour scheme when the brush is chosen. |
|
|
61
64
|
| A shape as the tip (stars, leaves, a logo) | `tip.shape` stamp with `stamps` (an editor stamp or a ref from `find_stickers`), continuous marks; it paints in the user's colour. Keep the sticker's colours with `marks` objects. Paint editor only. |
|
|
@@ -72,6 +75,11 @@ basedOn: "highlighter", colour: { default: "#ff6ec7" } }`, then `check_brush`.
|
|
|
72
75
|
`{ id: "board-chalk", name: "Board chalk", basedOn: "chalk", colour: { default: { light:
|
|
73
76
|
"#334155", dark: "#f8fafc" } } }`: white chalk in dark mode, slate on light paper.
|
|
74
77
|
|
|
78
|
+
**A charcoal brush from a scan.** `add_brush_source` `{ name: "Charcoal scan", image: <PNG>,
|
|
79
|
+
channel: "darkness" }` → `create_brush` `{ id: "scan-charcoal", name: "Scan charcoal", basedOn:
|
|
80
|
+
"charcoal-stick", tip: { shape: "stamp", stamps: ["source:charcoal-scan"], spacing: 0.25, grain:
|
|
81
|
+
{ source: "rough", depth: 0.5 } }, dynamics: { angleJitter: 0.3, flip: "xy" } }` → `preview_brush`.
|
|
82
|
+
|
|
75
83
|
**Port a wet brush to vector.** `check_brush` `{ id, host: "vector" }`; `create_brush` from the
|
|
76
84
|
`degraded` brush with `id` `<id>-vector`; `check_brush` again.
|
|
77
85
|
|
|
@@ -80,7 +88,8 @@ basedOn: "highlighter", colour: { default: "#ff6ec7" } }`, then `check_brush`.
|
|
|
80
88
|
- **Starting from nothing.** A brush without `basedOn` gets engine defaults (a hard round dab);
|
|
81
89
|
it rarely looks like the medium asked for.
|
|
82
90
|
- **A host that refuses the base.** A wet or particle preset can't be the base of a canvas
|
|
83
|
-
brush; set `behaviour.surface` to `dry`
|
|
91
|
+
brush, nor a thick (impasto) preset of a vector one; set `behaviour.surface` to `dry` (vector
|
|
92
|
+
also takes `wet`) or start from a dry preset.
|
|
84
93
|
- **Lists replace.** Giving `colour.palette` or `tip.stamps` replaces the whole list; include
|
|
85
94
|
every entry you want.
|
|
86
95
|
- **Changing a built-in.** `update_brush` refuses built-ins; duplicate first.
|
|
@@ -91,3 +100,4 @@ basedOn: "highlighter", colour: { default: "#ff6ec7" } }`, then `check_brush`.
|
|
|
91
100
|
- `create_brush`, `update_brush`, `duplicate_brush`: make and tune the brush.
|
|
92
101
|
- `check_brush`: prove it works for the host, and get a degraded spec when it doesn't.
|
|
93
102
|
- `preview_brush`: look at a sample stroke when the host renders previews.
|
|
103
|
+
- `add_brush_source`, `list_brush_sources`: images for image tips and grain.
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
|
-
"prompt": "A teammate's brush team-
|
|
2
|
+
"prompt": "A teammate's brush team-knife is in the library, but it won't work for vector brushstrokes. Make a copy called team-knife-vector that does, and leave theirs as it is.",
|
|
3
3
|
"fixture": {
|
|
4
4
|
"editor": "brushes",
|
|
5
|
-
"setup": [{ "tool": "create_brush", "args": { "id": "team-
|
|
5
|
+
"setup": [{ "tool": "create_brush", "args": { "id": "team-knife", "name": "Team knife", "basedOn": "palette-knife", "tags": ["team"] } }]
|
|
6
6
|
},
|
|
7
7
|
"checks": [
|
|
8
|
-
{ "why": "the copy works in the vector editor", "tool": "check_brush", "args": { "id": "team-
|
|
9
|
-
{ "why": "the copy keeps the
|
|
10
|
-
{ "why": "the teammate's brush still
|
|
8
|
+
{ "why": "the copy works in the vector editor", "tool": "check_brush", "args": { "id": "team-knife-vector", "host": "vector" }, "expect": { "ok": true } },
|
|
9
|
+
{ "why": "the copy keeps the knife's tip", "tool": "describe_brush", "args": { "id": "team-knife-vector" }, "expect": { "brush": { "tip": { "size": 48, "roundness": 0.18 } } } },
|
|
10
|
+
{ "why": "the teammate's brush still lays thick paint", "tool": "describe_brush", "args": { "id": "team-knife" }, "expect": { "brush": { "behaviour": { "surface": "thick" } } } }
|
|
11
11
|
],
|
|
12
12
|
"solution": [
|
|
13
|
-
{ "tool": "check_brush", "args": { "id": "team-
|
|
14
|
-
{ "tool": "create_brush", "args": { "id": "team-
|
|
15
|
-
{ "tool": "check_brush", "args": { "id": "team-
|
|
13
|
+
{ "tool": "check_brush", "args": { "id": "team-knife", "host": "vector" } },
|
|
14
|
+
{ "tool": "create_brush", "args": { "id": "team-knife-vector", "name": "Team knife (vector)", "basedOn": "team-knife", "behaviour": { "surface": "wet" } } },
|
|
15
|
+
{ "tool": "check_brush", "args": { "id": "team-knife-vector", "host": "vector" } }
|
|
16
16
|
]
|
|
17
17
|
}
|
|
@@ -100,7 +100,14 @@ you to. Withdraw stale ones with `reject_proposal`: when the user changes what a
|
|
|
100
100
|
stroke always looks the same, and neighbouring strokes share one sheet of paper. Pick the brush
|
|
101
101
|
for the look, then the colour; for a sketch, use one or two brushes rather than all of them.
|
|
102
102
|
A brush with a default colour (ballpoint blue, highlighter yellow, chalk) paints in it when
|
|
103
|
-
you pass no `color`; pass `color` to use another.
|
|
103
|
+
you pass no `color`; pass `color` to use another. Light / dark defaults (chalk) resolve for
|
|
104
|
+
the canvas's colour scheme (`canvas.setColorScheme`; the host usually matches its theme).
|
|
105
|
+
- **Setting up the pen for the person, not drawing.** `canvas.selectBrush` chooses the brush the
|
|
106
|
+
person draws with by hand, as the brush picker does: it takes the brush's default colour unless
|
|
107
|
+
they locked theirs (`canvas.setColorLocked`, "Keep my colour") or you pass `keepColour`. A
|
|
108
|
+
default taken this way follows the scheme until another colour is set. Respect a lock the
|
|
109
|
+
person set; don't unlock it to change their colour. These are editor state, not undo steps,
|
|
110
|
+
and don't affect `canvas.drawFreehand`, which takes its own `brush` and `color`.
|
|
104
111
|
- **Annotate with gestures, not points.** To mark up work the way a designer marks up a print,
|
|
105
112
|
use the gesture commands (`canvas.circle`, `canvas.underline`, `canvas.arrow`,
|
|
106
113
|
`canvas.bracket`, `canvas.strike`, `canvas.cross`, `canvas.check`) with node ids
|
|
@@ -254,6 +261,9 @@ character: seeded jitter and the paper grain they catch) and, when a width was c
|
|
|
254
261
|
| Command | Use it to |
|
|
255
262
|
| --- | --- |
|
|
256
263
|
| `canvas.drawFreehand` | Draw a pen or highlighter stroke through `points` (`[x, y]` pairs in canvas units, in drawing order; one undo step). `tool` picks the defaults (`pen`: blue, width 3; `highlighter`: yellow, width 24, opacity 0.35); `color`, `width`, `opacity` override them (with a `brush` and no `color`, the brush's default colour if it has one; with a `brush`, `width` is the brush diameter and defaults to the preset's own size). Pass `brush` (a preset or saved brush id from `canvas.listBrushes`, or tip settings) to paint it with a dry brush, plus `pressure` / `tiltX` / `tiltY` profiles spread along its length (`[0.2, 1, 0.3]` swells in the middle). Add `paint` (only with `brush`) for gradient paint that changes colour along the stroke: `{ "type": "gradient", "stops": [...], "map": { "by": "distance", "length": 200 } }` (length in canvas units), or `by` `pressure`, `tilt`, `direction`, `across-tip`, `random`. Returns the node `id`, its `bounds` and the stored `brush` (with `paint` normalised: defaults filled in, colours lowercased). |
|
|
264
|
+
| `canvas.selectBrush` | Choose the brush the person draws with by hand (`brushId` from `canvas.listBrushes`, or `null` for a plain vector stroke), at its own size, taking its default colour unless the colour is locked or `keepColour`. Draws nothing. Returns `{ brush, color, colorScheme, colorLocked, colorFollowsScheme }`. |
|
|
265
|
+
| `canvas.setColorLocked` | Lock (`locked: true`) or unlock the hand-drawing colour ("Keep my colour"): while locked, `canvas.selectBrush` keeps it. Returns the same settings as `canvas.selectBrush`; call it (or `canvas.selectBrush`) to read whether the person locked it. |
|
|
266
|
+
| `canvas.setColorScheme` | Set `scheme` `light` or `dark`: picks the side of light / dark default colours for `canvas.selectBrush` and `canvas.drawFreehand`; a colour taken from such a default follows, strokes already drawn keep theirs. Usually the host's job. Returns the same settings as `canvas.selectBrush`. |
|
|
257
267
|
| `canvas.listBrushes` | Read-only: the brushes `canvas.drawFreehand` and the gestures accept as `brush`: the dry presets, then saved brushes from the brush library the canvas can paint (`id`, `name`, `category`, the brush's own `size`, which a stroke uses unless you pass `width`, and `builtin`). Call it before the first brushed stroke instead of guessing ids. |
|
|
258
268
|
|
|
259
269
|
Gestures draw one hand-drawn stroke node each (one undo step) through the same path as
|
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: pixerate-image-editor
|
|
3
|
-
description: How to colour-correct, composite and retouch a photo in the Pixerate image editor through its agent tools - layers (pixel, adjustment, group, shape, type, annotation
|
|
3
|
+
description: How to colour-correct, composite and retouch a photo in the Pixerate image editor through its agent tools - layers (pixel, adjustment, group, shape, type, annotation, smart object; masks, clipping, blend modes, filters), 16/32-bit depth, colour management (profiles, proofing, CMYK, Lab), smart objects and smart filters, provider effects, layer effects, adjustments, selections and masks, Free Transform, crop, rotate, flip, painting and Mixer Brush, retouching (Clone Stamp, Healing, Spot Healing, Smudge, Dodge, Burn, Sponge, Blur, Sharpen, History Brush), undo, PSD, histogram and previews. Use when editing, grading, cropping, masking or retouching an image, adding effects, shapes or text, converting profiles or bit depth, transforming layers, or when list_layers, set_adjustments, add_layer_effect, apply_effect, transform_layer, add_text_layer, paint_stroke, clone_stamp, spot_heal, blur_stroke, sharpen_stroke, history_brush, set_bit_depth, convert_to_profile or import_psd are available.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Image editor
|
|
7
7
|
|
|
8
|
-
The image editor holds a layer stack over a canvas the size of the source image
|
|
8
|
+
The image editor holds a layer stack over a canvas the size of the source image (8-, 16- or
|
|
9
|
+
32-bit depth, with RGB, CMYK and Lab colour management, ICC profiles and soft proofing). Opening an
|
|
9
10
|
image gives one pixel layer, **Background**, whose pixels are the source and whose `develop`
|
|
10
11
|
filter holds the base adjustments (the base controls edit the develop filter of the active pixel
|
|
11
12
|
layer). Adjustment layers sit above it, each through its mask, opacity and blend mode, and
|
|
12
13
|
annotations are shape and type layers on top. Edits never touch the source pixels; `list_layers`
|
|
13
14
|
shows the whole stack. Pixel, group and smart object layers can carry live effects; a smart
|
|
14
|
-
object places contents through a transform and smart filters
|
|
15
|
+
object places contents through a transform and smart filters (including provider effects, which
|
|
16
|
+
also add generator and overlay effect layers); shape layers hold vector paths and
|
|
15
17
|
type layers live text, re-rendered on every change. There is also an optional selection and a
|
|
16
18
|
crop, rotation and flip. See `pixerate-agent-tools` for errors and batching.
|
|
17
19
|
|
|
@@ -95,9 +97,9 @@ Boxes, badges, arrows and callouts are shape layers (`add_shape_layer`), text is
|
|
|
95
97
|
(`add_text_layer`); both stay sharp and take effects, masks and blends. Read
|
|
96
98
|
[references/shapes-and-type.md](references/shapes-and-type.md) before drawing or editing either.
|
|
97
99
|
|
|
98
|
-
### Layer effects
|
|
100
|
+
### Layer and provider effects
|
|
99
101
|
|
|
100
|
-
Live per-layer
|
|
102
|
+
Live per-layer styles (shadows, glows, bevel, overlays, strokes): see [references/layer-effects.md](references/layer-effects.md). Provider filter smart filters and generator / overlay effect layers (`search_effects`, `describe_effect`, `apply_effect`, `add_effect_layer`): see [references/provider-effects.md](references/provider-effects.md).
|
|
101
103
|
|
|
102
104
|
### Paths and cutout edges
|
|
103
105
|
|
|
@@ -110,13 +112,15 @@ Keep outlines as paths (`make_work_path`, `add_path`) and edit their anchors: se
|
|
|
110
112
|
Paint on its own layer (`add_pixel_layer`), one stroke per call and one undo step, limited by a
|
|
111
113
|
selection or locked transparency. Read [references/painting.md](references/painting.md) first.
|
|
112
114
|
|
|
113
|
-
###
|
|
115
|
+
### Bit depth and colour management
|
|
114
116
|
|
|
115
|
-
|
|
117
|
+
Switch between 8-, 16- and 32-bit (float, linear light) with `set_bit_depth` (`references/photoshop-files.md`). For working space profiles (`assign_profile`, `convert_to_profile`), soft proofing (`set_proof_setup`) and CMYK / Lab print modes (`set_color_mode`, `convert_colors`), read [references/color-management.md](references/color-management.md).
|
|
116
118
|
|
|
117
119
|
### Retouching
|
|
118
120
|
|
|
119
|
-
Heal
|
|
121
|
+
Heal and clone on layers above the photo (`sample: "current-below"`); dodge, burn, sponge, blur
|
|
122
|
+
(`blur_stroke`), sharpen (`sharpen_stroke`) and History Brush (`history_brush`) change the pixels
|
|
123
|
+
they touch, so run them on a duplicate. Load
|
|
120
124
|
`pixerate-image-portrait-retouch`, and read [references/retouching.md](references/retouching.md) first.
|
|
121
125
|
|
|
122
126
|
### Photoshop files
|
|
@@ -136,11 +140,11 @@ in the source frame at the document's bit depth, colour mode and profile. Read
|
|
|
136
140
|
- **Blend modes for tone-only or colour-only changes:** `luminosity` applies a curves or
|
|
137
141
|
levels layer without shifting hue or saturation; `color` applies a tint without changing
|
|
138
142
|
brightness; `soft-light` / `overlay` for gentle contrast.
|
|
139
|
-
- **`pigment`
|
|
143
|
+
- **`pigment` and painterly modes mix like paint.** On a layer, a fill or a brush, `pigment` mixes the colour into
|
|
140
144
|
what is below as real paint would (Kubelka-Munk): blue into yellow gives green, white gives
|
|
141
145
|
tints, and opacity is the share of new paint (0.5 is half and half). Use it for glazes,
|
|
142
|
-
natural colour mixing and painterly strokes;
|
|
143
|
-
layers that must
|
|
146
|
+
natural colour mixing and painterly strokes; neither `pigment` nor the painterly modes (`watercolor`, `tint`, `highlight`, `shadow`) are Photoshop modes (`export_psd` writes them as Normal), so keep them off
|
|
147
|
+
layers that must stay editable in a PSD round trip. `pigment` costs about ten times a normal blend.
|
|
144
148
|
- **Name layers** (`name`) by intent ("Sky darken", "Warm skin"), so the stack stays readable.
|
|
145
149
|
- **Effects, transforms and smart objects** have their own best practices in
|
|
146
150
|
`references/layer-effects.md`, `references/free-transform.md` and `references/smart-objects.md`.
|
|
@@ -174,7 +178,7 @@ in the source frame at the document's bit depth, colour mode and profile. Read
|
|
|
174
178
|
| `measure_region` | Measure a rectangle of the composited image (`x`, `y`, `width`, `height` in natural pixels; default the crop, else the whole image) without a render: the `get_histogram` summary plus `meanColor` (hex) and `cast` (`redBlue`, `greenMagenta` in levels; within about ±4 is neutral). Check a neutral reference, skin, a background or clipping after each correction. |
|
|
175
179
|
| `render_preview` | See the edited image (crop, adjustments, layers, annotations) as a PNG, or with `layerId` one layer alone. `maxSide` 16..2048 px, default 512. Images cost tokens: render after a group of edits, use 512 for overall look and 1024+ to judge clipping, edges and masks. Fails in environments without rendering. |
|
|
176
180
|
| `inspect_psd` | Read a PSD / PSB (`data` base64) without opening it: size, `depth`, `colorMode`, `resolution`, every layer bottom first with `psdKind`, the `type` it would become (`smart`, `shape` and `type` for Photoshop smart objects, shapes and text) and `status` (`mapped`, `approximated`, `dropped`) with `notes`, and the import `warnings`. Call before `import_psd`. |
|
|
177
|
-
| `export_psd` | Save the document as
|
|
181
|
+
| `export_psd` | Save the document as a PSD in its colour mode (RGB, or CMYK / Lab channels after `set_color_mode`) with its profile, at its bit depth (RGB 8, 16 or 32; CMYK and Lab 8 or 16, so a 32-bit CMYK / Lab document is written at 16 with a warning; PSB above 30000 px), with layers, groups, adjustment layers and masks. Returns `data` (base64), `size` in bytes, `psb` and `warnings` (crop or rotation not applied, filters and depth masks baked, annotations rasterized or left out, Pigment blends written as Normal; painterly blends are written as Normal too, without a warning). Shape and type layers are written as real Photoshop shape and type layers. Changes nothing. |
|
|
178
182
|
| `get_transform_frame` | Before a transform: what it would move (`content`, `moved`: pixels, mask, selection), its `frame` (document bounds of the content), `corners` (top-left, top-right, bottom-right, bottom-left) and `center`. `meshColumns` / `meshRows` also return an identity warp `mesh` over the frame to edit for `warp_layer`. Changes nothing. |
|
|
179
183
|
| `get_smart_object` | Read a smart object: `contents` (`id` shared by linked instances, `name`, `kind` raster or document, `width` / `height`, `decoded`, `fileType`, `linkedPath`, `instances`), `placement` (`corners`, `warp` in contents px, `interpolation`, and when `affine` the `scaleX` / `scaleY` in percent of the contents, `rotate`, `skewX`, `center`, `bounds`) and `smartFilters` (`enabled`, `filters` bottom to top with ids, settings, `blend`, `opacity`; kind `psd` is a Photoshop filter kept but not drawn; the filter `mask`). Call before changing a smart object. |
|
|
180
184
|
| `list_fonts` | Read the font families type layers can use here (generic families always work) and which shaper draws them. Call before choosing a font. |
|
|
@@ -381,13 +385,7 @@ The host may add the shared document tools (see `pixerate-agent-tools`). An imag
|
|
|
381
385
|
## Pitfalls
|
|
382
386
|
|
|
383
387
|
- Agent playback (if on) opens each write's panel, then traces `points`, drags boxes or visits the layers and sliders named; results are unchanged.
|
|
384
|
-
-
|
|
385
|
-
- `bevel-emboss` has no `blend` / `opacity`: it uses `highlightBlend`, `highlightOpacity`,
|
|
386
|
-
`shadowBlend` and `shadowOpacity`. Inner shadows and inner glows use `choke`, not `spread`.
|
|
387
|
-
- Glows paint a colour or a gradient, never a pattern; strokes take all three. Pattern effects
|
|
388
|
-
need a pattern id from `list_layer_effects.patterns`; an unknown id paints nothing.
|
|
389
|
-
- Effect angles are where the light comes *from*: 120° (top left) casts a shadow down and to
|
|
390
|
-
the right. With `useGlobalLight` true an effect's own `angle` is ignored.
|
|
388
|
+
- Domain-specific pitfalls live in their references: layer styles in [references/layer-effects.md](references/layer-effects.md), provider effects in [references/provider-effects.md](references/provider-effects.md), painting and the Mixer Brush in [references/painting.md](references/painting.md), retouching in [references/retouching.md](references/retouching.md), shapes and text in [references/shapes-and-type.md](references/shapes-and-type.md), smart objects in [references/smart-objects.md](references/smart-objects.md), Free Transform in [references/free-transform.md](references/free-transform.md), colour management in [references/color-management.md](references/color-management.md), and PSD in [references/photoshop-files.md](references/photoshop-files.md).
|
|
391
389
|
- A layer's `kind` cannot change; to switch kinds add a new layer and remove the old one.
|
|
392
390
|
Curves points, `colorize` and colours are only set when the layer is added, so get them
|
|
393
391
|
right in `add_adjustment_layer` (or replace the layer).
|
|
@@ -395,41 +393,7 @@ The host may add the shared document tools (see `pixerate-agent-tools`). An imag
|
|
|
395
393
|
`locks` only when the user wants that layer changed.
|
|
396
394
|
- `merge_down`, `merge_visible` and `flatten_image` merge annotation layers only in a browser
|
|
397
395
|
(they need a canvas); elsewhere they fail and say so.
|
|
398
|
-
-
|
|
399
|
-
- `paint_stroke`, `fill_pixels` and `clear_pixels` need a visible pixel layer (or a layer with a
|
|
400
|
-
raster mask and `channel: "mask"`); adjustment, group, shape, type, annotation and smart object layers can
|
|
401
|
-
only be painted through their masks (and a smart object through `channel: "filter-mask"`).
|
|
402
|
-
To paint a smart object's pixels, `edit_smart_object_contents` or rasterize it. A layer with
|
|
403
|
-
`locks.pixels` refuses paint.
|
|
404
|
-
- Text ranges count UTF-16 code units (an emoji is two). Point text grows from its origin: centred
|
|
405
|
-
text is centred on `x`. Type cannot be distorted, put in perspective or warped; it can be scaled,
|
|
406
|
-
rotated and skewed. Where no font shaper exists (a server without one), type layers keep their
|
|
407
|
-
stored pixels and edits are refused with a reason.
|
|
408
|
-
- Shape strokes are not layer-effect strokes: `stroke` on `add_shape_layer` / `update_shape`
|
|
409
|
-
follows the path (and its dashes and caps); `add_layer_effect` `stroke` outlines the rendered
|
|
410
|
-
pixels. Arrowheads belong to `line` live shapes (their `width` and `length` are pixels), not to
|
|
411
|
-
strokes. A shape drawn over an annotation migrated from an old document (a shape layer with an
|
|
412
|
-
`annotation` in `list_layers`) stops being that annotation once you edit it as a shape.
|
|
413
|
-
- Shapes render up to 512 px beyond the canvas; moving one in from far outside draws it again
|
|
414
|
-
from its paths, so nothing is lost.
|
|
415
|
-
- While contents are open (`edit_smart_object_contents`), `list_layers` and every tool see the
|
|
416
|
-
contents, not the document, and `export_psd` / saving write the document without the open
|
|
417
|
-
edits. Close with `close_smart_object_contents` before anything else.
|
|
418
|
-
- Smart filters run over the canvas, like layer filters: a blur clamps at the canvas edge, and a
|
|
419
|
-
smart object is drawn only up to 512 px beyond the canvas. `get_transform_frame` on a smart
|
|
420
|
-
object returns the contents' rectangle (contents px) as the `frame`, and a warp `mesh` in
|
|
421
|
-
contents px.
|
|
422
|
-
- `mix_colors` predicts a mix; it does not paint. To paint the mix, pass `blend: "pigment"` to
|
|
423
|
-
`paint_stroke` (in `brush`) or `fill_pixels`, or set it on a layer.
|
|
424
|
-
- `pigment` has no PSD equivalent: `export_psd` writes those layers as Normal (the merged image
|
|
425
|
-
keeps the look) and says so in `warnings`, naming the layers. `import_psd` never produces it.
|
|
426
|
-
Over transparent pixels there is nothing to mix with, so it lays the colour down as Normal.
|
|
427
|
-
- The Mixer Brush ignores `brush.blend` (including `pigment`; use its own `mixer.mixing` instead) and the opacity ceiling: each dab lays paint at
|
|
428
|
-
`flow × opacity` over the pixels as they are now, so overlapping dabs build up. At `flow` 1
|
|
429
|
-
each dab covers what is under it, the pickup then sees mostly the brush's own paint, and the
|
|
430
|
-
stroke drifts towards the loaded colour; lower the flow for more blending.
|
|
431
|
-
- An empty, dry mixer (no reservoir, `wet` 0) paints nothing; the call succeeds with
|
|
432
|
-
`bounds: null`. A mixer stroke over transparent pixels has nothing to pick up.
|
|
396
|
+
- `pigment` and the painterly blend modes (`watercolor`, `tint`, `highlight`, `shadow`) have no Photoshop mode in the image editor's PSD exporter: `export_psd` writes those layers as Normal (the merged image keeps the composited look; only `pigment` adds a warning, naming the layers). `import_psd` never produces them.
|
|
433
397
|
- `export_psd` is in the source frame: a crop or rotation is not in the file (the warnings say
|
|
434
398
|
so). Crop with `set_crop` only for PNG / JPEG output, or flatten the look you need first.
|
|
435
399
|
- PSD opacity, fill and mask density come in as whole percents (Photoshop stores bytes), so a
|
|
@@ -444,19 +408,10 @@ The host may add the shared document tools (see `pixerate-agent-tools`). An imag
|
|
|
444
408
|
Do not keep raising it; correct the green-magenta cast with a `colorBalance` layer instead.
|
|
445
409
|
- Base `opacity` fades the whole image, not an adjustment. Base `blur` blurs a whole layer (the
|
|
446
410
|
Background by default, before the adjustment layers; in older documents with blur and
|
|
447
|
-
adjustment layers, the output after them).
|
|
411
|
+
adjustment layers, the output after them). For local softening use `blur_stroke`.
|
|
448
412
|
- New adjustment layers go above the other adjustment layers and below annotations, so they
|
|
449
413
|
never tint arrows, labels or watermarks. `list_layers` shows where each one went.
|
|
450
414
|
- `invert` and `threshold` are destructive-looking creative effects; never use them for a
|
|
451
415
|
correction the user did not ask for. Posterize `levels` below ~8 bands visibly.
|
|
452
|
-
- Transforms refuse hidden layers, layers with `locks.position` or `locks.pixels`, and adjustment,
|
|
453
|
-
annotation and group layers (transform a layer's mask with `channel: "mask"` after unlinking
|
|
454
|
-
it). A result larger than about 11 600 × 11 600 px is refused.
|
|
455
|
-
- `transform_layer` scale fields are percent (100 = unchanged), not factors; `rotate` is degrees
|
|
456
|
-
clockwise. `corners` that cross or fold through the horizon are refused: keep the quad convex.
|
|
457
|
-
- With a selection, `content: "auto"` (the default) moves only the selected pixels, not the
|
|
458
|
-
whole layer. Pass `content: "layer"` to move everything regardless of the selection.
|
|
459
|
-
- A Background transformed smaller leaves transparent canvas around it; fill it with a layer
|
|
460
|
-
below or crop afterwards.
|
|
461
416
|
- Opacity values are 0..1, not percent. Curves and levels points are 0..255 levels; levels
|
|
462
417
|
`gamma` is 0.1..9.99 (1 = neutral); hue is degrees -180..180.
|
|
@@ -38,6 +38,7 @@ means sRGB. The viewport assumes an sRGB display and converts other working spac
|
|
|
38
38
|
`unconvertedLayerIds`: convert inside them (`edit_smart_object_contents`) if the look matters.
|
|
39
39
|
- Images opened from a URL or file in the browser arrive already converted to sRGB by the
|
|
40
40
|
browser, so their own profile is not kept; PSDs keep theirs (resource 1039).
|
|
41
|
-
- `export_psd`
|
|
41
|
+
- `export_psd` embeds the profile (the working space for RGB, the press profile for CMYK; Lab
|
|
42
|
+
files carry none); PNG and JPEG exports embed it when it is not sRGB.
|
|
42
43
|
- The first proof or conversion with `coated-cmyk` builds that profile, which takes a second or
|
|
43
44
|
two.
|
|
@@ -31,3 +31,15 @@ How to move, scale, rotate, skew, distort and warp layers, selected pixels and m
|
|
|
31
31
|
- **Scale proportionally** unless asked to stretch: give `scaleX` and `scaleY` the same value.
|
|
32
32
|
Keep the subject in frame: after a scale about `center` the layer can run past the canvas,
|
|
33
33
|
which `bounds` in the result shows.
|
|
34
|
+
|
|
35
|
+
## Pitfalls
|
|
36
|
+
|
|
37
|
+
- Transforms refuse hidden layers, layers with `locks.position` or `locks.pixels`, and adjustment,
|
|
38
|
+
annotation and group layers (transform a layer's mask with `channel: "mask"` after unlinking
|
|
39
|
+
it). A result larger than about 11 600 × 11 600 px is refused.
|
|
40
|
+
- `transform_layer` scale fields are percent (100 = unchanged), not factors; `rotate` is degrees
|
|
41
|
+
clockwise. `corners` that cross or fold through the horizon are refused: keep the quad convex.
|
|
42
|
+
- With a selection, `content: "auto"` (the default) moves only the selected pixels, not the
|
|
43
|
+
whole layer. Pass `content: "layer"` to move everything regardless of the selection.
|
|
44
|
+
- A Background transformed smaller leaves transparent canvas around it; fill it with a layer
|
|
45
|
+
below or crop afterwards.
|
|
@@ -34,3 +34,13 @@ Read this before `add_layer_effect`, `update_layer_effect`, `set_global_light` o
|
|
|
34
34
|
layer `opacity` fades the effects too.
|
|
35
35
|
- **Prefer an effect over painted pixels** for shadows, glows, outlines and colour fills of a
|
|
36
36
|
shape: it follows later edits and stays adjustable.
|
|
37
|
+
|
|
38
|
+
## Pitfalls
|
|
39
|
+
|
|
40
|
+
- Effects need a shape: on an empty layer they draw nothing. They cannot go on adjustment layers. A clipped layer's effects stay inside the layer it is clipped to.
|
|
41
|
+
- `bevel-emboss` has no `blend` / `opacity`: it uses `highlightBlend`, `highlightOpacity`,
|
|
42
|
+
`shadowBlend` and `shadowOpacity`. Inner shadows and inner glows use `choke`, not `spread`.
|
|
43
|
+
- Glows paint a colour or a gradient, never a pattern; strokes take all three. Pattern effects
|
|
44
|
+
need a pattern id from `list_layer_effects.patterns`; an unknown id paints nothing.
|
|
45
|
+
- Effect angles are where the light comes *from*: 120° (top left) casts a shadow down and to
|
|
46
|
+
the right. With `useGlobalLight` true an effect's own `angle` is ignored.
|
|
@@ -43,3 +43,20 @@ Read this before `mix_colors`, a `paint_stroke` with `tool: "mixer"`, or gradien
|
|
|
43
43
|
"gradient", stops, map }`, or `paint_stroke` `paint` for one stroke (brush only). `map.by`
|
|
44
44
|
`distance` (default 300 px, mirrored) for drag-it-out colour, `pressure`, `direction`,
|
|
45
45
|
`across-tip`, `random`; stops may be `"paint"` / `"secondary"` (foreground / background).
|
|
46
|
+
|
|
47
|
+
## Pitfalls
|
|
48
|
+
|
|
49
|
+
- `paint_stroke`, `fill_pixels` and `clear_pixels` need a visible pixel layer (or a layer with a
|
|
50
|
+
raster mask and `channel: "mask"`); adjustment, group, shape, type, annotation and smart object layers can
|
|
51
|
+
only be painted through their masks (and a smart object through `channel: "filter-mask"`).
|
|
52
|
+
To paint a smart object's pixels, `edit_smart_object_contents` or rasterize it. A layer with
|
|
53
|
+
`locks.pixels` refuses paint.
|
|
54
|
+
- `mix_colors` predicts a mix; it does not paint. To paint the mix, pass `blend: "pigment"` to
|
|
55
|
+
`paint_stroke` (in `brush`) or `fill_pixels`, or set it on a layer.
|
|
56
|
+
- `pigment` and the painterly blend modes (`watercolor`, `tint`, `highlight`, `shadow`) have no Photoshop mode in the image editor's PSD exporter: `export_psd` writes those layers as Normal (the merged image keeps the look; only `pigment` adds a warning, naming the layers). `import_psd` never produces them. Over transparent pixels there is nothing for `pigment` to mix with, so it lays the colour down as Normal.
|
|
57
|
+
- The Mixer Brush ignores `brush.blend` (including `pigment`; use its own `mixer.mixing` instead) and the opacity ceiling: each dab lays paint at
|
|
58
|
+
`flow × opacity` over the pixels as they are now, so overlapping dabs build up. At `flow` 1
|
|
59
|
+
each dab covers what is under it, the pickup then sees mostly the brush's own paint, and the
|
|
60
|
+
stroke drifts towards the loaded colour; lower the flow for more blending.
|
|
61
|
+
- An empty, dry mixer (no reservoir, `wet` 0) paints nothing; the call succeeds with
|
|
62
|
+
`bounds: null`. A mixer stroke over transparent pixels has nothing to pick up.
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
(kind `psd`): hide, reorder, re-blend or remove them, and `export_psd` writes them back.
|
|
41
41
|
5. **`export_psd` writes the stack as it is**, in the source frame: crop and rotation are not
|
|
42
42
|
applied, layer filters and depth masks are baked, annotation layers are rasterized (only in
|
|
43
|
-
a browser). Effects are written as Photoshop layer styles: an effects block opened from a PSD
|
|
43
|
+
a browser), and `pigment` or painterly blend modes (`watercolor`, `tint`, `highlight`, `shadow`) are written as Normal (the merged image keeps their composited look; only `pigment` adds a warning, naming the layers). Effects are written as Photoshop layer styles: an effects block opened from a PSD
|
|
44
44
|
goes back byte for byte while its effects are unchanged, and the patterns effects use (the
|
|
45
45
|
built-in ones too) are embedded. Only the first outer glow, inner glow, bevel, satin and
|
|
46
46
|
pattern overlay of a layer fit in a PSD. Smart objects are written as smart objects (an
|
|
@@ -72,3 +72,17 @@ upright-Latin runs) and goes back out as vertical type. `get_text_layer` reports
|
|
|
72
72
|
and `missingFonts` for those: if a font is missing, edits draw with a fallback, so tell the user
|
|
73
73
|
before editing such text, or pick an available font with `set_text_style`. `export_psd` writes both
|
|
74
74
|
kinds back as Photoshop layers; unchanged ones are written byte for byte as they were read.
|
|
75
|
+
|
|
76
|
+
## Pitfalls
|
|
77
|
+
|
|
78
|
+
- Text ranges count UTF-16 code units (an emoji is two). Point text grows from its origin: centred
|
|
79
|
+
text is centred on `x`. Type cannot be distorted, put in perspective or warped; it can be scaled,
|
|
80
|
+
rotated and skewed. Where no font shaper exists (a server without one), type layers keep their
|
|
81
|
+
stored pixels and edits are refused with a reason.
|
|
82
|
+
- Shape strokes are not layer-effect strokes: `stroke` on `add_shape_layer` / `update_shape`
|
|
83
|
+
follows the path (and its dashes and caps); `add_layer_effect` `stroke` outlines the rendered
|
|
84
|
+
pixels. Arrowheads belong to `line` live shapes (their `width` and `length` are pixels), not to
|
|
85
|
+
strokes. A shape drawn over an annotation migrated from an old document (a shape layer with an
|
|
86
|
+
`annotation` in `list_layers`) stops being that annotation once you edit it as a shape.
|
|
87
|
+
- Shapes render up to 512 px beyond the canvas; moving one in from far outside draws it again
|
|
88
|
+
from its paths, so nothing is lost.
|