nanoraster
0.7.1

Format and annotate

Choose the encoder, background, and quality, then add the axis indicator, label, and scale bar that let a render stand on its own.

Open Markdown

Five choices decide what leaves the renderer: format, background, quality, annotations, and the dimensions annotations require.

1. Pick the format

import { renderImage } from 'nanoraster';const image = await renderImage(glb, {  format: 'webp',  quality: 1,});

Rendering…

 

Switch format and watch the badge. The MIME type and byte count change. The pixels do not change.

FormatAlphaLossyUse for
pngYesNoExact pixels, diffing, transparent thumbnails
webpYesOnly when quality is below 1Web delivery; lossless by default, optionally lossy
jpegNoYesInterop with tools that accept nothing else
jpgNoYesAlias for jpeg; the filename keeps the jpg extension
rawYesNoThe frame itself, for a diff, a video frame or a texture

mimeType reports the true type, so jpg and jpeg both report image/jpeg. The reference lists the full MIME map. raw runs no encoder; see Work with raw pixels.

2. Decide on a background

import { renderImage } from 'nanoraster';const image = await renderImage(glb, {  format: 'webp',  background: '#101418',});

Rendering…

 

The default background is transparent. PNG, WebP and raw can represent transparency; JPEG cannot. A JPEG request without an opaque background fails with an encode failure; the renderer does not silently flatten onto an arbitrary colour. Backgrounds accept #RRGGBB, #RRGGBBAA, or normalised straight-alpha RGBA such as [0.05, 0.06, 0.08, 1].

3. Tune quality per format

quality runs from 0 to 1 and means something different per format:

  • JPEG is always lossy. quality sets the compression level and defaults to 0.92.
  • WebP defaults to 1, which encodes lossless. Any value below 1 switches to the lossy codec. The lossy codec keeps alpha but never reaches exact pixels. This matches Chrome's canvas toBlob('image/webp', quality).
  • PNG and raw ignore quality.

Drag quality below 1 on the tile in step 1. The file shrinks and the pixels stop being exact.

4. Add an axis indicator, label and scale

Draw orientation, a label and a physical scale into the image. These annotations keep the render's context after it leaves the request.

import { renderImage } from 'nanoraster';const image = await renderImage(glb, {  format: 'webp',  width: 512,  height: 512,  axes: true,  scaleBar: true,  label: 'gear',});

Rendering…

 

The axis indicator is an XYZ marker in the bottom-right corner. It rotates with the camera, so it reports the view's orientation rather than a fixed key.

The renderer draws the label top-left, screen-upright, verbatim, and only when the request sets label. In a batch call, a view receives a label only when its own entry sets label.

The renderer draws the scale bar bottom-left in the model's own units. Under perspective, the scale bar is accurate at only one depth. A fitted camera labels that depth @ center; a fixed camera labels its caller-owned @ target. Under orthographic projection, scale is depth-invariant, so the label drops the qualifier. Annotations may loosen a fitted camera but never change a fixed camera.

5. Set authored-edge thickness

lineWidth controls glTF LINES primitives in output pixels, from 0.25 to 16. The default is 3. The width does not grow with image height: a 1 px line stays 1 px at 2048×2048. Meshes and lines use 4× MSAA.

const image = await renderImage(glb, { format: 'png', lineWidth: 1 });

6. Meet the minimum dimensions

Enabling any annotation raises the minimum output size to 192 pixels on both axes. A smaller request fails validation rather than producing an unreadable overlay.

const image = await renderImage(glb, {
  format: 'webp',
  width: 192,
  height: 192,
  axes: true,
});

Below that size, drop the annotations.

Variations

Smallest useful thumbnail. WebP at quality: 0.9 with width: 256 is around 60 percent smaller than the lossless default. It is a third the size of the equivalent PNG, and it keeps transparency. Sparse line art can still encode smaller lossless than lossy, so measure both when every byte matters.

Byte-exact comparison. Any lossless format works: PNG, or WebP at the default quality: 1. A lossy baseline is deterministic, but a diff then includes the encoder's losses along with the render. format: 'raw' removes the encoder from the comparison.

Alpha over an unknown page background. Use PNG or WebP and leave the background transparent, then let the page composite it.

Annotations plus a tight fit. The renderer draws overlays inside the frame, so a margin near 0 can put the subject underneath them. Keep the default margin when you annotate.

On this page