Documentation
¶
Overview ¶
Package imaging turns one image into resized copies, safely: pure Go (no cgo, no external library), the pixel count checked from the header before anything is decoded, the orientation flag applied, a time limit per image, and output that never carries metadata.
It reads JPEG, PNG, GIF (the first frame) and WebP, and writes JPEG and PNG. WebP output is not offered: the pure-Go encoders are lossless only, and a lossless WebP of a photograph is about eight times the size of the JPEG.
An Engine decodes an image once and renders every version asked of it.
Index ¶
- Constants
- Variables
- func ContainerLimits() (cpus float64, memory int64)
- func DeriveConcurrency(cpus float64, memory, maxPixels int64) int
- func ReasonOf(err error) string
- func Strip(dst io.Writer, src io.Reader, format string) error
- type Engine
- type Error
- type Fit
- type Format
- type Info
- type Limits
- type Outcome
- type Params
- type Result
Constants ¶
const ( ReasonNotAnImage = "not_an_image" ReasonUnsupportedFormat = "unsupported_format" ReasonTooLarge = "too_large" ReasonDecodeError = "decode_error" ReasonTimeout = "timeout" ReasonInvalidParameters = "invalid_parameters" )
Reasons an image could not be made, as the version statuses will name them.
const DefaultMaxPixels int64 = 40_000_000
DefaultMaxPixels is the pixel limit when none is set.
const DefaultQuality = 82
DefaultQuality is the JPEG quality when none is given.
Variables ¶
var ErrUnreadable = errors.New("imaging: the image can't be read to remove its metadata")
ErrUnreadable means the data is not an image of the format that can be copied: a damaged file. Strip fails closed on it rather than pass the metadata through.
Functions ¶
func ContainerLimits ¶
ContainerLimits reads the CPU and memory limits of the container the process runs in (cgroup v2, then v1): zero where there is no limit.
func DeriveConcurrency ¶
DeriveConcurrency is how many images a worker can process at once: half the CPUs, and no more than fit in half the memory when each takes four bytes per pixel of the largest image allowed; at least one. cpus <= 0 means the host's; memory <= 0 means unknown, which leaves only the CPUs to count.
func Strip ¶
Strip copies the JPEG or PNG in src to dst without its metadata, as described above. format is "jpeg" or "png" (Info.Format); any other is an error. Data after the end of a JPEG (an embedded second image, a trailer) is dropped. dst gets the stream as it goes; on an error what was written is incomplete.
Types ¶
type Engine ¶
type Engine struct {
// contains filtered or unexported fields
}
Engine makes the versions of images, at most Limits.Concurrency at a time.
func (*Engine) Limits ¶
Limits returns the limits the Engine works within, with the defaults filled in.
func (*Engine) Process ¶
func (e *Engine) Process(ctx context.Context, src io.ReadSeeker, maxPixels int64, versions []Params) ([]Outcome, error)
Process reads one image and makes a version for each of the parameter sets, in order, decoding the image once. maxPixels, when above zero, lowers the Engine's pixel limit for this image (a field may only lower the operator's limit).
The error is for the image itself (not an image, too large, damaged, timed out); each version has its own Outcome. Parameters that don't validate are an error before anything is read.
type Error ¶
Error is why an image could not be read or made; Reason is one of the Reason constants.
type Fit ¶
type Fit string
Fit says how an image is placed in the box of max_width × max_height.
const ( // Contain fits the image inside the box, keeping its proportions. The default. Contain Fit = "contain" // Cover fills the box, keeping the proportions and cropping the excess, // centered. Needs both dimensions; with one it behaves as Contain. Cover Fit = "cover" // Stretch fills the box, ignoring the proportions. A missing dimension stays as it is. Stretch Fit = "stretch" )
type Info ¶
type Info struct {
Format string // jpeg, png, gif or webp
Width int
Height int
Orientation int // EXIF orientation, 1 to 8 (1: as stored)
}
Info is what an image's header says, read without decoding it.
func Inspect ¶
func Inspect(r io.ReadSeeker) (Info, error)
Inspect reads the image's format, dimensions and orientation from its header, without decoding it. It fails with ReasonNotAnImage for content that isn't an image, ReasonUnsupportedFormat for an image format it doesn't read (BMP, TIFF, HEIC, AVIF, SVG, …) and ReasonDecodeError for a damaged header. The reader is left at the start.
type Limits ¶
type Limits struct {
// MaxPixels is the most pixels an image may have (width × height), checked
// from the header before decoding. Zero means DefaultMaxPixels.
MaxPixels int64
// Timeout bounds the whole of one image: decoding and every version. Zero
// means 30 seconds.
Timeout time.Duration
// Concurrency is how many images one Engine processes at the same time.
// Zero or less means 1.
Concurrency int
}
Limits bound the work done for one image.
type Params ¶
type Params struct {
MaxWidth int // box width in pixels; zero is unbounded
MaxHeight int // box height in pixels; zero is unbounded
Fit Fit // default Contain
Quality int // 1 to 100, for JPEG; default DefaultQuality
Format Format // default: the source's family (jpeg stays jpeg, png and gif become png, webp becomes jpeg unless it has transparency)
Upscale bool // enlarge images smaller than the box; default no
}
Params describe one version, with the names of collection.yaml.