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
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
//! The Rust Imaging Library. A performant and high-level image processing crate for Rust.
//!
//! See benchmarks and more by viewing the [README](https://github.com/jay3332/ril#ril). It should
//! also be noted that the README is updated more frequently than the documentation.
//!
//! Similarly, you can see the changelog [here](https://github.com/jay3332/ril/blob/main/CHANGELOG.md).
//!
//! # Installation
//! The MSRV (Minimum Supported Rust Version) of this crate is **v1.61.0**.
//!
//! Add the following to your `Cargo.toml` dependencies:
//! ```toml
//! ril = { version = "0", features = ["all"] ]
//! ```
//!
//! ## Installing from GitHub
//! You can also use the unstable but latest version by installing from GitHub:
//! ```toml
//! ril = { git = "https://github.com/jay3332/ril", branch = "main", features = ["all"] }
//! ```
//!
//! ## Using `cargo add`
//! If you have cargo >= 1.62.0, you can use `cargo add ril --features=all`.
//!
//! ## Cargo Features
//! RIL currently depends on a few dependencies for certain features - especially for various image encodings.
//! By default RIL comes with no encoding dependencies but with the `text` and `resize` dependencies, which give you text
//! and resizing capabilities respectively.
//!
//! You can use the `all` feature to enable all features, including encoding features. This enables the widest range of
//! image format support, but adds a lot of dependencies you may not need.
//!
//! For every image encoding that requires a dependency, a corresponding feature can be enabled for it:
//!
//! | Encoding | Feature | Dependencies | Default? |
//! |---------------|---------|--------------------------------|----------|
//! | PNG and APNG | `png` | `png` | no |
//! | JPEG | `jpeg` | `jpeg-decoder`, `jpeg-encoder` | no |
//! | GIF | `gif` | `gif` | no |
//! | WebP | `webp` | `libwebp-sys2` | no |
//!
//! Other features:
//!
//! | Description | Feature | Dependencies | Default? |
//! |-----------------------------------------------------------|------------|---------------------|----------|
//! | Font/Text Rendering | `text` | `fontdue` | yes |
//! | Image Resizing | `resize` | `fast_image_resize` | yes |
//! | Color Quantization (using NeuQuant) | `quantize` | `color_quant` | yes |
//! | Gradients | `gradient` | `colorgrad` | yes |
//! | Enable all features,<br/> including all encoding features | `all` | | no |
//!
//! ### WebP Support limitations
//! WebP support uses `libwebp`, which is a native library. This means that if you try to use the
//! `webp` feature when compiling to a WebAssembly target, it might fail. We plan on making a
//! pure-Rust port of `libwebp` in the future.
//!
//! For ease of use, the `all-pure` feature is provided, which is the equivalent of `all` minus the
//! `webp` feature.
//!
//! # Getting Started
//! Import the prelude which brings commonly used types and crucial traits into scope:
//!
//! ```no_run
//! use ril::prelude::*;
//! ```
//!
//! Because all errors from this crate are of the same type, ril provides a `Result` type
//! which you can use in any function that leverages ril, such as the `main` function:
//!
//! ```no_run
//! use ril::prelude::*;
//!
//! fn main() -> ril::Result<()> {
//! // code goes here...
//!
//! Ok(())
//! }
//! ```
//!
//! Now you can use the `?` operator on anything that returns a ``Result`` for convenience.
//!
//! # Brief Guide
//! A quick guide and overview of ril's interface.
//!
//! ## Opening an image
//! The [`open`][Image::open] method should suit your needs:
//!
//! ```no_run
//! # use ril::prelude::*;
//! # fn main() -> ril::Result<()> {
//! let image = Image::<Rgb>::open("my_image.png")?;
//! # Ok(()) }
//! ```
//!
//! The sole argument can be anything that implements [`AsRef<Path>`][AsRef], such as
//! a string or a file.
//!
//! You might have also noticed that [`Image`] is generic with one type parameter,
//! which can be anything that implements [`Pixel`]. It represents what type of pixel
//! this image has - in this case, the image has RGB pixels.
//!
//! Common pixel formats are [`Rgb`] (colored) and [`Rgba`] (colored with transparency),
//! which are found in the prelude. There are also grayscale counterparts, such as [`L`].
//!
//! ### Reading from a byte stream
//! You can also read from raw bytes using [`from_bytes`][Image::decode_from_bytes]:
//!
//! ```ignore
//! # use ril::prelude::*;
//! # fn main() -> ril::Result<()> {
//! let bytes = include_bytes!("image.png") as &[u8]; // Replace this with your own image data
//! let image = Image::<Rgb>::from_bytes(ImageFormat::Png, bytes)?;
//! # Ok(()) }
//! ```
//!
//! The first argument is the encoding of the image, and the second is a slice of bytes, or anything
//! that implements [`AsRef<[u8]>`].
//!
//! You can also use [`from_bytes_inferred`][Image::from_bytes_inferred] to
//! infer the format from the byte slice without having to explicitly provide an encoding:
//!
//! ```no_run
//! # use ril::prelude::*;
//! # fn main() -> ril::Result<()> {
//! # let bytes = [0].as_slice();
//! let image = Image::<Rgb>::from_bytes_inferred(bytes)?;
//! # Ok(()) }
//! ```
//!
//! ## Creating your own image
//! You can create your own image using the [`Image::new`][Image::new] method:
//!
//! ```no_run
//! # use ril::prelude::*;
//! let image = Image::new(256, 256, Rgb::new(255, 0, 0));
//! ```
//!
//! The above creates a 256x256 RGB image with all pixels set to red.
//!
//! The first argument is the width of the image, the second is the height, and the third is the
//! fill color. The pixel type of the image can be inferred from this argument, which is why we
//! don't have to specify it explicitly as a type argument - Rust type inference is powerful and
//! infers this for us.
//!
//! ### The `from_fn` method
//! The [`from_fn`][Image::from_fn] method is a shortcut for creating an image from a function:
//!
//! ```no_run
//! # use ril::prelude::*;
//! let image = Image::from_fn(256, 256, |x, y| {
//! // Do something, maybe with `x` and `y`, and return a pixel
//! Rgb::new(x as u8, y as u8, 0)
//! });
//! ```
//!
//! The above is just an example. You specify the width, height, and the function that
//! generates the pixels. It should take two parameters - `x` and `y`, which specify the position
//! of the pixel to generate - and return a pixel.
//!
//! ## Encoding and saving images
//! You can encode and save an image to a file with the [`save`][Image::save] method:
//!
//! ```no_run
//! # use ril::prelude::*;
//! # fn main() -> ril::Result<()> {
//! // Here's the red image from before:
//! let image = Image::new(256, 256, Rgb::new(255, 0, 0));
//!
//! image.save(ImageFormat::Png, "output.png")?;
//! # Ok(()) }
//! ```
//!
//! The first argument is the encoding of the image, and the second is the path to the file.
//!
//! You may have noticed this is a bit repetitive, and that it is possible to infer the encoding
//! from the file extension. In cases like this, you can use the slightly slower
//! [`save_inferred`][Image::save_inferred] method:
//!
//! ```no_run
//! # use ril::prelude::*;
//! # fn main() -> ril::Result<()> {
//! # let image = Image::new(256, 256, Rgb::new(255, 0, 0));
//! image.save_inferred("output.png")?;
//! # Ok(()) }
//! ```
//!
//! Now, you do not have to explicitly specify the encoding as it is inferred from the output path.
//!
//! ### Encoding and saving images to memory
//! You can encode images to a memory buffer by using the [`encode`][Image::encode] method:
//!
//! ```no_run
//! # use ril::prelude::*;
//! # fn main() -> ril::Result<()> {
//! # let image = Image::new(256, 256, Rgb::new(255, 0, 0));
//! let mut out = Vec::new();
//! image.encode(ImageFormat::Png, &mut out)?;
//! # Ok(()) }
//!
//! // Do something with `out`
//! ```
//!
//! The first argument is the encoding of the image, and the second is the output buffer that must
//! implement [`Write`][std::io::Write].
//!
//! There is no filename to infer the encoding from, so in this case you have to explicitly
//! specify the encoding.
//!
//! ## Manipulating images
//! Now that you know how to create and save images, let's look at some of the ways we can modify
//! them!
//!
//! ### Inverting images
//! A common manipulation method would be inverting every pixel in the image. To do this, there are
//! two methods which you can use:
//!
//! - [`invert`][Image::invert]: Inverts the image in-place
//! - [`inverted`][Image::inverted]: Consumes the image and returns a new image with the inverted pixels
//!
//! A common pattern you'll see in this crate is that many methods have an in-place method and a
//! not-in-place counterpart, in which the former can be useful for method chaining. One usually does
//! not have any memory or performance benefits than the other.
//!
//! Anyhow, here's how you'd invert an image:
//!
//! ```no_run
//! # use ril::prelude::*;
//! # fn main() -> ril::Result<()> {
//! let mut image = Image::new(256, 256, Rgb::new(255, 0, 0));
//! image.invert();
//! image.save_inferred("output.png")?;
//! # Ok(()) }
//! ```
//!
//! `(255, 0, 0)` (red) inverts to `(0, 255, 255)` (cyan), so that should be the color of the
//! output image.
//!
//! We can also use the [`std::ops::Not`] trait to invert an image:
//!
//! ```no_run
//! # use ril::prelude::*;
//! # fn main() -> ril::Result<()> {
//! let image = Image::new(256, 256, Rgb::new(255, 0, 0));
//! (!image).save_inferred("output.png")?;
//! # Ok(()) }
//! ```
//!
//! Seems to be a bit cleaner than the first way, but it really just comes down to preference...
//! and whether or not you have ownership of the image object; you likely want to stay away from
//! cloning images for no benefit as it is a very expensive operation.
//!
//! TODO: finish guide
inline_doc!
/// The crate prelude exports. Importing this with a wildcard will import most items from RIL that
/// can be useful for image processing, along with bringing crucial traits into scope.
///
/// # Example
/// ```no_run
/// use ril::prelude::*;
///
/// // Prelude imported Image and Rgb
/// let image = Image::new(100, 100, Rgb::new(255, 0, 0));
/// // Prelude imported the Banded trait
/// let (r, g, b) = image.bands();
/// ```