> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nika.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# nika:image_fx

> Usage, declared contract and source links for this Nika builtin.

export const Ecosystem = () => <CardGroup cols={3}>
    <Card title="Documentation" icon="book" href="/introduction">
      Guides, reference contracts and working examples.
    </Card>
    <Card title="Nika Lab" icon="diagram-project" href="https://github.com/supernovae-st/nika-lab">
      Internal workspace and graph projections of the spec, documentation and code.
    </Card>
    <Card title="Language spec" icon="file-contract" href="https://github.com/supernovae-st/nika-spec">
      the nine-key envelope, Apache-2.0. The contract these docs explain.
    </Card>
    <Card title="Engine source" icon="gem" href="https://github.com/supernovae-st/nika">
      Rust, AGPL-3.0-or-later. Every commit public.
    </Card>
    <Card title="TypeScript SDK" icon="code" href="/sdk/overview">
      Use one typed lifecycle locally or against authenticated nika serve HTTP.
    </Card>
    <Card title="Editor extension" icon="puzzle-piece" href="https://marketplace.visualstudio.com/items?itemName=supernovae.nika-lang">
      VS Code · Cursor · Windsurf: check-as-you-type, DAG view, trace replay.
    </Card>
    <Card title="Homebrew tap" icon="beer-mug-empty" href="https://github.com/supernovae-st/homebrew-tap">
      `brew install supernovae-st/tap/nika` for the latest tagged CLI release.
    </Card>
    <Card title="SuperNovae" icon="star" href="https://supernovae.studio">
      The Paris studio crafting Nika. 🦋
    </Card>
  </CardGroup>;

[Builtins catalog](/reference/builtins) / `nika:image_fx`

<CardGroup cols={2}>
  <Card title="Media" icon="layer-group">Tool family from the canonical registry.</Card>
  <Card title="invoke" icon="code" href="/reference/language/words/invoke">Call this builtin through the invoke verb.</Card>
</CardGroup>

## Read this contract

This reference preserves the specification at the revision linked below. Source examples are **fragments**: their surrounding tasks, inputs and permissions are not supplied here. Consult [engine status](/reference/status) and `nika catalog --tools --json` for the installed implementation; a registry declaration is not a runtime qualification.

## Usage and behavior

```yaml illustration theme={"system"}
invoke:
  tool: "nika:image_fx"
  args:
    input: out/hero-openai-gptimage2-0-a1b2c3d4.png   # source PNG (read-gated)
    out: out/hero-styled.png                          # artifact path (write-gated)
    seed: 42                                          # optional · default 0
    ops:                                              # ordered · single-key op maps
      - resize: { width: 320 }                        # linear-light · auto|nearest|bilinear
      - dither: { mode: floyd_steinberg, palette: gameboy }
      - grain: { intensity: 32 }
      - scanlines: { strength: 110, period: 4 }
      - vignette: { strength: 140 }
```

The §Media graduate #3 (the `image editing` deferred row) — the
DETERMINISTIC sibling of `image_generate`: pure pixel transform, NO
provider, NO network, NO clock. **Byte-identical output forever** for
identical `(input bytes, args)` — the artifact's sha256 joins the
hash-chained trace, re-render IS the tamper check, and the full recipe
(contract tag `image_fx/v1` · input sha256 · seed · ops) rides the artifact itself
as a PNG `nika` tEXt chunk (no timestamp — determinism holds).
Identical bytes already at `out:` = idempotent skip (`skipped_existing`).

| Arg                | Contract                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `input`            | REQUIRED · source path · **PNG v1** (depth 8 · gray/RGB/RGBA · no Adam7) — non-PNG fails `-003` with the honest hint (produce PNG upstream via `image_generate format: png`) · read rides `permits.fs.read` · decoded-pixel budget gated from the header BEFORE any decompression (`-005`)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `out`              | REQUIRED · artifact path · extension must match the pipeline (`.png` · `.txt`/`.ans` for ascii text/ansi emits) · write rides `permits.fs.write`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `ops`              | REQUIRED · 1..=32 ordered single-key maps over the closed v1 vocabulary: `resize {width,height,filter}` · `crop {x,y,width,height}` · `levels {brightness,contrast}` · `grayscale` · `palette_map {palette}` · `dither {mode: bayer2\|bayer4\|bayer8\|blue_noise\|ign\|floyd_steinberg\|atkinson\|jjn, palette}` · `duotone {dark,light}` · `pixelate {block}` · `halftone {cell, angle: 0\|15\|45\|75}` · `grain {intensity}` · `vignette {strength}` · `chromatic_aberration {shift}` · `scanlines {strength,period}` · `glitch {line_shift,channel_shift,blocks}` · `ascii {cols, emit: png\|text\|ansi}` (ascii MUST be last — it changes the artifact type). Branching/fan-out is the WORKFLOW's job (`with:`/`after:` edges · `for_each`) — `ops` is a linear pipeline by design · unknown op parameters are rejected (`-001` — no silent style lies) |
| `palette` (in ops) | preset (`bw` · `gray4` · `gameboy` · `cga` · `okabe_ito`) or inline list of `#rrggbb` / `[r,g,b]` (2..=256 colors) · nearest-color mapping is perceptual (Oklab distance)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `seed`             | stochastic-op seed (`grain` · `glitch`) · default 0 · **the seed IS the style** — same seed, same bytes                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |

Per-op defaults + acceptance ranges (NORMATIVE — for a byte-deterministic
builtin the defaults ARE the wire contract; a second engine choosing other
defaults emits different bytes for the same YAML) ·

| Op                     | Defaults                                | Ranges                                                          |
| ---------------------- | --------------------------------------- | --------------------------------------------------------------- |
| `resize`               | `filter: auto`                          | width/height 1..=16384 (≥1 required)                            |
| `crop`                 | `x: 0` · `y: 0`                         | width/height ≥1 · rect inside image                             |
| `levels`               | `brightness: 0` · `contrast: 0`         | brightness −255..=255 · contrast −128..=128                     |
| `dither`               | `mode: floyd_steinberg` · `palette: bw` | palette 2..=256 colors                                          |
| `palette_map`          | `palette: bw`                           | palette 2..=256 colors                                          |
| `pixelate`             | —                                       | block 2..=256                                                   |
| `halftone`             | `cell: 8` · `angle: 45`                 | cell 3..=64                                                     |
| `grain`                | `intensity: 48`                         | 0..=128                                                         |
| `vignette`             | `strength: 160`                         | 0..=255                                                         |
| `chromatic_aberration` | `shift: 4`                              | 1..=16                                                          |
| `scanlines`            | `strength: 96` · `period: 4`            | strength 0..=255 · period 2..=64                                |
| `glitch`               | all 0                                   | line\_shift ≤64 · channel\_shift ≤16 · blocks ≤64 · ≥1 non-zero |
| `ascii`                | `cols: 96` · `emit: png`                | cols 2..=1024                                                   |

Input caps (normative) · per-dimension ≤16384 · decoded pixels ≤2^26
(gated from the header BEFORE any decompression · `-005`).

Output · `&#123; input, input_sha256, path, sha256, size_bytes, width, height,
format, ops_applied, seed, skipped_existing &#125;` — artifact bytes NEVER
ride outputs (the disk law, inherited verbatim). Text artifacts (ascii
`text`/`ansi` emits) report `width`/`height` `0` and `format` `txt`/`ans`.

Determinism contract (normative) · no wall-clock · no randomness beyond
the seeded stream · no float transcendentals · integer/fixed-point pixel
math · identical `(input, args)` MUST produce byte-identical artifacts
across platforms and releases within a stdlib major (the recipe carries
the stable contract tag `image_fx/v1`, never the engine build). An
engine that cannot honor this is not conformant (07-conformance §3).

Throws · `NIKA-BUILTIN-IMAGE_FX-001` invalid arguments (unknown op ·
out-of-range param · extension mismatch · `validation_error`) · `-002`
input read failed (`tool_error`) · `-003` unsupported input format
(non-PNG · exotic depth/interlace · `validation_error`) · `-004` decode
failed (structural corruption · CRC/Adler mismatch · `tool_error`) ·
`-005` decoded-pixel budget exceeded (`security_error` · never
transient) · `-006` artifact save failed (`tool_error`). Plus the
boundary `NIKA-SEC-004` (paths outside `permits.fs`).

***

## Related concepts

<CardGroup cols={2}>
  <Card title="Arguments" icon="sliders" href="/reference/language/words/args">Pass the values required by the tool contract.</Card>
  <Card title="Permissions" icon="shield" href="/concepts/security">Understand authority before granting effects.</Card>
  <Card title="Errors and recovery" icon="rotate" href="/reference/error-codes">Read diagnostics and choose a recovery policy.</Card>
  <Card title="Workflow templates" icon="file-code" href="/guides/templates">Put the fragment inside a complete workflow.</Card>
</CardGroup>

## Contract provenance

[Read the pinned specification](https://github.com/supernovae-st/nika-spec/blob/f8c5df2127c7867b2e51a2cd5712fa9d8461e73e/stdlib/builtins-v0.1.md#L677) · [Canonical registry](https://github.com/supernovae-st/nika-spec/blob/f8c5df2127c7867b2e51a2cd5712fa9d8461e73e/canon/builtins.yaml).

Tool identity: `nika:image_fx`. Specification revision: `f8c5df2127c7`.
The Lab language identity is `language:tool:image_fx`; the registry view is `ecosystem:tool/nika:image_fx`. They refer to this contract without merging their graph identities.

<Ecosystem />
