1 | //! # Overview |
2 | //! |
3 | //! This crate provides native rust implementations of image encoding and decoding as well as some |
4 | //! basic image manipulation functions. Additional documentation can currently also be found in the |
5 | //! [README.md file which is most easily viewed on |
6 | //! github](https://github.com/image-rs/image/blob/master/README.md). |
7 | //! |
8 | //! There are two core problems for which this library provides solutions: a unified interface for image |
9 | //! encodings and simple generic buffers for their content. It's possible to use either feature |
10 | //! without the other. The focus is on a small and stable set of common operations that can be |
11 | //! supplemented by other specialized crates. The library also prefers safe solutions with few |
12 | //! dependencies. |
13 | //! |
14 | //! # High level API |
15 | //! |
16 | //! Load images using [`io::Reader`]: |
17 | //! |
18 | //! ```rust,no_run |
19 | //! use std::io::Cursor; |
20 | //! use image::io::Reader as ImageReader; |
21 | //! # fn main() -> Result<(), image::ImageError> { |
22 | //! # let bytes = vec![0u8]; |
23 | //! |
24 | //! let img = ImageReader::open("myimage.png" )?.decode()?; |
25 | //! let img2 = ImageReader::new(Cursor::new(bytes)).with_guessed_format()?.decode()?; |
26 | //! # Ok(()) |
27 | //! # } |
28 | //! ``` |
29 | //! |
30 | //! And save them using [`save`] or [`write_to`] methods: |
31 | //! |
32 | //! ```rust,no_run |
33 | //! # use std::io::{Write, Cursor}; |
34 | //! # use image::{DynamicImage, ImageOutputFormat}; |
35 | //! # #[cfg (feature = "png" )] |
36 | //! # fn main() -> Result<(), image::ImageError> { |
37 | //! # let img: DynamicImage = unimplemented!(); |
38 | //! # let img2: DynamicImage = unimplemented!(); |
39 | //! img.save("empty.jpg" )?; |
40 | //! |
41 | //! let mut bytes: Vec<u8> = Vec::new(); |
42 | //! img2.write_to(&mut Cursor::new(&mut bytes), image::ImageOutputFormat::Png)?; |
43 | //! # Ok(()) |
44 | //! # } |
45 | //! # #[cfg (not(feature = "png" ))] fn main() {} |
46 | //! ``` |
47 | //! |
48 | //! With default features, the crate includes support for [many common image formats](codecs/index.html#supported-formats). |
49 | //! |
50 | //! [`save`]: enum.DynamicImage.html#method.save |
51 | //! [`write_to`]: enum.DynamicImage.html#method.write_to |
52 | //! [`io::Reader`]: io/struct.Reader.html |
53 | //! |
54 | //! # Image buffers |
55 | //! |
56 | //! The two main types for storing images: |
57 | //! * [`ImageBuffer`] which holds statically typed image contents. |
58 | //! * [`DynamicImage`] which is an enum over the supported ImageBuffer formats |
59 | //! and supports conversions between them. |
60 | //! |
61 | //! As well as a few more specialized options: |
62 | //! * [`GenericImage`] trait for a mutable image buffer. |
63 | //! * [`GenericImageView`] trait for read only references to a GenericImage. |
64 | //! * [`flat`] module containing types for interoperability with generic channel |
65 | //! matrices and foreign interfaces. |
66 | //! |
67 | //! [`GenericImageView`]: trait.GenericImageView.html |
68 | //! [`GenericImage`]: trait.GenericImage.html |
69 | //! [`ImageBuffer`]: struct.ImageBuffer.html |
70 | //! [`DynamicImage`]: enum.DynamicImage.html |
71 | //! [`flat`]: flat/index.html |
72 | //! |
73 | //! # Low level encoding/decoding API |
74 | //! |
75 | //! Implementations of [`ImageEncoder`] provides low level control over encoding: |
76 | //! ```rust,no_run |
77 | //! # use std::io::Write; |
78 | //! # use image::DynamicImage; |
79 | //! # use image::ImageEncoder; |
80 | //! # #[cfg (feature = "jpeg" )] |
81 | //! # fn main() -> Result<(), image::ImageError> { |
82 | //! # use image::codecs::jpeg::JpegEncoder; |
83 | //! # let img: DynamicImage = unimplemented!(); |
84 | //! # let writer: Box<dyn Write> = unimplemented!(); |
85 | //! let encoder = JpegEncoder::new_with_quality(&mut writer, 95); |
86 | //! img.write_with_encoder(encoder)?; |
87 | //! # Ok(()) |
88 | //! # } |
89 | //! # #[cfg (not(feature = "jpeg" ))] fn main() {} |
90 | //! ``` |
91 | //! While [`ImageDecoder`] and [`ImageDecoderRect`] give access to more advanced decoding options: |
92 | //! |
93 | //! ```rust,no_run |
94 | //! # use std::io::Read; |
95 | //! # use image::DynamicImage; |
96 | //! # use image::ImageDecoder; |
97 | //! # #[cfg (feature = "png" )] |
98 | //! # fn main() -> Result<(), image::ImageError> { |
99 | //! # use image::codecs::png::PngDecoder; |
100 | //! # let img: DynamicImage = unimplemented!(); |
101 | //! # let reader: Box<dyn Read> = unimplemented!(); |
102 | //! let decoder = PngDecoder::new(&mut reader)?; |
103 | //! let icc = decoder.icc_profile(); |
104 | //! let img = DynamicImage::from_decoder(decoder)?; |
105 | //! # Ok(()) |
106 | //! # } |
107 | //! # #[cfg (not(feature = "png" ))] fn main() {} |
108 | //! ``` |
109 | //! |
110 | //! [`DynamicImage::from_decoder`]: enum.DynamicImage.html#method.from_decoder |
111 | //! [`ImageDecoderRect`]: trait.ImageDecoderRect.html |
112 | //! [`ImageDecoder`]: trait.ImageDecoder.html |
113 | //! [`ImageEncoder`]: trait.ImageEncoder.html |
114 | #![warn (missing_docs)] |
115 | #![warn (unused_qualifications)] |
116 | #![deny (unreachable_pub)] |
117 | #![deny (deprecated)] |
118 | #![deny (missing_copy_implementations)] |
119 | #![cfg_attr (all(test, feature = "benchmarks" ), feature(test))] |
120 | // it's a backwards compatibility break |
121 | #![allow (clippy::wrong_self_convention, clippy::enum_variant_names)] |
122 | #![cfg_attr (docsrs, feature(doc_auto_cfg))] |
123 | |
124 | #[cfg (all(test, feature = "benchmarks" ))] |
125 | extern crate test; |
126 | |
127 | #[cfg (test)] |
128 | #[macro_use ] |
129 | extern crate quickcheck; |
130 | |
131 | pub use crate::color::{ColorType, ExtendedColorType}; |
132 | |
133 | pub use crate::color::{Luma, LumaA, Rgb, Rgba}; |
134 | |
135 | pub use crate::error::{ImageError, ImageResult}; |
136 | |
137 | pub use crate::image::{ |
138 | AnimationDecoder, |
139 | GenericImage, |
140 | GenericImageView, |
141 | ImageDecoder, |
142 | ImageDecoderRect, |
143 | ImageEncoder, |
144 | ImageFormat, |
145 | ImageOutputFormat, |
146 | // Iterators |
147 | Pixels, |
148 | Progress, |
149 | SubImage, |
150 | }; |
151 | |
152 | pub use crate::buffer_::{ |
153 | GrayAlphaImage, |
154 | GrayImage, |
155 | // Image types |
156 | ImageBuffer, |
157 | Rgb32FImage, |
158 | RgbImage, |
159 | Rgba32FImage, |
160 | RgbaImage, |
161 | }; |
162 | |
163 | pub use crate::flat::FlatSamples; |
164 | |
165 | // Traits |
166 | pub use crate::traits::{EncodableLayout, Pixel, PixelWithColorType, Primitive}; |
167 | |
168 | // Opening and loading images |
169 | pub use crate::dynimage::{ |
170 | image_dimensions, load_from_memory, load_from_memory_with_format, open, save_buffer, |
171 | save_buffer_with_format, write_buffer_with_format, |
172 | }; |
173 | pub use crate::io::free_functions::{guess_format, load}; |
174 | |
175 | pub use crate::dynimage::DynamicImage; |
176 | |
177 | pub use crate::animation::{Delay, Frame, Frames}; |
178 | |
179 | // More detailed error type |
180 | pub mod error; |
181 | |
182 | /// Iterators and other auxiliary structure for the `ImageBuffer` type. |
183 | pub mod buffer { |
184 | // Only those not exported at the top-level |
185 | pub use crate::buffer_::{ |
186 | ConvertBuffer, EnumeratePixels, EnumeratePixelsMut, EnumerateRows, EnumerateRowsMut, |
187 | Pixels, PixelsMut, Rows, RowsMut, |
188 | }; |
189 | |
190 | #[cfg (feature = "rayon" )] |
191 | pub use crate::buffer_par::*; |
192 | } |
193 | |
194 | // Math utils |
195 | pub mod math; |
196 | |
197 | // Image processing functions |
198 | pub mod imageops; |
199 | |
200 | // Io bindings |
201 | pub mod io; |
202 | |
203 | // Buffer representations for ffi. |
204 | pub mod flat; |
205 | |
206 | /// Encoding and decoding for various image file formats. |
207 | /// |
208 | /// # Supported formats |
209 | /// |
210 | /// <!--- NOTE: Make sure to keep this table in sync with the README --> |
211 | /// |
212 | /// | Format | Decoding | Encoding | |
213 | /// | -------- | ----------------------------------------- | --------------------------------------- | |
214 | /// | AVIF | Only 8-bit | Lossy | |
215 | /// | BMP | Yes | Rgb8, Rgba8, Gray8, GrayA8 | |
216 | /// | DDS | DXT1, DXT3, DXT5 | No | |
217 | /// | Farbfeld | Yes | Yes | |
218 | /// | GIF | Yes | Yes | |
219 | /// | HDR | Yes | Yes | |
220 | /// | ICO | Yes | Yes | |
221 | /// | JPEG | Baseline and progressive | Baseline JPEG | |
222 | /// | OpenEXR | Rgb32F, Rgba32F (no dwa compression) | Rgb32F, Rgba32F (no dwa compression) | |
223 | /// | PNG | All supported color types | Same as decoding | |
224 | /// | PNM | PBM, PGM, PPM, standard PAM | Yes | |
225 | /// | QOI | Yes | Yes | |
226 | /// | TGA | Yes | Rgb8, Rgba8, Bgr8, Bgra8, Gray8, GrayA8 | |
227 | /// | TIFF | Baseline(no fax support) + LZW + PackBits | Rgb8, Rgba8, Gray8 | |
228 | /// | WebP | Yes | Rgb8, Rgba8 | |
229 | /// |
230 | /// ## A note on format specific features |
231 | /// |
232 | /// One of the main goals of `image` is stability, in runtime but also for programmers. This |
233 | /// ensures that performance as well as safety fixes reach a majority of its user base with little |
234 | /// effort. Re-exporting all details of its dependencies would run counter to this goal as it |
235 | /// linked _all_ major version bumps between them and `image`. As such, we are wary of exposing too |
236 | /// many details, or configuration options, that are not shared between different image formats. |
237 | /// |
238 | /// Nevertheless, the advantage of precise control is hard to ignore. We will thus consider |
239 | /// _wrappers_, not direct re-exports, in either of the following cases: |
240 | /// |
241 | /// 1. A standard specifies that configuration _x_ is required for decoders/encoders and there |
242 | /// exists an essentially canonical way to control it. |
243 | /// 2. At least two different implementations agree on some (sub-)set of features in practice. |
244 | /// 3. A technical argument including measurements of the performance, space benefits, or otherwise |
245 | /// objectively quantified benefits can be made, and the added interface is unlikely to require |
246 | /// breaking changes. |
247 | /// |
248 | /// Features that fulfill two or more criteria are preferred. |
249 | /// |
250 | /// Re-exports of dependencies that reach version `1` will be discussed when it happens. |
251 | pub mod codecs { |
252 | #[cfg (any(feature = "avif-encoder" , feature = "avif-decoder" ))] |
253 | pub mod avif; |
254 | #[cfg (feature = "bmp" )] |
255 | pub mod bmp; |
256 | #[cfg (feature = "dds" )] |
257 | pub mod dds; |
258 | #[cfg (feature = "dxt" )] |
259 | #[deprecated = "DXT support will be removed or reworked in a future version. Prefer the `squish` crate instead. See https://github.com/image-rs/image/issues/1623" ] |
260 | pub mod dxt; |
261 | #[cfg (feature = "farbfeld" )] |
262 | pub mod farbfeld; |
263 | #[cfg (feature = "gif" )] |
264 | pub mod gif; |
265 | #[cfg (feature = "hdr" )] |
266 | pub mod hdr; |
267 | #[cfg (feature = "ico" )] |
268 | pub mod ico; |
269 | #[cfg (feature = "jpeg" )] |
270 | pub mod jpeg; |
271 | #[cfg (feature = "exr" )] |
272 | pub mod openexr; |
273 | #[cfg (feature = "png" )] |
274 | pub mod png; |
275 | #[cfg (feature = "pnm" )] |
276 | pub mod pnm; |
277 | #[cfg (feature = "qoi" )] |
278 | pub mod qoi; |
279 | #[cfg (feature = "tga" )] |
280 | pub mod tga; |
281 | #[cfg (feature = "tiff" )] |
282 | pub mod tiff; |
283 | #[cfg (feature = "webp" )] |
284 | pub mod webp; |
285 | } |
286 | |
287 | mod animation; |
288 | #[path = "buffer.rs" ] |
289 | mod buffer_; |
290 | #[cfg (feature = "rayon" )] |
291 | mod buffer_par; |
292 | mod color; |
293 | mod dynimage; |
294 | mod image; |
295 | mod traits; |
296 | mod utils; |
297 | |
298 | // Can't use the macro-call itself within the `doc` attribute. So force it to eval it as part of |
299 | // the macro invocation. |
300 | // |
301 | // The inspiration for the macro and implementation is from |
302 | // <https://github.com/GuillaumeGomez/doc-comment> |
303 | // |
304 | // MIT License |
305 | // |
306 | // Copyright (c) 2018 Guillaume Gomez |
307 | macro_rules! insert_as_doc { |
308 | { $content:expr } => { |
309 | #[allow(unused_doc_comments)] |
310 | #[doc = $content] extern { } |
311 | } |
312 | } |
313 | |
314 | // Provides the README.md as doc, to ensure the example works! |
315 | insert_as_doc!(include_str!("../README.md" )); |
316 | |