thumbnail

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Aug 6, 2026 License: BSD-3-Clause Imports: 20 Imported by: 0

README

thumbnail

CI Go Reference Go Report Card coverage

A pure-Go (CGO_ENABLED=0) implementation of the freedesktop.org Thumbnail Managing Standard.

It generates and caches file thumbnails exactly where and how the standard prescribes, so thumbnails written by this library are visible to other compliant tools (file managers, image viewers) and vice versa.

What it does

  • Canonical cache layout — thumbnails live under $XDG_CACHE_HOME/thumbnails/{normal,large,x-large,xx-large}, the 128 / 256 / 512 / 1024-pixel buckets. $XDG_CACHE_HOME is resolved with github.com/adrg/xdg.
  • MD5 naming — a thumbnail's filename is the MD5 hex digest of the canonical file:// URI of its source, plus .png.
  • Mandated PNG metadata — every thumbnail carries tEXt chunks Thumb::URI and Thumb::MTime (and optional Thumb::Size, Thumb::Mimetype, Software).
  • Validation & invalidation — a cached thumbnail is served only while its stored Thumb::MTime matches the source file's current mtime; otherwise it is transparently regenerated.
  • Fail records — sources that cannot be thumbnailed are recorded under thumbnails/fail/<appname>/ and are not retried until the source changes.
  • Fleet resizer — scaling dog-foods github.com/go-images/images (SIMD bilinear) by default, with golang.org/x/image/draw (Catmull-Rom) available as a higher-quality fallback filter. Aspect ratio is always preserved and sources are never upscaled.
  • Provider seam — a Provider interface decouples "decode a source into an image" from the caching machinery, so non-file sources can be plugged in. A live-framebuffer provider resizes an in-memory image.Image directly (bypassing the disk cache) for a compositor's live window / exposé thumbnails.

Install

go get github.com/go-thumbnail/thumbnail

Quickstart

package main

import (
	"fmt"

	"github.com/go-thumbnail/thumbnail"
)

func main() {
	// Package-level helpers use a default normal-size (128px) cache.
	path, err := thumbnail.Get("/home/jens/photo/me.png")
	if err != nil {
		panic(err)
	}
	fmt.Println("cached thumbnail at", path)

	// A configured cache: 256px bucket, custom fail-dir app name.
	c := thumbnail.New(thumbnail.Large, thumbnail.WithAppName("myapp"))
	img, err := c.GetImage("/home/jens/photo/me.png")
	if err != nil {
		panic(err)
	}
	fmt.Println("thumbnail bounds:", img.Bounds())
}
Live framebuffer (compositor window / exposé thumbnails)
c := thumbnail.New(thumbnail.Normal)

// src is an image.Image you already hold — a window's framebuffer, say.
// Live resizes into the bucket and never touches the on-disk cache.
scaled, err := c.Live(src)

API

Symbol Purpose
Get(uri) (string, error) Path to the cached (normal) thumbnail, generating if missing/stale.
GetImage(uri) (image.Image, error) The thumbnail image itself.
New(size, ...Option) *Cache A cache bound to a size bucket.
Cache.Get / GetImage / Path Cached thumbnail path / image / would-be path.
Cache.Live(image.Image) Resize an in-memory image into the bucket, no disk I/O.
Provider Thumbnail(src string) (image.Image, error) — pluggable source decoder.
FileProvider, FramebufferProvider The default file decoder and the live-framebuffer seam.
Size Normal, Large, XLarge, XXLarge.
Filter Bilinear (go-images), CatmullRom (x/image/draw).

Options: WithRoot, WithFilter, WithAppName, WithProvider, WithSoftware, WithMaxBytes.

Scope

This library implements the Thumbnail Managing Standard — the cache layout, naming, metadata, validation and fail-record rules, plus a resize pipeline over the standard-library image decoders (PNG, JPEG, GIF). It does not implement the companion thumbnailer D-Bus service or .thumbnailer provider discovery; non-image sources are handled by supplying your own Provider.

Tests

100% statement coverage (including every error branch), verified in CI along with go vet and a nine-target cross-build (linux amd64/arm64/riscv64/ppc64le/ s390x/loong64, darwin amd64/arm64, windows amd64).

go test -covermode=set -coverprofile=cover.out ./...
go tool cover -func=cover.out

License

BSD-3-Clause — see LICENSE.

Documentation

Overview

Package thumbnail is a pure-Go (CGO_ENABLED=0) implementation of the freedesktop.org Thumbnail Managing Standard.

It stores thumbnails under $XDG_CACHE_HOME/thumbnails in the four canonical size buckets — normal (128px), large (256px), x-large (512px) and xx-large (1024px). Each thumbnail is a PNG whose filename is the MD5 hex digest of the canonical file:// URI of the source, and which carries the mandated tEXt metadata chunks Thumb::URI and Thumb::MTime (plus optional Thumb::Size, Thumb::Mimetype and Software). A cached thumbnail is valid only while its recorded Thumb::MTime matches the source file's current modification time; otherwise it is regenerated. Sources that cannot be thumbnailed are recorded under thumbnails/fail/<appname>/ so they are not retried until they change.

The scaling engine dog-foods the fleet's github.com/go-images/images resizer (SIMD bilinear) by default and falls back to golang.org/x/image/draw (Catmull-Rom) when a higher-quality filter is requested.

A Provider seam decouples "decode a source into an image" from the caching machinery so that non-file sources can be plugged in. Two providers ship: the default file-decoding provider, and a live-framebuffer provider that resizes an in-memory image.Image directly, bypassing the on-disk cache — intended for a compositor's live window / exposé thumbnails.

Index

Constants

View Source
const (
	KeyURI      = "Thumb::URI"      // canonical source URI (mandatory)
	KeyMTime    = "Thumb::MTime"    // source mtime, decimal seconds (mandatory)
	KeySize     = "Thumb::Size"     // source size in bytes (optional)
	KeyMimetype = "Thumb::Mimetype" // source MIME type (optional)
	KeySoftware = "Software"        // generating software (optional)
)

Standard tEXt keywords defined (or recommended) by the Thumbnail Managing Standard.

Variables

View Source
var ErrFailed = errors.New("thumbnail: source previously failed to thumbnail")

ErrFailed is wrapped by the error returned from Get/GetImage when the source is recorded in the fail directory for the current mtime, meaning a previous attempt failed and the source has not changed since.

Functions

func FileURI

func FileURI(path string) string

FileURI returns the canonical file:// URI for a local filesystem path, as required by the Thumbnail Managing Standard for hash computation. The path is made absolute and each path segment is percent-encoded. A path that already carries a URI scheme (e.g. "file://…" or "http://…") is returned unchanged.

func Get

func Get(uri string) (string, error)

Get returns the path to the cached normal-size thumbnail for uri, using a default cache rooted at $XDG_CACHE_HOME/thumbnails. It generates and caches the thumbnail if absent or stale.

func GetImage

func GetImage(uri string) (image.Image, error)

GetImage returns the normal-size thumbnail image for uri, using a default cache rooted at $XDG_CACHE_HOME/thumbnails.

func Hash

func Hash(uri string) string

Hash returns the lowercase MD5 hex digest of a URI: the basename (without the ".png" extension) of the thumbnail file for that URI.

Types

type Cache

type Cache struct {
	// Root is the base thumbnails directory (default $XDG_CACHE_HOME/thumbnails).
	Root string
	// Size is the size bucket this cache serves.
	Size Size
	// Filter selects the scaling kernel (default Bilinear via go-images).
	Filter Filter
	// AppName names the fail subdirectory (thumbnails/fail/<AppName>).
	AppName string
	// Provider decodes sources into images (default FileProvider).
	Provider Provider
	// Software is written to the Software tEXt chunk; empty omits it.
	Software string
	// MaxBytes bounds the default provider's source file size.
	MaxBytes int64
}

Cache is a thumbnail cache bound to a single size bucket. Construct it with New. The exported fields may be read for introspection; mutate them only before first use.

func New

func New(size Size, opts ...Option) *Cache

New returns a Cache for the given size bucket with the supplied options applied. Unset options take fleet-standard defaults.

func (*Cache) Get

func (c *Cache) Get(uri string) (string, error)

Get returns the path to the cached thumbnail for uri, generating and caching it if absent or stale. uri may be a filesystem path or a file:// URI.

func (*Cache) GetImage

func (c *Cache) GetImage(uri string) (image.Image, error)

GetImage returns the thumbnail image for uri, generating and caching it if absent or stale.

func (*Cache) Live

func (c *Cache) Live(img image.Image) (*image.RGBA, error)

Live resizes an in-memory image into this cache's size bucket without touching the on-disk cache. It is the live-framebuffer entry point used for a compositor's window and exposé thumbnails.

func (*Cache) Path

func (c *Cache) Path(uri string) string

Path returns the on-disk path where the thumbnail for uri would live, whether or not it currently exists. uri may be a filesystem path or a URI.

type FileProvider

type FileProvider struct {
	MaxBytes int64
}

FileProvider is the default Provider: it decodes an image file at the given path using the standard library's registered decoders (PNG, JPEG, GIF). If MaxBytes is positive, sources whose on-disk size exceeds MaxBytes are rejected before decoding to bound resource use.

func (FileProvider) Thumbnail

func (p FileProvider) Thumbnail(path string) (image.Image, error)

Thumbnail reads and decodes the image file at path.

type Filter

type Filter int

Filter selects the scaling kernel used to fit a source image into a bucket.

const (
	// Bilinear scales with the fleet's github.com/go-images/images SIMD bilinear
	// resizer. It is the default.
	Bilinear Filter = iota
	// CatmullRom scales with golang.org/x/image/draw's Catmull-Rom kernel, a
	// higher-quality filter used as the fallback when go-images lacks it.
	CatmullRom
)

type FramebufferProvider

type FramebufferProvider struct {
	// Img is the live source image. A nil Img yields an error.
	Img image.Image
}

FramebufferProvider is a live-framebuffer Provider seam for callers such as a compositor that already hold an image in memory (a window's framebuffer, an exposé snapshot). Src is ignored; the stored image is returned directly. Used with Cache.Live, it resizes without ever touching the on-disk cache.

func (FramebufferProvider) Thumbnail

func (p FramebufferProvider) Thumbnail(_ string) (image.Image, error)

Thumbnail returns the stored framebuffer image, ignoring src.

type Option

type Option func(*Cache)

Option configures a Cache in New.

func WithAppName

func WithAppName(name string) Option

WithAppName sets the fail-directory application name.

func WithFilter

func WithFilter(f Filter) Option

WithFilter sets the scaling filter.

func WithMaxBytes

func WithMaxBytes(n int64) Option

WithMaxBytes bounds the default provider's source file size (0 disables it).

func WithProvider

func WithProvider(p Provider) Option

WithProvider sets a custom source Provider.

func WithRoot

func WithRoot(root string) Option

WithRoot overrides the base thumbnails directory.

func WithSoftware

func WithSoftware(s string) Option

WithSoftware sets the Software tEXt value (empty string omits the chunk).

type Provider

type Provider interface {
	Thumbnail(src string) (image.Image, error)
}

Provider decodes or synthesizes the full-resolution source image identified by src. The default file provider treats src as a filesystem path; other providers may interpret it however they wish. A Provider must never panic on malformed input — it returns an error instead — but the cache also guards against panics defensively.

type Size

type Size int

Size selects one of the four canonical thumbnail size buckets defined by the Thumbnail Managing Standard. The zero value is Normal.

const (
	// Normal thumbnails fit within a 128x128 pixel box.
	Normal Size = iota
	// Large thumbnails fit within a 256x256 pixel box.
	Large
	// XLarge thumbnails fit within a 512x512 pixel box.
	XLarge
	// XXLarge thumbnails fit within a 1024x1024 pixel box.
	XXLarge
)

func (Size) Dir

func (s Size) Dir() string

Dir returns the on-disk directory name of the size bucket, as mandated by the standard (normal, large, x-large, xx-large).

func (Size) Pixels

func (s Size) Pixels() int

Pixels returns the maximum edge length, in pixels, of the size bucket.

func (Size) Valid

func (s Size) Valid() bool

Valid reports whether s names one of the four canonical buckets.

Jump to

Keyboard shortcuts

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