1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
//! # Raster //! //! Raster is an image processing lib for Rust. //! //! It provides a simplified API for processing raster images (JPEG, PNG and GIF). //! //! ## Installation //! Add this to your Cargo.toml file: //! //! ```rust,ignore //! [dependencies] //! //! raster = "x.x.x" //! ``` //! Where x are version numbers of the [latest version](https://crates.io/crates/raster) of //! raster. Eg.: 0.1.0 //! //! Then add the raster crate in your main.rs: //! //! ```rust,ignore //! extern crate raster; // In your main rust file //! ``` //! //! ## Creating Images //! ### From an image file //! //! ```rust,ignore //! // Create an image from file //! let image = raster::open("tests/in/sample.png").unwrap(); //! //! ``` //! Raster will detect the image format based on the file name. //! //! ### Create a blank image //! ```rust,ignore //! use raster::Image; // Include the Image struct //! //! // Create a blank 150x100 image. Defaults to a black background. //! let image = Image::blank(150, 100); //! //! ``` //! //! ## Saving Images //! Save the opened image file: //! //! ``` //! // Create an image from file //! let image = raster::open("tests/in/sample.png").unwrap(); //! //! // Save opened image //! raster::save(&image, "tests/out/test_open_save.png").unwrap(); //! //! ``` //! //! //! //! //! ## Blending 2 Images //! //! Here are two images blended using the normal mode. //! //! ![](https://kosinix.github.io/raster/out/test_blend_normal.png) //! //! More blending modes and options are available, see the blend API. //! //! ## Resizing Images //! //! An example of images resized to "fit" in a 200x200 box. //! //! ![](https://kosinix.github.io/raster/out/test_resize_fit_1.jpg) ![](https://kosinix.github.io/raster/out/test_resize_fit_2.jpg) //! //! More modes available, see the resize API. //! //! ## Rotating Images //! //! Images can be rotated both clockwise and counter-clockwise at any arbitrary angle with a //! custom background color. //! //! ![](https://kosinix.github.io/raster/out/test_transform_rotate_45.png) //! ![](https://kosinix.github.io/raster/out/test_transform_rotate_45cc.png) //! //! ## And Many More... //! //! More options are available, checkout the modules below. //! // modules pub mod compare; pub mod editor; pub mod error; pub mod filter; pub mod interpolate; pub mod transform; mod blend; mod color; mod endec; mod image; mod position; // crates extern crate gif; extern crate image as piston_image; extern crate png; // from rust use std::ascii::AsciiExt; use std::fs::File; use std::path::Path; // from external crate use piston_image::GenericImage; // from local crate use error::{RasterError, RasterResult}; // re-exports pub use blend::BlendMode; pub use color::Color; pub use editor::ResizeMode; pub use filter::BlurMode; pub use filter::Orientation; pub use image::Histogram; pub use image::Image; pub use image::ImageFormat; pub use interpolate::InterpolationMode; pub use position::PositionMode; pub use transform::TransformMode; /// Create an image from an image file. /// /// # Errors /// /// This function can return `RasterError::Io`, `RasterError::Decode`, or /// `RasterError::UnsupportedFormat` upon failure. /// See error module for more info. /// /// # Examples /// /// ``` /// // Create an image from file /// let image = raster::open("tests/in/sample.png").unwrap(); /// println!("{:?}", image.bytes); /// ``` pub fn open(image_file: &str) -> RasterResult<Image> { let path = Path::new(image_file); let ext = path.extension() .and_then(|s| s.to_str()) .map_or("".to_string(), |s| s.to_ascii_lowercase()); // Open the file with basic error check let file = File::open(image_file)?; match &ext[..] { "gif" => Ok(endec::decode_gif(&file)?), "jpg" | "jpeg" => { let src = piston_image::open(image_file)?; let (w, h) = src.dimensions(); let mut bytes = Vec::with_capacity((w * h) as usize * 4); for y in 0..h { for x in 0..w { let p = src.get_pixel(x, y); bytes.extend_from_slice(&p.data[0..4]); } } Ok(Image { width: w as i32, height: h as i32, bytes: bytes, }) } "png" => Ok(endec::decode_png(&file)?), _ => Err(RasterError::UnsupportedFormat(ext)), } } /// Save an image to an image file. The image type is detected from the file extension of the file /// name. /// /// # Errors /// /// This function can return `RasterError::Io`, `RasterError::Encode`, or /// `RasterError::UnsupportedFormat` upon failure. /// See error module for more info. /// /// # Examples /// /// ``` /// // Create an image from file /// let image = raster::open("tests/in/sample.png").unwrap(); /// raster::save(&image, "tests/out/test.png").unwrap(); /// ``` pub fn save(image: &Image, out: &str) -> RasterResult<()> { let path = Path::new(out); let ext = path.extension() .and_then(|s| s.to_str()) .map_or("".to_string(), |s| s.to_ascii_lowercase()); match &ext[..] { "gif" => Ok(endec::encode_gif(&image, &path)?), "jpg" | "jpeg" => { piston_image::save_buffer( &path, &image.bytes, image.width as u32, image.height as u32, piston_image::RGBA(8), ).map_err(|_| RasterError::Encode(ImageFormat::Jpeg, "Format".to_string())) } "png" => Ok(endec::encode_png(&image, &path)?), _ => Err(RasterError::UnsupportedFormat(ext)), } }