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 New ¶
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.