pix

package module
v0.0.0-...-52594cd Latest Latest
Warning

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

Go to latest
Published: Feb 9, 2026 License: BSD-3-Clause Imports: 7 Imported by: 0

README

pix

go.dev reference Go Report Card codecov Go sourcegraph

Low-level pixel buffer manipulation for Go. Designed for RAW photo editing, AI image preprocessing, and embedded display drivers.

Credit to Amken3D GPU approach to filtering.

Features

  • Multiple pixel formats: RGB888, RGBA8888, RGB565BE, RGB555, RGB444BE, Grayscale, Monochrome
  • Streaming I/O or Buffered: Images implement io.ReaderAt — process from disk/network without loading everything into memory
  • ROI support: Process only a region of interest
  • Filter pipeline: Composable filters with in-place operation support
  • Embedded-friendly: Supports display formats like ST7789 (RGB565BE)

Module structure

  • pix.go - Contains top level interface abstractions.
  • controls.go - Control type and implementations.
  • filters - Directory containing image filter implementations.
    • filters/point-filter.go - Most basic CPU filter implementation- pixel-by-pixel image transformation. grayscale.go and invert.go use this filter base
    • filters/point-filter-gpu.go - GPU-accelerated filter base using WebGPU compute shaders. grayscale_gpu.go and invert_gpu.go use this base

Examples

CPU Filters
import (
	"image"

	"github.com/soypat/pix/filters"
)

// Create a grayscale filter with luminance-weighted conversion.
filter := filters.NewGrayscalePerPixel(filters.GrayscaleLuminance)

// Process full image.
outDims, err := filter.Process(dstBuf, srcImage, nil)

// Or process only a region of interest.
roi := image.Rect(100, 100, 200, 200)
outDims, err = filter.Process(dstBuf, srcImage, &roi)
GPU Filters (WebGPU)
import (
	"github.com/cogentcore/webgpu/wgpu"
	"github.com/soypat/pix/filters"
)

// Initialize WebGPU
instance := wgpu.CreateInstance(nil)
adapter, _ := instance.RequestAdapter(&wgpu.RequestAdapterOptions{
	PowerPreference: wgpu.PowerPreferenceLowPower,
})
device, _ := adapter.RequestDevice(nil)
queue := device.GetQueue()

// Create GPU-accelerated grayscale filter
filter, err := filters.NewGrayscaleGPU(device, queue, filters.GrayscaleLuminance)
defer filter.Cleanup()

// Process image.RGBA directly
result, err := filter.Process(inputRGBA)

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ImageRow

func ImageRow(dst []byte, img Image, row int) (resultSized []byte, err error)

Types

type Control

type Control interface {
	// Display/human readable name and description.
	Describe() (name, description string)
	// ActualValue returns the current value of the control.
	ActualValue() any
	// ChangeValue attempts to update the ActualValue to newValue.
	ChangeValue(newValue any) error
}

Control represents an editable parameter of a filter. When Value is modified via OnChange, the filter updates its output immediately.

type ControlCurve

type ControlCurve struct {
	Name        string
	Description string
	Points      []CurvePoint // Control points, X/Y in 0-1 range.
	OnChange    func([]CurvePoint) error
}

ControlCurve is a spline curve control with editable control points. Points are in normalized 0-1 range for both X (input) and Y (output).

func (*ControlCurve) ActualValue

func (cc *ControlCurve) ActualValue() any

func (*ControlCurve) ChangeValue

func (cc *ControlCurve) ChangeValue(newValue any) error

func (*ControlCurve) Describe

func (cc *ControlCurve) Describe() (name, description string)

type ControlEnum

type ControlEnum[T enum] struct {
	Name        string
	Description string
	Value       T
	ValidValues []T
	OnChange    func(T) error
}

ControlEnum maps to dropdown kind of list.

func (*ControlEnum[T]) ActualValue

func (ce *ControlEnum[T]) ActualValue() any

func (*ControlEnum[T]) ChangeValue

func (ce *ControlEnum[T]) ChangeValue(newValue any) error

func (*ControlEnum[T]) Describe

func (ce *ControlEnum[T]) Describe() (name, description string)

type ControlOrdered

type ControlOrdered[T cmp.Ordered] struct {
	Name        string
	Description string
	Value       T
	Min         T
	Max         T
	Step        T
	OnChange    func(T) error
}

func (*ControlOrdered[T]) ActualValue

func (co *ControlOrdered[T]) ActualValue() any

func (*ControlOrdered[T]) ChangeValue

func (co *ControlOrdered[T]) ChangeValue(newValue any) error

func (*ControlOrdered[T]) Describe

func (co *ControlOrdered[T]) Describe() (name, description string)

type CurvePoint

type CurvePoint = ms2.Vec

CurvePoint is a control point for curve-type controls. X represents input (0-1), Y represents output (0-1).

type Dims

type Dims struct {
	Width  int
	Height int
	Stride int
	Shape  Shape
}

func ValidateProcessArgs

func ValidateProcessArgs(dst []byte, dstShape Dims, src Image, roi *image.Rectangle) (_ []byte, srcDims Dims, err error)

ValidateProcessArgs gets correct write destination buffer and provides basic guarantees of inputs to Filter such as:

  • Source Dims.Validate early validation. Always returned as called.
  • Valid ROI argument.
  • Valid input image for buffered in-place operations. In-place rejects non-nil ROI.
  • shape match for in-place operations.
  • For users who know the output stride and height offers checking of dst buffer size. Use dstDims.Stride=0 to omit this check.

dstDims.Shape must be set to support in-place operations. Other fields are optional but provide buffer size checks. srcDims is always returned as called by src.Dims.

func (Dims) NumPixels

func (d Dims) NumPixels() int64

func (Dims) Size

func (d Dims) Size() int64

Size returns the readable section size of raw image in bytes.

func (Dims) SizeRow

func (d Dims) SizeRow() int

func (Dims) Validate

func (d Dims) Validate() error

type Filter

type Filter interface {
	// ShapeIO returns expected output and input [pixel.Shape] of the filter.
	// output shape MUST match Process [Dims.Shape] output.
	ShapeIO() (output, input Shape)
	// Process processes an input image and writes the result to
	// destination buffer and returns the dimensions of the resulting image.
	//
	// If destination buffer is nil Filter will assert [ImageBuffered.Buffer] non-nilness
	// and use the buffer as the destination data. In-place does not support ROI.
	// Use [ValidateProcessArgs] to acquire dst buffer and validate arguments.
	//
	// For sub-byte ROI alignment filter must implement bit-level extraction.
	Process(dstOrNilForInPlace []byte, src Image, roi *image.Rectangle) (Dims, error)
	// Controls returns the actual controls of the filter.
	// Controls should remain valid even after calling [Control.ChangeValue]
	// and their [Control.ActualValue] return the updated value.
	Controls() []Control
}

Filter is a extremely flexible low-level filter implementation.

Binary/Ternary... operations such as blend, composite and difference may be implemented by having the filter store the additional images before calling process on a target image.

type Image

type Image interface {
	// Dims returns information on in-memory image structure.
	// Row spacing must be homogenous in entire image separated by stride bytes.
	Dims() Dims
	// ReadAt reads from the image buffer of pixels, which may be in-memory or elsewhere (disk, network).
	//
	// Users should always try casting [Image] to [ImageBuffered]
	// to see if they can work with the image in-memory which is more efficient.
	io.ReaderAt
}

Image is a low-level, whole-buffer image access abstraction of raw memory. It does not do bounds abstraction. As made implicit by Dims signature, row spacing must be homogenous in images.

type ImageBuffered

type ImageBuffered interface {
	Image
	// Buffer returns the raw underlying buffer for images stored in memory.
	// Buffer returns the entire buffer or nil to signal buffer is currently not in memory.
	//
	// Application note: A Load method is not included because
	// if the user wishes for Buffered to be used then the user
	// should worry about loading the buffer early or adding logic to their
	// ImageBuffered implementation so it loads on this Buffer call.
	// Users will decide which works best for their use case.
	Buffer() []byte
}

type Shape

type Shape int
const (
	ShapeRGB888        Shape // rgb888
	ShapeRGBA8888            // rgba8888
	ShapeRGB565BE            // rgb565be
	ShapeRGB555              // rgb555
	ShapeRGB444BE            // rgb444be
	ShapeGrayscale2bit       // gray2
	ShapeMonochrome          // monochrome
)

func (Shape) BitsPerPixel

func (sh Shape) BitsPerPixel() (bits int)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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