Skip to content

Commit

Permalink
implement linear gradients
Browse files Browse the repository at this point in the history
  • Loading branch information
jay3332 committed Dec 14, 2022
2 parents dbe1048 + 9bd492a commit ebcef8b
Show file tree
Hide file tree
Showing 13 changed files with 828 additions and 136 deletions.
61 changes: 61 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,67 @@ of v0.5, therefore all changes logged prior to v0.5 may not be accurate and are

Versions prior to v0.5 are not tagged/released on GitHub.

## v0.9 (2022-12-13)
### Breaking changes
- `Pixel::force_into_rgb[a]` method is now replaced with `Pixel::as_rgb[a]`, which also takes self by reference instead
of by value.
- All provided `Draw` objects (but not the `Draw` trait itself) are now generic over `F: IntoFill` instead of `P: Pixel`
- The trait `IntoFill` is explained below
- There should be no change in usage because for any `P: Pixel`, `P` is implemented for `IntoFill`
- If you are extracting the fill color from a `Draw` object, you will need to access the `.color()` method on
the `SolidColor` struct. It is a `const fn`.
- The `Draw` trait is still generic over `P: Pixel`, no changes there

### Other changes
- `ColorType::is_dynamic` is now a `const fn`
- Add `ColorType::has_alpha` for whether the color type has an alpha channel
- Add new `Fill` trait, used to represent a fill color (or gradient, see below) for a `Draw` object. This replaces the
simple `Pixel` trait previously used for this purpose.
- Add new `IntoFill` trait, which provides a way to convert anything to a `Fill` object
- Associated type `<_ as IntoFill>::Pixel` is the pixel type of the fill.
- Associated type `<_ as IntoFill>::Fill` is the actual fill type.
- `IntoFill` is implemented for all `P: Pixel` and turns into `draw::SolidColor<P>`
- `IntoFill` is implemented for `LinearGradient` (see below) and turns into `gradient::LinearGradientFill<P>`
- Add support for gradients
- Enabled with the `gradient` feature, which is enabled by default
- New `LinearGradient` struct, which represents a linear gradient
- `LinearGradientBlendMode` and `LinearGradientInterpolation` enums are re-exports from the `colorgrad` crate,
which is used to configure the gradient's blending mode and interpolation.
- Add `Polygon::regular` method, which creates a regular polygon with the given amount of sides, center, and radius
- This uses the `Polygon::regular_rotated` method, which is the same method, but you are able to specify the rotation
of the polygon in radians.

### Linear gradient example
```rust
use ril::prelude::*;

fn main() -> ril::Result<()> {
// Create a new 256x256 RGB image with a black background
let mut image = Image::new(256, 256, Rgb::black());
// Create the `LinearGradient` object
let gradient = LinearGradient::new()
// The gradient will be rotated 45 degrees
.with_angle_degrees(45.0)
// The first stop is at 0.0, and is red
.with_color(Rgb::new(255, 0, 0))
// The second stop is at 0.5, and is white
.with_color(Rgb::new(255, 255, 255))
// We can also specify color stop positions manually:
// .with_color_at(0.5, Rgb::new(255, 255, 255))
// ...
// The third stop is at 1.0, and is green
.with_color(Rgb::new(0, 255, 0));

// Fill a hexagon with the gradient and draw it to the image
image.draw(&Polygon::regular(6, image.center(), 64).with_fill(gradient));
// Save the image to a PNG file
image.save_inferred("gradient_output.png")
}
```

#### Output
![image](https://user-images.githubusercontent.com/40323796/207496707-11541d75-d491-4061-88be-112813b86498.png)

## v0.8 (2022-11-30)
### Breaking changes
- `Paste` draw struct now stores images and masks by reference instead of by value. This is to prevent
Expand Down
6 changes: 4 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "ril"
authors = ["jay3332"]
version = "0.8.0"
version = "0.9.0"
license = "MIT"
edition = "2021"
description = "Rust Imaging Library: A performant and high-level image processing crate for Rust"
Expand All @@ -21,9 +21,10 @@ gif = { version = "^0.12", optional = true }
libwebp-sys2 = { version = "^0.1", features = ["1_2", "mux", "demux"], optional = true }
fontdue = { version = "^0.7", optional = true }
color_quant = { version = "^1.1", optional = true }
colorgrad = { version = "^0.6", optional = true, default_features = false }

[features]
default = ["resize", "text", "quantize"]
default = ["resize", "text", "quantize", "gradient"]
all-pure = ["resize", "png", "jpeg", "gif", "text", "quantize"]
all = ["all-pure", "webp"]
png = ["dep:png"]
Expand All @@ -33,6 +34,7 @@ webp = ["dep:libwebp-sys2"]
resize = ["dep:fast_image_resize"]
text = ["dep:fontdue"]
quantize = ["dep:color_quant"]
gradient = ["dep:colorgrad"]
static = ["libwebp-sys2?/static"]

[dev-dependencies]
Expand Down
25 changes: 19 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,18 @@ Or, you can run `cargo add ril --features=all` if you have Rust 1.62.0 or newer.
The above enables all features. See [Cargo Features](#cargo-features) for more information on how you can
tune these features to reduce dependencies.

### Linking errors on Windows
If you get errors regarding `link.exe` on Windows, this is because `libwebp` has problems linking with Windows for now.

This will be resolved when WebP encoders/decoders are rewritten in pure Rust. For now, you can use switch out the
`all` feature with `all-pure`:

```toml
ril = { version = "0", features = ["all-pure"] }
```

This will hopefully resolve the linking errors, at the cost of not having WebP support.

## Benchmarks

### Decode GIF + Invert each frame + Encode GIF (600x600, 77 frames)
Expand Down Expand Up @@ -114,12 +126,13 @@ For every image encoding that requires a dependency, a corresponding feature can

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 |
| Enable all features,<br/> including all encoding features | `all` | | no |
| 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 (excludes `nightly` feature) | `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
Expand Down
Loading

0 comments on commit ebcef8b

Please sign in to comment.