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