1# Image [![crates.io](https://img.shields.io/crates/v/image.svg)](https://crates.io/crates/image) [![Build Status](https://travis-ci.org/image-rs/image.svg?branch=master)](https://travis-ci.org/image-rs/image) [![Gitter](https://badges.gitter.im/image-rs/image.svg)](https://gitter.im/image-rs/image?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) 2 3Maintainers: @HeroicKatora, @fintelia 4 5[How to contribute](https://github.com/image-rs/organization/blob/master/CONTRIBUTING.md) 6 7## An Image Processing Library 8 9This crate provides basic imaging processing functions and methods for converting to and from image formats. 10 11All image processing functions provided operate on types that implement the `GenericImageView` and `GenericImage` traits and return an `ImageBuffer`. 12 13## 1. Documentation 14 15https://docs.rs/image 16 17## 2. Supported Image Formats 18 19`image` provides implementations of common image format encoders and decoders. 20 21### 2.1 Supported Image Formats 22 23| Format | Decoding | Encoding | 24| ------ | -------- | -------- | 25| PNG | All supported color types | Same as decoding | 26| JPEG | Baseline and progressive | Baseline JPEG | 27| GIF | Yes | Yes | 28| BMP | Yes | RGB(8), RGBA(8), Gray(8), GrayA(8) | 29| ICO | Yes | Yes | 30| TIFF | Baseline(no fax support) + LZW + PackBits | RGB(8), RGBA(8), Gray(8) | 31| WebP | Lossy(Luma channel only) | No | 32| PNM | PBM, PGM, PPM, standard PAM | Yes | 33| DDS | DXT1, DXT3, DXT5 | No | 34| TGA | Yes | RGB(8), RGBA(8), BGR(8), BGRA(8), Gray(8), GrayA(8) | 35| farbfeld | Yes | Yes | 36 37### 2.2 The [`ImageDecoder`](https://docs.rs/image/0.23.8/image/trait.ImageDecoder.html) and [`ImageDecoderExt`](https://docs.rs/image/0.23.8/image/trait.ImageDecoderExt.html) Traits 38 39All image format decoders implement the `ImageDecoder` trait which provide 40basic methods for getting image metadata and decoding images. Some formats 41additionally provide `ImageDecoderExt` implementations which allow for 42decoding only part of an image at once. 43 44The most important methods for decoders are... 45+ **dimensions**: Return a tuple containing the width and height of the image. 46+ **color_type**: Return the color type of the image data produced by this decoder. 47+ **read_image**: Decode the entire image into a slice of bytes. 48 49## 3 Pixels 50 51`image` provides the following pixel types: 52+ **Rgb**: RGB pixel 53+ **Rgba**: RGBA pixel 54+ **Luma**: Grayscale pixel 55+ **LumaA**: Grayscale with alpha 56 57All pixels are parameterised by their component type. 58 59## 4 Images 60### 4.1 The [`GenericImageView`](https://docs.rs/image/0.23.8/image/trait.GenericImageView.html) and [`GenericImage`](https://docs.rs/image/0.23.8/image/trait.GenericImage.html) Traits 61 62Traits that provide methods for inspecting (`GenericImageView`) and manipulating (`GenericImage`) images, parameterised over the image's pixel type. 63 64Some of these methods for `GenericImageView` are... 65+ **dimensions**: Return a tuple containing the width and height of the image. 66+ **get_pixel**: Returns the pixel located at (x, y). 67+ **pixels**: Returns an Iterator over the pixels of this image. 68 69While some of the methods for `GenericImage` are... 70+ **put_pixel**: Put a pixel at location (x, y). 71+ **copy_from**: Copies all of the pixels from another image into this image. 72 73### 4.2 Representation of Images 74`image` provides two main ways of representing image data: 75 76#### 4.2.1 [`ImageBuffer`](https://docs.rs/image/0.23.8/image/struct.ImageBuffer.html) 77An image parameterised by its Pixel types, 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. 78 79```rust 80extern crate image; 81 82use image::{GenericImage, GenericImageView, ImageBuffer, RgbImage}; 83 84// Construct a new RGB ImageBuffer with the specified width and height. 85let img: RgbImage = ImageBuffer::new(512, 512); 86 87// Construct a new by repeated calls to the supplied closure. 88let mut img = ImageBuffer::from_fn(512, 512, |x, y| { 89 if x % 2 == 0 { 90 image::Luma([0u8]) 91 } else { 92 image::Luma([255u8]) 93 } 94}); 95 96// Obtain the image's width and height. 97let (width, height) = img.dimensions(); 98 99// Access the pixel at coordinate (100, 100). 100let pixel = img[(100, 100)]; 101 102// Or use the `get_pixel` method from the `GenericImage` trait. 103let pixel = *img.get_pixel(100, 100); 104 105// Put a pixel at coordinate (100, 100). 106img.put_pixel(100, 100, pixel); 107 108// Iterate over all pixels in the image. 109for pixel in img.pixels() { 110 // Do something with pixel. 111} 112``` 113 114#### 4.2.2 [`DynamicImage`](https://docs.rs/image/0.23.8/image/enum.DynamicImage.html) 115A `DynamicImage` is an enumeration over all supported `ImageBuffer<P>` types. 116Its exact image type is determined at runtime. It is the type returned when opening an image. 117For convenience `DynamicImage` reimplements all image processing functions. 118 119`DynamicImage` implement the `GenericImageView` and `GenericImage` traits for RGBA pixels. 120 121#### 4.2.3 [`SubImage`](https://docs.rs/image/0.23.8/image/struct.SubImage.html) 122A view into another image, delimited by the coordinates of a rectangle. 123This is used to perform image processing functions on a subregion of an image. 124 125```rust 126extern crate image; 127 128use image::{GenericImageView, ImageBuffer, RgbImage, imageops}; 129 130let mut img: RgbImage = ImageBuffer::new(512, 512); 131let subimg = imageops::crop(&mut img, 0, 0, 100, 100); 132 133assert!(subimg.dimensions() == (100, 100)); 134``` 135 136## 5 Image Processing Functions 137These are the functions defined in the `imageops` module. All functions operate on types that implement the `GenericImage` trait. 138 139+ **blur**: Performs a Gaussian blur on the supplied image. 140+ **brighten**: Brighten the supplied image 141+ **huerotate**: Hue rotate the supplied image by degrees 142+ **contrast**: Adjust the contrast of the supplied image 143+ **crop**: Return a mutable view into an image 144+ **filter3x3**: Perform a 3x3 box filter on the supplied image. 145+ **flip_horizontal**: Flip an image horizontally 146+ **flip_vertical**: Flip an image vertically 147+ **grayscale**: Convert the supplied image to grayscale 148+ **invert**: Invert each pixel within the supplied image This function operates in place. 149+ **resize**: Resize the supplied image to the specified dimensions 150+ **rotate180**: Rotate an image 180 degrees clockwise. 151+ **rotate270**: Rotate an image 270 degrees clockwise. 152+ **rotate90**: Rotate an image 90 degrees clockwise. 153+ **unsharpen**: Performs an unsharpen mask on the supplied image 154 155For more options, see the [`imageproc`](https://crates.io/crates/imageproc) crate. 156 157## 6 Examples 158### 6.1 Opening and Saving Images 159 160`image` provides the `open` function for opening images from a path. The image 161format is determined from the path's file extension. An `io` module provides a 162reader which offer some more control. 163 164```rust,no_run 165extern crate image; 166 167use image::GenericImageView; 168 169fn main() { 170 // Use the open function to load an image from a Path. 171 // `open` returns a `DynamicImage` on success. 172 let img = image::open("tests/images/jpg/progressive/cat.jpg").unwrap(); 173 174 // The dimensions method returns the images width and height. 175 println!("dimensions {:?}", img.dimensions()); 176 177 // The color method returns the image's `ColorType`. 178 println!("{:?}", img.color()); 179 180 // Write the contents of this image to the Writer in PNG format. 181 img.save("test.png").unwrap(); 182} 183``` 184 185### 6.2 Generating Fractals 186 187```rust,no_run 188//! An example of generating julia fractals. 189extern crate image; 190extern crate num_complex; 191 192fn main() { 193 let imgx = 800; 194 let imgy = 800; 195 196 let scalex = 3.0 / imgx as f32; 197 let scaley = 3.0 / imgy as f32; 198 199 // Create a new ImgBuf with width: imgx and height: imgy 200 let mut imgbuf = image::ImageBuffer::new(imgx, imgy); 201 202 // Iterate over the coordinates and pixels of the image 203 for (x, y, pixel) in imgbuf.enumerate_pixels_mut() { 204 let r = (0.3 * x as f32) as u8; 205 let b = (0.3 * y as f32) as u8; 206 *pixel = image::Rgb([r, 0, b]); 207 } 208 209 // A redundant loop to demonstrate reading image data 210 for x in 0..imgx { 211 for y in 0..imgy { 212 let cx = y as f32 * scalex - 1.5; 213 let cy = x as f32 * scaley - 1.5; 214 215 let c = num_complex::Complex::new(-0.4, 0.6); 216 let mut z = num_complex::Complex::new(cx, cy); 217 218 let mut i = 0; 219 while i < 255 && z.norm() <= 2.0 { 220 z = z * z + c; 221 i += 1; 222 } 223 224 let pixel = imgbuf.get_pixel_mut(x, y); 225 let image::Rgb(data) = *pixel; 226 *pixel = image::Rgb([data[0], i as u8, data[2]]); 227 } 228 } 229 230 // Save the image as “fractal.png”, the format is deduced from the path 231 imgbuf.save("fractal.png").unwrap(); 232} 233``` 234 235Example output: 236 237<img src="examples/fractal.png" alt="A Julia Fractal, c: -0.4 + 0.6i" width="500" /> 238 239### 6.3 Writing raw buffers 240If 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. 241 242```rust,no_run 243extern crate image; 244 245fn main() { 246 247 let buffer: &[u8] = unimplemented!(); // Generate the image data 248 249 // Save the buffer as "image.png" 250 image::save_buffer("image.png", buffer, 800, 600, image::ColorType::Rgb8).unwrap() 251} 252 253``` 254