image://¶
Producer-only image component — the discoverable home for turning other content into a raster image (PNG / JPEG). Two operations today:
op=screenshot(default) — rasterize an HTML body to a PNG/JPEG via headless Chromium (chromedppage.CaptureScreenshot). Highest fidelity: Tailwind, web fonts, complex CSS. Requires achromium/google-chromebinary on PATH at runtime.op=rasterize— render a page of a PDF body to a PNG/JPEG via pdfium (viaklippa-app/go-pdfium, WebAssembly — no CGO, no browser). The Chrome-free path for page previews / thumbnails.
Output is image bytes on the exchange body (Content-Type: image/png or
image/jpeg), ready for a file:// write or an HTTP response.
The heavy engines are shared with pdf:// and vlm:// via
pkg/component/internal: chromerender (the headless-Chromium round-trip,
also used by pdf:// mode=chrome) and pdfiumpool (one process-wide PDFium
WASM pool, also used by pdf:// op=fillForm and vlm://).
Producer-only — CreateConsumer returns ErrNoConsumer.
When to use which¶
| You have… | …and want a | Use |
|---|---|---|
| HTML (Tailwind / CSS / charts) | high-fidelity PNG/JPEG | image://?op=screenshot |
| an existing PDF | page thumbnail / preview, no browser | image://?op=rasterize |
| a structured doc, no Chromium | image, fully pure-Go | pdf://?op=create&mode=native → image://?op=rasterize |
| HTML | a PDF (not an image) | pdf://?mode=chrome |
URI shape¶
image://<name>?op=screenshot&width=1200&height=800&deviceScaleFactor=2&format=png
image://<name>?op=screenshot&fullPage=true&format=jpeg&quality=85
image://<name>?op=rasterize&page=1&dpi=150&format=png
Omitting op= defaults to screenshot.
Parameters¶
General (both ops)¶
| Param | Type | Default | Description |
|---|---|---|---|
op |
enum | screenshot |
screenshot (HTML→image, Chromium) or rasterize (PDF page→image, pdfium). |
format |
enum | png |
Output image format: png or jpeg. |
quality |
integer | 90 |
JPEG compression quality [0..100]; ignored for png. |
screenshot (Chromium)¶
| Param | Type | Default | Description |
|---|---|---|---|
width |
integer | 1200 |
Viewport width in CSS px. |
height |
integer | 800 |
Viewport height in CSS px. With fullPage=true the captured height grows to the whole page. |
deviceScaleFactor |
number | 1 |
Device pixel ratio; 2 = retina / 2× output resolution. |
fullPage |
boolean | false |
Capture the whole scrollable page instead of just the viewport. |
chromePath |
string | autodiscover | Explicit Chromium / Chrome binary path. |
timeout |
duration | 30s |
Render timeout. |
waitSelector |
string | — | Wait for a CSS selector to appear before capturing. |
waitMs |
integer | — | Fixed wait in milliseconds before capturing (use sparingly). |
rasterize (pdfium)¶
| Param | Type | Default | Description |
|---|---|---|---|
page |
integer | 1 |
1-indexed PDF page to render. Out-of-range errors. |
dpi |
integer | 150 |
Render resolution in DPI; output pixel size ≈ pageSize(in) × dpi. |
Body contracts¶
op=screenshot— the body must be HTML: astringor[]byte. It is loaded as adata:text/html;charset=utf-8,…URL and captured.op=rasterize— the body must be PDF bytes: a[]byte, astring, or anio.Readerwhose content contains the%PDF-magic. A non-PDF body is rejected up front.
Headers (written)¶
| Header | Description |
|---|---|
Content-Type |
image/png or image/jpeg. |
image.op |
Operation that ran (screenshot / rasterize). |
image.format |
png or jpeg. |
image.bytes |
Output size in bytes. |
image.page |
(rasterize) The 1-indexed page rendered. |
image.width, image.height |
(rasterize) Output pixel dimensions. |
The body is set to the image []byte; the exchange's In() body is also
overwritten so the next pipeline step sees the image.
Examples¶
Screenshot an HTML poster to a retina PNG and write it to disk:
workflows:
- id: poster
trigger: { uri: direct://render }
steps:
- set-body: { starlang: payload.html } # an HTML string
- target: image://poster?op=screenshot&width=1080&height=1080&deviceScaleFactor=2&format=png
- set-header: { name: HelixFileName, constant: poster.png }
- target: file:///var/out # default op=write
Return a screenshot straight over HTTP (image bytes become the response body):
- id: og-image
trigger: { uri: http-server://0.0.0.0:8080/og }
steps:
- set-body: { starlang: payload.html }
- target: image://og?op=screenshot&width=1200&height=630&format=png
Full-page JPEG capture (whole scrollable page, not just the viewport):
Wait for an async chart to render before capturing:
Thumbnail page 1 of an uploaded PDF — pure-Go, no Chromium:
- id: pdf-thumb
trigger: { uri: "file:///var/in?include=.*\\.pdf" }
steps:
- target: image://thumb?op=rasterize&page=1&dpi=120&format=png
- set-header: { name: HelixFileName, starlang: 'headers["HelixFileName"] + ".png"' }
- target: file:///var/thumbs
Structured content → image with no browser at any step (native PDF, then pdfium raster):
- set-body:
starlang: |
{ "title": "Weekly Report", "text": "Generated without a browser." }
- target: pdf://doc?op=create&mode=native # fpdf → PDF bytes (pure-Go)
- target: image://page?op=rasterize&dpi=150 # pdfium → PNG bytes (pure-Go)
Behavior notes¶
screenshotneeds Chromium;rasterizedoes not. Only arbitrary-HTML rasterization is browser-bound — there is no pure-Go engine that renders modern HTML/CSS at fidelity. Every PDF/structured path to an image (rasterize, orpdf://mode=native→rasterize) is pure-Go.fullPagesetsCaptureBeyondViewport— the capture extends past the viewport to the full document height. Without it you get exactlywidth × height(×deviceScaleFactor) pixels.deviceScaleFactormultiplies the raster resolution: a400×300viewport atdeviceScaleFactor=2yields an800×600image.rasterizedraws the form layer (RenderForm), so filled AcroForm field values appear in the raster — the same renderingvlm://uses.- Shared engines —
screenshotruns the samechromerenderround-trip aspdf://mode=chrome;rasterizeuses the same process-wide pdfium pool aspdf://op=fillFormandvlm://. One Chromium launch path, one WASM module. - Both ops overwrite the In() body — the next pipeline step sees the image bytes, not the HTML / PDF input.
Source¶
pkg/component/image/image.go— component, endpoint, param parsing, op dispatch.pkg/component/image/screenshot.go—op=screenshot(chromerender).pkg/component/image/rasterize.go—op=rasterize(pdfiumpool).pkg/component/internal/chromerender/render.go— shared headless-Chromium round-trip.pkg/component/internal/pdfiumpool/pool.go— shared PDFium WASM pool.
See also¶
- pdf — HTML→PDF (
mode=chrome) and structured→PDF (mode=native); pairmode=nativewithimage://op=rasterizefor a browser-free content→image path. - chart — native chart rendering (render a chart, drop it into HTML, screenshot the result).
- template — build the HTML you feed into
op=screenshot. - vlm — shares the same pdfium engine to rasterise PDF pages for vision models.
- file, s3 — common downstream sinks for the rendered image.