imageview

package
v0.4.1 Latest Latest
Warning

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

Go to latest
Published: May 29, 2026 License: LGPL-2.1 Imports: 21 Imported by: 0

Documentation

Overview

Package imageview provides ImageView — a view that renders a stdlib image.Image either as Unicode half-blocks (works on every terminal) or as SIXEL graphics (when the host supports it).

Half-block rendering uses U+2580 ("▀"). The cell's foreground RGB becomes the top pixel and the background RGB the bottom; one terminal cell therefore shows two vertical pixels. The result reads at roughly 50% vertical resolution but works everywhere truecolor SGR works.

SIXEL rendering uses pkg/fv/sixel.EncodeRealtime and emits a DCS string anchored to the view's screen origin. The underlying cells are blanked so the cell-diff flush doesn't fight the graphics. A terminal that doesn't support SIXEL (and reports so via FV_SIXEL=0 or by being unrecognized in sixel.IsSupported) silently falls back to half-block.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func FitCells

func FitCells(cols, rows, maxCols, maxRows int) (int, int)

FitCells scales (cols, rows) down so it fits inside (maxCols, maxRows) while preserving aspect ratio. Both axes are clamped to a minimum of 1. If the input already fits, it's returned unchanged.

func IsLikelyImageFile

func IsLikelyImageFile(path string) bool

IsLikelyImageFile is a cheap filename-suffix check; the demo's file dialog uses it as a glob hint. Real format detection only happens inside LoadFile via image.Decode.

func LoadFile

func LoadFile(path string) (image.Image, error)

LoadFile reads an image from path and returns the decoded image. PNG, JPEG, and GIF are supported via stdlib decoders. Other formats (BMP, TIFF, WebP) require additional decoder registrations and are not supported here — the caller can do that themselves and pass the decoded image to SetImage.

The returned error wraps the underlying decoder error with the path for debuggability.

func PreferredCells

func PreferredCells(img image.Image, useSixel bool) (cols, rows int)

PreferredCells returns the cell dimensions needed to display img at native pixel resolution given the rendering mode. SIXEL: one image pixel = 1/cellW × 1/cellH cells (cell sizes come from sixel.CellSize). Half-block: one image-column = 1 cell, two image-rows = 1 cell. The caller is expected to add window-frame padding and clamp to the available desktop area — this helper just answers "what size of view would be 1:1?".

Types

type ImageView

type ImageView struct {
	views.Base

	Image    image.Image
	UseSixel bool // honored only when sixel.IsSupported(); otherwise we half-block

	// Quality selects the SIXEL encoder. true = median-cut + Floyd-
	// Steinberg dither (good for photos, ~hundreds of ms one-shot);
	// false = 216-color realtime cube (instant, bands on gradients).
	// Result is cached so the per-frame cost stays at one DCS write.
	Quality       bool
	QualityColors int // palette size for the quality encoder (default 128)

	// Pan offsets (image pixels from the top-left).
	OffsetX, OffsetY int

	// Zoom factor for SIXEL mode (integer pixel replication, ≥1).
	// Half-block ignores Zoom — cells dictate fit.
	Zoom int

	// Background color for cells outside the image / half-block bottom
	// when the image height is odd.
	BG uint32
	// contains filtered or unexported fields
}

ImageView is the view.

func New

func New(bounds geom.Rect) *ImageView

New constructs an ImageView at bounds with no image loaded yet. SetImage to populate. Default UseSixel mirrors sixel.IsSupported() so that callers don't have to gate at the call site — passing a SIXEL- supporting image to a non-SIXEL terminal still draws (as half-block).

func (*ImageView) Draw

func (iv *ImageView) Draw()

Draw routes to half-block, sentinel-stamping (SIXEL), or BG fill. SIXEL emission is deferred to PreFlush so it can resolve z-order against any covering view; see PreFlush below.

func (*ImageView) GetTypeID

func (iv *ImageView) GetTypeID() string

GetTypeID for serial registry.

func (*ImageView) HandleEvent

func (iv *ImageView) HandleEvent(ev *drivers.Event)

HandleEvent implements basic pan/zoom controls:

arrows / Page{Up,Dn} / Home / End — pan
+ / -                              — zoom in/out (SIXEL only)
mouse wheel                        — vertical pan

func (*ImageView) PreFlush

func (iv *ImageView) PreFlush(b views.RootBackend)

PreFlush implements views.PreFlusher. Sentinel cells written by Draw mean "I want SIXEL here"; PreFlush turns that into actual DCS emission while resolving z-order against any covering view (see SixelCanvasView.PreFlush for the full mechanics — same algorithm).

Three pieces of stdout get emitted, in order, every frame the imageview is at least partially visible:

  1. A BG fill (truecolor SGR + spaces) over every uncovered cell. This claims the cell content as iv.BG so the desktop's wallpaper pattern doesn't keep showing through wherever SIXEL pixels don't reach (cell-size mismatch, or letterbox padding inside the SIXEL itself).
  2. The SIXEL DCS, painted on top of the BG fill.
  3. (Implicit, in the cell flush) covering cells that were Invalidated below — they paint on top of the SIXEL pixels so overlapping windows survive the SIXEL repaint.

func (*ImageView) SetImage

func (iv *ImageView) SetImage(img image.Image)

SetImage attaches img and resets pan/zoom and the encoded cache.

Jump to

Keyboard shortcuts

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