pub struct Image { /* private fields */ }Expand description
A lazily evaluated image pipeline.
Cheap to clone: clones share graph nodes rather than pixels. Chaining builds graph structure and executes nothing (SPEC §Guarantees 3).
Implementations§
Source§impl Image
impl Image
Sourcepub fn from_raw(descriptor: ImageDescriptor, bytes: Vec<u8>) -> Result<Self>
pub fn from_raw(descriptor: ImageDescriptor, bytes: Vec<u8>) -> Result<Self>
Build an image from raw pixels already in memory.
bytes must be exactly the packed byte length of descriptor.
§Errors
Returns PixelsError::InvalidArgument if bytes is not exactly the
packed length descriptor implies.
Sourcepub fn from_raw_stream(
layout: RawFormat,
source: impl Source + Debug + 'static,
) -> Result<Self>
pub fn from_raw_stream( layout: RawFormat, source: impl Source + Debug + 'static, ) -> Result<Self>
Build an image by decoding a raw pixel stream.
The header parse is trivial for raw — the layout is the header — so
this reads no bytes from source. Pixels are pulled at the terminal.
§Errors
Returns PixelsError::InvalidArgument if the layout is not
representable on this platform.
Sourcepub fn open(path: impl AsRef<Path>) -> Result<Self>
pub fn open(path: impl AsRef<Path>) -> Result<Self>
Open an image file, identifying its format from its contents, with
default OpenOptions — so it is turned upright.
The path’s extension is ignored. Detection is by magic bytes only (SPEC §Formats), because a name is an attacker-controlled hint while the bytes are a fact.
§Errors
Returns PixelsError::Io if the file cannot be opened,
PixelsError::Unsupported if no built-in codec recognises it, and
PixelsError::Malformed if the header is invalid for the format its
magic bytes claim.
Sourcepub fn from_stream(source: impl Source + Debug + 'static) -> Result<Self>
pub fn from_stream(source: impl Source + Debug + 'static) -> Result<Self>
Build an image from a byte stream, identifying its format from the leading bytes.
Sniffing reads only the longest magic prefix any known codec needs, and
replays it to the decoder rather than seeking — a Source is
forward-only (ADR-0005), so a pipe or socket works here exactly as a
file does. A stream shorter than that prefix is not an error at this
stage: it simply matches nothing.
§Errors
Returns PixelsError::Unsupported if no built-in codec recognises
the stream, PixelsError::Io on read failure, or
PixelsError::Malformed if the header is invalid for the format its
magic bytes claim.
Sourcepub fn from_stream_with(
source: impl Source + Debug + 'static,
options: OpenOptions,
) -> Result<Self>
pub fn from_stream_with( source: impl Source + Debug + 'static, options: OpenOptions, ) -> Result<Self>
Sourcepub fn from_decoder(decoder: Box<dyn Decoder>, format: Format) -> Self
pub fn from_decoder(decoder: Box<dyn Decoder>, format: Format) -> Self
Build an image from any decoder whose header has already been parsed.
This is the extension point for codecs living outside this crate.
Pixels arrive as stored: Decoder::orientation is not applied here,
so pass it to Image::orient to turn the result upright.
Sourcepub fn from_producer(producer: Arc<dyn Producer>, format: Format) -> Self
pub fn from_producer(producer: Arc<dyn Producer>, format: Format) -> Self
Build an image from any pixel producer.
Sourcepub fn metadata(&self) -> Result<Metadata>
pub fn metadata(&self) -> Result<Metadata>
Header-only facts about this image: dimensions, format, pixel format.
Free — descriptors are resolved as the graph is built, so this decodes nothing (SPEC §Guarantees 3).
§Errors
Returns the first error captured while building the pipeline, if any.
Sourcepub fn descriptor(&self) -> Result<ImageDescriptor>
pub fn descriptor(&self) -> Result<ImageDescriptor>
The shape of this image at this point in the pipeline.
§Errors
Returns the first error captured while building the pipeline, if any.
Sourcepub fn crop(self, x: u32, y: u32, width: u32, height: u32) -> Self
pub fn crop(self, x: u32, y: u32, width: u32, height: u32) -> Self
Extract the rectangular window at (x, y) of size width × height.
A window outside the image is an error, surfaced at the terminal.
Sourcepub fn resize(self, width: u32, height: u32) -> Self
pub fn resize(self, width: u32, height: u32) -> Self
Resample to width by height with the default filter (Lanczos3).
Sourcepub fn resize_with(
self,
width: u32,
height: u32,
options: ResizeOptions,
) -> Self
pub fn resize_with( self, width: u32, height: u32, options: ResizeOptions, ) -> Self
Resample to width by height with explicit options.
Sourcepub fn thumbnail(self, width: u32, height: u32) -> Self
pub fn thumbnail(self, width: u32, height: u32) -> Self
Scale to fit inside width by height, preserving aspect ratio.
Sourcepub fn orient(self, orientation: Orientation) -> Self
pub fn orient(self, orientation: Orientation) -> Self
Apply orientation: the stored image becomes the upright one.
Image::open and Image::from_stream already do this with the
orientation the file declares; this is for pixels opened with
auto_orient off or through Image::from_decoder. It is a quarter
turn and a mirror at most, and both rescale, so an oriented JPEG
keeps its shrink-on-load fast path.
Sourcepub fn extract_channel(self, index: usize) -> Self
pub fn extract_channel(self, index: usize) -> Self
Extract one channel as a greyscale image.
Sourcepub fn extract_channel_named(self, channel: Channel) -> Self
pub fn extract_channel_named(self, channel: Channel) -> Self
Extract a channel by name (sharp’s extractChannel('red') and so on).
Alpha is the last channel of an image that has one. A greyscale image has no green or blue, and asking for them is an error, surfaced at the terminal like any other.
Sourcepub fn negate(self, alpha: bool) -> Self
pub fn negate(self, alpha: bool) -> Self
Invert colours, and alpha too when alpha is set (sharp’s negate,
whose default is to invert alpha).
Sourcepub fn gamma(self, exponent: f32) -> Self
pub fn gamma(self, exponent: f32) -> Self
Gamma: each colour channel becomes value^(1 / exponent) (libvips’
definition); above 1 brightens.
sharp’s gamma(g, gOut) is gamma(1.0 / g) before a resize and
gamma(gOut) after it.
Sourcepub fn linear(self, a: f32, b: f32) -> Self
pub fn linear(self, a: f32, b: f32) -> Self
value * a + b on every colour channel (sharp’s linear), with b
in 8-bit units at any depth. Alpha is untouched.
Sourcepub fn linear_per_channel(self, a: [f32; 3], b: [f32; 3]) -> Self
pub fn linear_per_channel(self, a: [f32; 3], b: [f32; 3]) -> Self
Image::linear with a separate a and b for red, green and blue.
Sourcepub fn threshold(self, level: u8, greyscale: bool) -> Self
pub fn threshold(self, level: u8, greyscale: bool) -> Self
Two levels (sharp’s threshold): at or above level (8-bit units;
sharp’s default is 128) becomes full, below becomes zero. With
greyscale, sharp’s default, luma is thresholded into every colour
channel; without, each channel on its own.
Sourcepub fn tint(self, red: u8, green: u8, blue: u8) -> Self
pub fn tint(self, red: u8, green: u8, blue: u8) -> Self
Tint towards a colour, keeping each pixel’s luma (sharp’s tint).
A greyscale image becomes colour.
Sourcepub fn greyscale(self) -> Self
pub fn greyscale(self) -> Self
Greyscale by BT.601 luma (sharp’s greyscale). As in sharp, the
channel count is kept: RGB becomes three equal channels, and alpha is
untouched. Use Image::to_pixel_format for a one-channel image.
Sourcepub fn recomb(self, matrix: [[f32; 3]; 3]) -> Self
pub fn recomb(self, matrix: [[f32; 3]; 3]) -> Self
Mix red, green and blue through a 3x3 matrix (sharp’s recomb):
out[i] = sum(matrix[i][j] * in[j]). Alpha is untouched.
Sourcepub fn recomb_rgba(self, matrix: [[f32; 4]; 4]) -> Self
pub fn recomb_rgba(self, matrix: [[f32; 4]; 4]) -> Self
Image::recomb with a 4x4 matrix that mixes alpha too; an image
without alpha gains an opaque one first.
Sourcepub fn ensure_alpha(self, level: f32) -> Self
pub fn ensure_alpha(self, level: f32) -> Self
Add an alpha channel at level, 0 transparent to 1 opaque, if there
is none (sharp’s ensureAlpha, default 1). An image with alpha is
unchanged.
Sourcepub fn remove_alpha(self) -> Self
pub fn remove_alpha(self) -> Self
Drop the alpha channel without compositing (sharp’s removeAlpha).
Use Image::flatten to composite onto a colour instead. An image
without alpha is unchanged.
Sourcepub fn flatten(self, red: u8, green: u8, blue: u8) -> Self
pub fn flatten(self, red: u8, green: u8, blue: u8) -> Self
Composite this image against an opaque background, discarding alpha.
Sourcepub fn extend(self, options: Extend) -> Self
pub fn extend(self, options: Extend) -> Self
Grow the canvas by a margin on each side (sharp’s extend).
As in sharp, a translucent background on an image without alpha adds an opaque alpha channel first, so the margin can be translucent.
Sourcepub fn trim(self, options: Trim) -> Self
pub fn trim(self, options: Trim) -> Self
Cut away a border of near-background pixels (sharp’s trim).
The background is the top-left pixel’s colour unless options give
one; see Trim for what counts as near. An image that is all
background is left as it is, as sharp leaves it, and
Image::trim_offset says where the cut was.
This is the one chaining method that does work when it is called:
the size of the result depends on its pixels, which are not known
until the pipeline so far has run. It runs on Scheduler::global,
and the result is held in memory, so place trim after any resize
that makes the image smaller. Errors are still deferred to the
terminal, like every other chaining method’s.
Sourcepub const fn trim_offset(&self) -> Option<(u32, u32)>
pub const fn trim_offset(&self) -> Option<(u32, u32)>
Where the last Image::trim cut: the left and top of the kept box
in the image it trimmed, or None if this pipeline was not trimmed.
sharp reports these negated, as trimOffsetLeft and trimOffsetTop.
Sourcepub fn composite(self, overlay: Self, x: i64, y: i64) -> Self
pub fn composite(self, overlay: Self, x: i64, y: i64) -> Self
Draw overlay over this image at (x, y).
This is the join point for two branches of a graph: both pipelines stay lazy, and neither is evaluated until a terminal pulls on the result.
Sourcepub fn composite_with(self, overlay: Self, x: i64, y: i64, blend: Blend) -> Self
pub fn composite_with(self, overlay: Self, x: i64, y: i64, blend: Blend) -> Self
Draw overlay over this image with an explicit blend mode.
Sourcepub fn composite_overlays(
self,
overlays: impl IntoIterator<Item = Overlay>,
) -> Self
pub fn composite_overlays( self, overlays: impl IntoIterator<Item = Overlay>, ) -> Self
Draw each of overlays in turn, the first lowest (sharp’s
composite([...])). Each has its own placement and blend; see
Overlay. With none, the image is unchanged.
The overlays may differ from this image in format: an RGBA watermark
over an RGB photo stays RGB under Blend::Over, a grey image under
a colour overlay becomes colour, and a blend that can make the image
translucent (Blend::Clear, Blend::DestOut, …) adds alpha.
Sourcepub fn animation(&self) -> Option<&Animation>
pub fn animation(&self) -> Option<&Animation>
The source file’s animation, if it has more than one frame.
The pipeline processes the first frame, so this describes what the
file holds rather than what will be written: frame count, loop count
and per-frame durations, for a caller to decide whether a still is
what it wants (see OpenOptions::animated).
Sourcepub const fn pages(&self) -> u32
pub const fn pages(&self) -> u32
How many pages the source document holds, at least 1.
More than one only for a multi-page TIFF. The pipeline processes the
page it was opened on, the first unless OpenOptions::page chose
another, so this says what else the file holds. Counting reads no
pixels.
Sourcepub fn icc_profile(&self) -> Option<&[u8]>
pub fn icc_profile(&self) -> Option<&[u8]>
The ICC profile this image’s pixels are in, if it is not sRGB.
A file’s embedded profile, unless the pixels were converted to sRGB
on open (see OpenOptions). It is written into the output where
the format has a place for one, so colours survive the round trip.
Sourcepub fn to_srgb(self) -> Self
pub fn to_srgb(self) -> Self
Convert the pixels from their ICC profile’s colour space to sRGB, and drop the profile.
Image::open already does this unless told not to
(OpenOptions::to_srgb). Matrix/TRC RGB and grey profiles convert,
relative colorimetric with out-of-gamut colours clipped, as lcms2
does; a profile that is sRGB in all but name is just dropped. Any
other profile (LUT-based, CMYK, one that does not match the pixels)
is kept, unconverted, so the output still carries it.
Sourcepub fn to_pixel_format(self, pixel: PixelFormat) -> Self
pub fn to_pixel_format(self, pixel: PixelFormat) -> Self
Convert to pixel: depth (8-bit, 16-bit, float) and layout (grey,
grey with alpha, RGB, RGBA). Grey widens to RGB by repetition and RGB
narrows to grey by BT.601 luma; alpha is added opaque or dropped
(use Image::flatten to composite against a colour instead).
Outputs need not ask for this: Image::output narrows to what the
format holds by itself.
Sourcepub fn exif(&self) -> Option<&[u8]>
pub fn exif(&self) -> Option<&[u8]>
The source’s EXIF block, TIFF-structured, if it had one.
Outputs drop it unless EncodeOptions::keep_exif is set. When
OpenOptions::auto_orient turned the pixels upright, its
Orientation tag already says so.
Sourcepub fn with_exif(self, exif: Option<Vec<u8>>) -> Self
pub fn with_exif(self, exif: Option<Vec<u8>>) -> Self
Replace the EXIF block an output with EncodeOptions::keep_exif
writes, or with None remove it (sharp’s withExif, given whole).
exif is TIFF-structured, from its II or MM byte-order mark.
Sourcepub fn xmp(&self) -> Option<&[u8]>
pub fn xmp(&self) -> Option<&[u8]>
The source’s XMP packet, if it had one.
Outputs drop it unless EncodeOptions::keep_xmp is set, as for
EXIF.
Sourcepub fn with_xmp(self, xmp: Option<Vec<u8>>) -> Self
pub fn with_xmp(self, xmp: Option<Vec<u8>>) -> Self
Replace the XMP packet an output with EncodeOptions::keep_xmp
writes, or with None remove it (sharp’s withXmp).
Sourcepub const fn density(&self) -> Option<Density>
pub const fn density(&self) -> Option<Density>
The resolution outputs will write, if one was set with
Image::with_density.
Sourcepub const fn with_density(self, density: Option<Density>) -> Self
pub const fn with_density(self, density: Option<Density>) -> Self
Write density as the output’s resolution (sharp’s
withMetadata({ density })): JPEG’s JFIF header, PNG’s pHYs, TIFF’s
resolution tags. Without it an output writes the source’s density only
when it keeps the metadata (EncodeOptions::with_keep_metadata).
Sourcepub fn source_metadata(&self) -> Option<&SourceMetadata>
pub fn source_metadata(&self) -> Option<&SourceMetadata>
What the source file says about itself (sharp’s metadata()): its
format and stored size, depth, alpha, orientation, density, pages and
animation, palette, interlace and subsampling, background, comments,
and its EXIF, ICC and XMP. Read from the headers; decodes nothing.
None for an image that did not come from a file.
Sourcepub fn stats(&self) -> Result<Stats>
pub fn stats(&self) -> Result<Stats>
Pixel statistics of this pipeline’s result (sharp’s stats()): per
channel extremes, sums, mean and deviation, whether it is opaque, its
entropy and sharpness, and its dominant colour. A terminal: it runs
the pipeline.
§Errors
As Output::bytes.
Sourcepub fn with_icc_profile(self, profile: Option<Vec<u8>>) -> Self
pub fn with_icc_profile(self, profile: Option<Vec<u8>>) -> Self
Declare the ICC profile the pixels are in, or with None drop it and
call them sRGB. Only the label changes, never a pixel.
Sourcepub fn apply(self, op: Arc<dyn Op>) -> Self
pub fn apply(self, op: Arc<dyn Op>) -> Self
Chain an arbitrary op onto this pipeline.
The escape hatch for ops defined outside this crate. Errors are deferred to the terminal, like every other chaining method.
Sourcepub fn output(self, format: Format, options: EncodeOptions) -> Output
pub fn output(self, format: Format, options: EncodeOptions) -> Output
Choose the encoder and options for this pipeline’s output.
This is the single encode terminal, with format as data (ADR-0006):
requesting a format that is not yet implemented is a catchable
PixelsError::Unsupported, not a compile error.