Documentation
¶
Overview ¶
Package transformations holds the twelve things that can be asked of an image, as twelve types.
Each is a record and nothing else: plain exported fields, with no behaviour of their own. What they mean is decided by the driver that executes them, and the driver in the image package is the one that decides it here.
They live in their own package for one reason: the image package builds them, so if Transformation lived there, this package could not name it and the import would be a cycle.
A caller rarely names these types directly. The image package's Image type has a method for each -- Cover, Blur, Orient -- and they are the way in; what these are for is Image.Transform, and the custom transformation that a driver was taught to handle with ImageManager.TransformUsing.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Blur ¶
type Blur struct {
// Amount is 0 to 100. Image.Blur clamps a caller's value to that range
// before building this transformation.
Amount int
}
Blur softens the whole canvas: every pixel is averaged with the ones around it, so noise and fine detail go and the broad shapes stay. There is no way to blur part of an image -- crop first if that is what you want.
Amount is a strength, not a distance in pixels, and the driver decides how far it reaches. Zero is a no-op: the canvas comes out of the pipeline untouched rather than rejected.
func (Blur) TransformationName ¶
TransformationName returns "Blur".
type Contain ¶
type Contain struct {
Width int
Height int
// Background is a CSS-style hex colour ("#ffffff", "fff", "ffffffff") or
// the sentinel "dominant", which expands to the image's own dominant
// colour. Empty means opaque white.
Background string
}
Contain scales the whole image to fit inside the box, padded with Background to exactly Width by Height.
func (Contain) TransformationName ¶
TransformationName returns "Contain".
type Cover ¶
Cover fills the box edge to edge, aspect ratio kept, whatever overflows cropped from the centre.
func (Cover) TransformationName ¶
TransformationName returns "Cover".
type Crop ¶
Crop cuts a rectangle out of the image and throws the rest away. Nothing is scaled: the result is Width by Height at the original resolution, taken from the source starting at X, Y, which are counted from the top left corner.
The rectangle is not required to fit inside the source. Whatever part of it hangs over an edge has no pixels to take, and that part of the result stays transparent.
func (Crop) TransformationName ¶
TransformationName returns "Crop".
type FlipHorizontally ¶
type FlipHorizontally struct{}
FlipHorizontally mirrors the image across its vertical centre line: the leftmost column of pixels becomes the rightmost. The dimensions do not change, no pixel is interpolated, and applying it twice gives the original back.
func (FlipHorizontally) TransformationName ¶
func (FlipHorizontally) TransformationName() string
TransformationName returns "FlipHorizontally".
type FlipVertically ¶
type FlipVertically struct{}
FlipVertically flips the image top to bottom.
func (FlipVertically) TransformationName ¶
func (FlipVertically) TransformationName() string
TransformationName returns "FlipVertically".
type Grayscale ¶
type Grayscale struct{}
Grayscale drops the colour and keeps the brightness: every pixel becomes the grey of its own luminance. Transparency survives untouched, and the image stays in a colour format -- this makes the picture grey, it does not make the file smaller by storing one channel instead of three.
It is not reversible. The colour is gone from the pipeline's output, so an image needed in both forms has to be derived twice from the original.
func (Grayscale) TransformationName ¶
TransformationName returns "Grayscale".
type Orient ¶
type Orient struct{}
Orient reads the EXIF orientation tag and applies it, so a photograph taken with the phone on its side is stored the way it was seen.
func (Orient) TransformationName ¶
TransformationName returns "Orient".
type Resize ¶
type Resize struct {
// Width zero leaves that axis as it is, and the other one moves alone.
// Image.Resize refuses the call where both are absent.
Width int
// Height zero leaves that axis as it is.
Height int
}
Resize sets the image to exactly Width by Height; the aspect ratio is not kept.
func (Resize) TransformationName ¶
TransformationName returns "Resize".
type Rotate ¶
type Rotate struct {
// Angle is degrees clockwise.
Angle float64
// Background fills the corners the rotation leaves empty. Same spelling as
// [Contain.Background], including the "dominant" sentinel; empty means
// transparent.
Background string
}
Rotate turns the image around its centre. The canvas grows to the bounding box of the turned rectangle, so no corner is cut off -- a square rotated by 45 degrees comes back wider and taller than it went in, and only a multiple of 90 degrees keeps the dimensions (swapped, for the odd multiples).
The turn opens up triangles of empty canvas at the corners, and Background is what goes in them. A right angle is a straight copy of the pixels; any other angle samples between them, so repeated rotation of the same image softens it.
func (Rotate) TransformationName ¶
TransformationName returns "Rotate".
type Scale ¶
type Scale struct {
// Width zero means that axis does not constrain the result.
Width int
// Height zero means that axis does not constrain the result.
Height int
}
Scale fits the image inside the box, aspect ratio kept, and never scales up.
Never scaling up is the whole difference from Resize.
func (Scale) TransformationName ¶
TransformationName returns "Scale".
type Sharpen ¶
type Sharpen struct {
// Amount ranges from 0 to 100.
Amount int
}
Sharpen makes edges read as crisper by pushing the contrast up where the image already changes fast. It adds no detail that was not there: what it works on is the difference between the image and a softened copy of itself, so it recovers the look of definition a resize cost and nothing more.
Amount is how much of that difference is added back, and a high value shows as a bright halo tracing every edge. Zero is a no-op.
func (Sharpen) TransformationName ¶
TransformationName returns "Sharpen".
type Transformation ¶
type Transformation interface {
// TransformationName is the string that names this transformation, such
// as "Blur", "Cover", or "Crop".
TransformationName() string
}
Transformation is the interface every transformation type implements.
An empty interface in Go is `any`, which every type satisfies, so a marker interface needs at least one method -- and the method it got is the one the driver needs anyway.
TransformationName is the key a per-driver handler is registered under with ImageManager.TransformUsing, and the tag the driver switches on:
manager.TransformUsing("std", "Blur", handler)
A type outside this package may implement it, and that is how a custom transformation reaches a driver that was taught to handle it. A driver that meets a name it does not know returns an error rather than dropping the transformation on the floor -- a resize that silently did not happen is worse than one that failed.