# pxstud.io Lua scripting API — Pixels

> Part of the pxstud.io Lua scripting reference, whose overview (https://pxstud.io/docs/scripting.md) explains its conventions. The option groups and types it refers to are in https://pxstud.io/docs/scripting/option-groups.md and https://pxstud.io/docs/scripting/types.md. Everything in one file: https://pxstud.io/llms-full.txt. The whole site's index: https://pxstud.io/llms.txt.

### Pixels
Pixel reads and writes as flat RGBA lists (built on Images; never selection-clipped or mirrored), whole-selection fills and flips, and the eyedropper.

#### `app.clearSelection(layerId, frameId)` — changes, undoable, refused on a locked layer
Clears the selection to fully transparent, trimming the cel to what's left (an emptied cel is removed, with every frame linked to it); with nothing selected, removes this frame's cel (a linked frame only drops its link). On the Background layer everything clears to the background colour.

- `layerId` (string)
- `frameId` (string)

Returns nothing.

#### `app.fillSelection(layerId, frameId, color, opts?)` — changes, undoable, refused on a locked layer
Fills the selection (or the whole cel, if nothing's selected) with a solid color. A plain fill (copy) unless `ink` is given: unlike the drawing commands it never takes the editing context's ink, matching Edit > Fill.

- `layerId` (string)
- `frameId` (string)
- `color` (table) — { r, g, b, a } — each 0-255.
- `opts` (table, optional)
  - `ink` (Ink: "copy" | "simple" | "lock-alpha" | "shading"; default "copy") — copy replaces pixels, simple alpha-composites, lock-alpha recolors only visible pixels, shading steps colors along `shades`. Ignored by erase.
  - `shades` (a list of colors ("#rrggbb[aa]" or { r, g, b, a }), in ramp order) — The ramp shading steps along. A pixel whose color is not in the list is untouched; a pixel at the end of the list stays there.
  - `shadeReverse` (boolean; default false) — Shading steps backward in `shades` (the GUI's right mouse button) instead of forward.

Returns nothing.

#### `app.flipCelRegion(layerId, frameId, axis)` — changes, undoable, refused on a locked layer
Flips the selected pixels (or the whole cel, if nothing's selected) within the selection's bounds: every selected pixel moves to its mirror, the ones left behind clear (to the background colour on the Background layer) and the marquee flips too.

- `layerId` (string)
- `frameId` (string)
- `axis` (FlipAxis: "horizontal" | "vertical")

Returns nothing.

#### `app.getCompositePixels(frameId, x, y, width, height)` — pure
app.getCompositeImage's pixels as a flat RGBA list in the app.getPixels shape. At most 262144 pixels per call.

- `frameId` (string)
- `x` (number)
- `y` (number)
- `width` (number)
- `height` (number)

Returns (table): Flat RGBA list.

#### `app.getPixels(layerId, frameId, x, y, width, height)` — pure
Reads a width x height rectangle at (x, y) of a layer/frame's cel as a flat RGBA list (length width*height*4, row-major: pixel (px, py) starts at index (py*width + px)*4 + 1), in the shape app.setPixels takes. Pixels with no cel read as transparent (0, 0, 0, 0). Built on app.getImage, which is faster when you don't need a list. At most 262144 pixels per call.

- `layerId` (string)
- `frameId` (string)
- `x` (number)
- `y` (number)
- `width` (number)
- `height` (number)

Returns (table): Flat RGBA list.

#### `app.sampleColor(frameId, x, y, layerId?)` — reads
The eyedropper: the color at (x, y) as { r, g, b, a } — by default what the canvas shows there (visible layers blended with their opacity and blend modes), or one layer's color when layerId is given.

- `frameId` (string)
- `x` (number)
- `y` (number)
- `layerId` (string, optional) — Sample only this layer. Omitted = every visible layer composited, as shown on screen.

Returns (table): { r, g, b, a }, each 0-255.

#### `app.setPixels(layerId, frameId, x, y, width, height, pixels)` — pure
Overwrites a width x height rectangle at (x, y) of a layer/frame's cel with a flat RGBA list (app.getPixels' shape), as one app.putImage. Raw write: never clipped to the selection or mirrored. On indexed and grayscale sprites colours are mapped as img:setPixel maps them. At most 262144 pixels per call.

- `layerId` (string)
- `frameId` (string)
- `x` (number)
- `y` (number)
- `width` (number)
- `height` (number)
- `pixels` (table) — Flat RGBA list, length width*height*4, row-major: pixel (px, py) is at index (py*width + px)*4 + 1 (r, then g, b, a; each 0-255).

Returns nothing.
