export

package
v0.0.0-...-0b57a39 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 25, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Package export encodes still renderer output to PNG and GIF.

GIF capture accumulates per-frame delays as time.Duration internally; conversion to centiseconds (1/100s) happens at finalize. Delays shorter than 10 ms round up to 1 cs; the maximum representable delay is about 655.35s (65535cs). WithChannel accepts explicit Frame.Delay values preserved as Duration until finalize; zero delay accumulates elapsed wall time since the last capture attempt (including deduped ticks). Non-strict WithFrameRate snaps accumulated delays to the nearest nominal FPS grid at finalize.

WithMaxFrames limits in-memory GIF capture to the last n palettized frames (after dedup when OptimizeFrames is enabled). Dropped frame delays are not carried forward; disposal optimization runs on the retained window only.

Export defaults to OptimizeAll when WithOptimize is omitted. GIF uses frame dedup, disposal/sub-rect optimization, and palette compaction. PNG applies OptimizeColorQuantization only (OptimizeFrames and OptimizeDirtyRects are stripped). Pass OptimizeNone for unoptimized GIF or full RGBA PNG with alpha preserved.

GIF palette transparency

The capture and optimization pipeline reserves palette index 255 (TransparentPaletteIndex) for transparency. During palettization, fully transparent source pixels (alpha 0) map to this index; opaque pixels that would otherwise quantize to 255 are remapped to 254 so the slot stays free. The default xterm-256 capture palette pre-fills slot 255 with a zero-alpha marker instead of the grayscale color that would occupy it otherwise.

At finalize, disposal sub-rect optimization marks unchanged pixels with TransparentPaletteIndex; GIF viewers require a zero-alpha palette entry at that index (finalize patches opaque slot 255 when needed). Palette compaction may move transparent pixels to a lower index but keeps a zero-alpha palette entry so ReplayGIF can detect transparency.

Custom capture palettes (WithPalette) with 256 entries should leave slot 255 transparent when using disposal optimization; finalize patches an opaque slot 255 automatically when the palette is long enough.

Index

Constants

View Source
const (

	// MaxFrameRate is the highest FPS accepted by [WithFrameRate]. GIF delays
	// are stored in centiseconds, so cannot represent more than 100 FPS.
	MaxFrameRate = 100
)
View Source
const TransparentPaletteIndex uint8 = 255

TransparentPaletteIndex is the palette index reserved for transparency during GIF capture and optimization. See package documentation for the full invariant.

Variables

This section is empty.

Functions

func GIF

func GIF(path string, opts ...Option) (closer func() error, err error)

GIF records animated frames to path. Returns a closer that finalizes and encodes on first call; later calls are no-op. Setup errors are returned immediately; finalize and encode errors come from the closer.

func MustGIF

func MustGIF(path string, opts ...Option) func()

MustGIF is a convenience wrapper around GIF that panics on setup or close errors.

func MustPNG

func MustPNG(img image.Image, path string, opts ...Option)

MustPNG is a convenience wrapper around PNG that panics on error.

func PNG

func PNG(img image.Image, path string, opts ...Option) error

PNG writes img to path using opts. By default OptimizeAll applies (indexed paletted PNG via the internal palette). Pass WithOptimize(OptimizeNone) to encode full RGBA with alpha preserved.

func ReplayGIF

func ReplayGIF(r io.Reader) ([]image.Image, error)

ReplayGIF decodes r and reconstructs each animation frame as a full-canvas NRGBA image, undoing disposal methods (None, Background, Previous) in order.

func WriteGIF

func WriteGIF(w io.Writer, opts ...Option) (closer func() error, err error)

WriteGIF records animated frames to w. See GIF for lifecycle and errors.

func WritePNG

func WritePNG(img image.Image, w io.Writer, opts ...Option) error

WritePNG encodes img to w. See PNG for format behavior and option notes.

Types

type Frame

type Frame struct {
	Image image.Image
	Delay time.Duration
}

Frame is the channel payload for WithChannel. Delay zero accumulates elapsed time since the last capture attempt (including deduped ticks) as Duration until finalize, when it is rounded once to centiseconds (minimum 1 cs). Explicit delays are preserved as Duration until finalize.

type FrameRecorder

type FrameRecorder struct {
	// contains filtered or unexported fields
}

FrameRecorder captures palettized GIF frames using the production append path.

func NewFrameRecorder

func NewFrameRecorder() *FrameRecorder

NewFrameRecorder returns a recorder configured like default GIF capture.

func (*FrameRecorder) AddFrame

func (fr *FrameRecorder) AddFrame(frame image.Image, delay time.Duration) error

AddFrame palettizes and appends one frame.

type OptimizeFlags

type OptimizeFlags uint

OptimizeFlags selects post-process and capture optimizations. Each WithOptimize call replaces the full flag set; OptimizeNone resets to zero.

When WithOptimize is omitted, export defaults to OptimizeAll. On PNG, GIF-only flags are stripped so only OptimizeColorQuantization applies.

const (
	OptimizeNone OptimizeFlags = 0
	// OptimizeFrames deduplicates byte-identical GIF frames during capture,
	// merging their delays. GIF only; ignored on PNG.
	OptimizeFrames OptimizeFlags = 1 << iota
	// OptimizeDirtyRects runs disposal/sub-rect optimization at GIF finalize.
	// GIF only; ignored on PNG.
	OptimizeDirtyRects
	// OptimizeColorQuantization compacts the GIF palette at finalize when no
	// custom palette is set, or encodes PNG as an indexed paletted image.
	OptimizeColorQuantization

	// OptimizeAll enables every optimization flag above. On PNG export, GIF-only
	// bits are ignored and only color quantization runs.
	OptimizeAll = OptimizeFrames | OptimizeDirtyRects | OptimizeColorQuantization
)

type Option

type Option func(*options)

Option configures PNG or GIF exports. Options are validated in collectOptions; GIF-only capture options return an error from PNG entry points.

func WithBackground

func WithBackground(c color.Color) Option

WithBackground sets an opaque compositing color for semi-transparent GIF pixels before palettization. GIF only.

func WithChannel

func WithChannel(ch <-chan Frame) Option

WithChannel reads frames from ch until it is closed, then finalizes and encodes. The returned closer can cancel early; either channel close or the first closer call triggers finalize (once). GIF only.

func WithFrameRate

func WithFrameRate(fps int, strict bool, fn func() image.Image) Option

WithFrameRate captures frames from fn at FPS. When strict is true, each tick stores an exact delay of time.Second/FPS and ticks are skipped if fn is still running; delays are grid-snapped to max(1, 100/FPS) centiseconds at finalize. When strict is false, delay accumulates wall time per tick and snaps to the nearest nominal FPS grid at finalize. GIF only.

It is important to note that most browsers support a max of 50 FPS (and if higher, will actually cap at 10 FPS). Most operating systems and supported GIF players will cap at 100 FPS. Additionally, as GIFs use centiseconds for per-frame delays, the maximum is MaxFrameRate FPS (even if we could export higher). Additionally, for smoother GIFs, prefer centisecond-aligned FPS (10, 20, 25, 50, 100).

fn must return quickly and must not retain the returned image.Image beyond the call (same contract as [still.Renderer.Draw] buffer reuse).

func WithMaxFrames

func WithMaxFrames(n int) Option

WithMaxFrames keeps only the last n palettized frames in memory during GIF capture. When OptimizeFrames is enabled, duplicate consecutive frames merged during dedup do not consume cap slots. Oldest frames are dropped without carrying their delays forward. n == 0 disables the cap (same as omitting this option). GIF only.

func WithOptimize

func WithOptimize(flags OptimizeFlags) Option

WithOptimize sets optimization flags, replacing any prior WithOptimize call. Pass OptimizeNone to disable all optimizations.

When omitted, export defaults to OptimizeAll. Pass OptimizeNone for full RGBA PNG with alpha preserved.

func WithPalette

func WithPalette(p color.Palette) Option

WithPalette overrides the capture palette for GIF palettization. Disables automatic palette compaction when OptimizeColorQuantization is set. GIF only. When using disposal optimization, palettes with 256 entries should reserve TransparentPaletteIndex (255) as a zero-alpha color; see package documentation for the transparency invariant.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL