imagefield

package
v0.51.0 Latest Latest
Warning

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

Go to latest
Published: Jul 28, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package imagefield connects the image pipeline to the upload path: it turns a framework/image.VariantSet into the file.ImageDeriver that ProcessFileField and the CRUD upload handler call, so declaring a schema.Image field is what makes uploads produce renditions and a BlurHash — no per-entity upload handler.

It is a separate package on purpose. framework/file is a leaf that framework/crud imports, so an edge from there to framework/image would link every image decoder plus the WebP encoder into every application with a CRUD handler. Keeping the adapter here means only applications that actually want the pipeline pay for it.

Typical wiring — one option on the app:

framework.NewApp(
    framework.WithFileStorage(store),
    framework.WithImagePipeline(imagefield.MustNew(imagefield.Config{
        Variants: []image.Variant{
            {Width: 480, Format: image.FormatWebP, Suffix: "sm"},
            {Width: 960, Format: image.FormatWebP, Suffix: "md"},
            {Width: 480, Format: image.FormatJPEG, Quality: 82, Suffix: "sm"},
            {Width: 960, Format: image.FormatJPEG, Quality: 82, Suffix: "md"},
        },
        BlurHashX: 4, BlurHashY: 3,
    })),
)

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	// Variants are the renditions to produce and store. Each entry's
	// Suffix (or width, when Suffix is empty) distinguishes its storage
	// key from the original's.
	Variants []fwimage.Variant

	// BlurHashX and BlurHashY are the BlurHash component counts (1..9).
	// Both zero means no BlurHash; setting only one is an error. 4x3 suits
	// landscape images, 3x4 portrait.
	BlurHashX int
	BlurHashY int

	// Placeholder, when non-nil, also stores an LQIP data URL. Redundant
	// alongside a BlurHash for most callers — a BlurHash costs ~28 bytes
	// in the column against a few hundred, and framework/image renders
	// either one the same way.
	Placeholder *fwimage.PlaceholderOptions

	// RejectAnimated fails the upload when the source has more than one
	// frame instead of silently flattening to the first. Worth setting on
	// avatar and profile-photo fields, where a surprise still frame is
	// worse than a rejection the user can act on.
	RejectAnimated bool

	// AllowUpscale opts back in to renditions wider than the source. The
	// default clamps each rendition to the source width, so a small upload
	// does not fan out into pixel-multiplied storage waste.
	AllowUpscale bool

	// MaxPixels overrides the decompression-bomb guard for this pipeline
	// (default framework/image.DefaultMaxPixels, 64 MP).
	MaxPixels int64
}

Config declares what to derive from each uploaded image. The zero value derives nothing and New rejects it — an image pipeline that produces no renditions, no hash, and no placeholder is a configuration mistake, not a no-op worth honouring silently.

type Deriver

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

Deriver implements file.ImageDeriver over a VariantSet.

func MustNew

func MustNew(cfg Config) *Deriver

MustNew is New for package-level wiring, panicking on a bad config.

func New

func New(cfg Config) (*Deriver, error)

New builds a Deriver from cfg. It returns an error for a configuration that could not produce anything, or that framework/image would reject at process time anyway — better at wiring time than on the first upload.

func (*Deriver) DeriveImage

func (d *Deriver) DeriveImage(ctx context.Context, store upload.Storage, data []byte, primaryRef string) (*file.ImageDerivatives, error)

DeriveImage decodes the upload, produces every configured rendition, stores them beside the original, and returns their references plus the placeholder metadata.

Renditions stream one at a time through VariantSet.ProcessTo, so peak memory stays near a single rendition rather than all of them summed — this runs inside a request, on bytes a client chose.

Jump to

Keyboard shortcuts

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