Home

Awesome

Image

crates.io Documentation Build Status Gitter

Maintainers: @HeroicKatora, @fintelia

How to contribute

An Image Processing Library

This crate provides basic image processing functions and methods for converting to and from various image formats.

All image processing functions provided operate on types that implement the GenericImageView and GenericImage traits and return an ImageBuffer.

High level API

Load images using [ImageReader]:

use std::io::Cursor;
use image::ImageReader;

let img = ImageReader::open("myimage.png")?.decode()?;
let img2 = ImageReader::new(Cursor::new(bytes)).with_guessed_format()?.decode()?;

And save them using [save] or [write_to] methods:

img.save("empty.jpg")?;

let mut bytes: Vec<u8> = Vec::new();
img2.write_to(&mut Cursor::new(&mut bytes), image::ImageFormat::Png)?;

Supported Image Formats

With default features enabled, image provides implementations of many common image format encoders and decoders.

<!--- NOTE: Make sure to keep this table in sync with the one in src/lib.rs -->
FormatDecodingEncoding
AVIFYes *Yes (lossy only)
BMPYesYes
DDSYes---
FarbfeldYesYes
GIFYesYes
HDRYesYes
ICOYesYes
JPEGYesYes
EXRYesYes
PNGYesYes
PNMYesYes
QOIYesYes
TGAYesYes
TIFFYesYes
WebPYesYes (lossless only)

Image Types

This crate provides a number of different types for representing images. Individual pixels within images are indexed with (0,0) at the top left corner.

ImageBuffer

An image parameterised by its Pixel type, represented by a width and height and a vector of pixels. It provides direct access to its pixels and implements the GenericImageView and GenericImage traits.

DynamicImage

A DynamicImage is an enumeration over all supported ImageBuffer<P> types. Its exact image type is determined at runtime. It is the type returned when opening an image. For convenience DynamicImage reimplements all image processing functions.

The GenericImageView and GenericImage Traits

Traits that provide methods for inspecting (GenericImageView) and manipulating (GenericImage) images, parameterised over the image's pixel type.

SubImage

A view into another image, delimited by the coordinates of a rectangle. The coordinates given set the position of the top left corner of the rectangle. This is used to perform image processing functions on a subregion of an image.

The ImageDecoder and ImageDecoderRect Traits

All image format decoders implement the ImageDecoder trait which provide basic methods for getting image metadata and decoding images. Some formats additionally provide ImageDecoderRect implementations which allow for decoding only part of an image at once.

The most important methods for decoders are...

Pixels

image provides the following pixel types:

All pixels are parameterised by their component type.

Image Processing Functions

These are the functions defined in the imageops module. All functions operate on types that implement the GenericImage trait. Note that some of the functions are very slow in debug mode. Make sure to use release mode if you experience any performance issues.

For more options, see the imageproc crate.

Examples

Opening and Saving Images

image provides the open function for opening images from a path. The image format is determined from the path's file extension. An io module provides a reader which offer some more control.

use image::GenericImageView;

// Use the open function to load an image from a Path.
// `open` returns a `DynamicImage` on success.
let img = image::open("tests/images/jpg/progressive/cat.jpg").unwrap();

// The dimensions method returns the images width and height.
println!("dimensions {:?}", img.dimensions());

// The color method returns the image's `ColorType`.
println!("{:?}", img.color());

// Write the contents of this image to the Writer in PNG format.
img.save("test.png").unwrap();

Generating Fractals

//! An example of generating julia fractals.
let imgx = 800;
let imgy = 800;

let scalex = 3.0 / imgx as f32;
let scaley = 3.0 / imgy as f32;

// Create a new ImgBuf with width: imgx and height: imgy
let mut imgbuf = image::ImageBuffer::new(imgx, imgy);

// Iterate over the coordinates and pixels of the image
for (x, y, pixel) in imgbuf.enumerate_pixels_mut() {
    let r = (0.3 * x as f32) as u8;
    let b = (0.3 * y as f32) as u8;
    *pixel = image::Rgb([r, 0, b]);
}

// A redundant loop to demonstrate reading image data
for x in 0..imgx {
    for y in 0..imgy {
        let cx = y as f32 * scalex - 1.5;
        let cy = x as f32 * scaley - 1.5;

        let c = num_complex::Complex::new(-0.4, 0.6);
        let mut z = num_complex::Complex::new(cx, cy);

        let mut i = 0;
        while i < 255 && z.norm() <= 2.0 {
            z = z * z + c;
            i += 1;
        }

        let pixel = imgbuf.get_pixel_mut(x, y);
        let image::Rgb(data) = *pixel;
        *pixel = image::Rgb([data[0], i as u8, data[2]]);
    }
}

// Save the image as “fractal.png”, the format is deduced from the path
imgbuf.save("fractal.png").unwrap();

Example output:

<img src="examples/fractal.png" alt="A Julia Fractal, c: -0.4 + 0.6i" width="500" />

Writing raw buffers

If the high level interface is not needed because the image was obtained by other means, image provides the function save_buffer to save a buffer to a file.

let buffer: &[u8] = unimplemented!(); // Generate the image data

// Save the buffer as "image.png"
image::save_buffer("image.png", buffer, 800, 600, image::ExtendedColorType::Rgb8).unwrap()