diff --git a/components/imageproc/Cargo.toml b/components/imageproc/Cargo.toml index b45479783..5cebec79e 100644 --- a/components/imageproc/Cargo.toml +++ b/components/imageproc/Cargo.toml @@ -8,7 +8,7 @@ edition = "2018" lazy_static = "1" regex = "1.0" tera = "1" -image = "0.23" +image = { version = "0.23.13", features = ["avif"] } rayon = "1" errors = { path = "../errors" } diff --git a/components/imageproc/src/lib.rs b/components/imageproc/src/lib.rs index 0b0a8b48f..c10a929dc 100644 --- a/components/imageproc/src/lib.rs +++ b/components/imageproc/src/lib.rs @@ -5,7 +5,7 @@ use std::fs::{self, File}; use std::hash::{Hash, Hasher}; use std::path::{Path, PathBuf}; -use image::imageops::FilterType; +use image::{avif::AvifEncoder, imageops::FilterType, ColorType}; use image::{GenericImageView, ImageOutputFormat}; use lazy_static::lazy_static; use rayon::prelude::*; @@ -140,6 +140,8 @@ pub enum Format { Jpeg(u8), /// PNG Png, + /// AVIF + Avif(u8), } impl Format { @@ -156,6 +158,7 @@ impl Format { }, "jpeg" | "jpg" => Ok(Jpeg(quality)), "png" => Ok(Png), + "avif" => Ok(Avif(quality)), _ => Err(format!("Invalid image format: {}", format).into()), } } @@ -182,6 +185,7 @@ impl Format { match *self { Png => "png", Jpeg(_) => "jpg", + Avif(_) => "avif", } } } @@ -194,6 +198,7 @@ impl Hash for Format { let q = match *self { Png => 0, Jpeg(q) => q, + Avif(q) => 101 + q, }; hasher.write_u8(q); @@ -303,6 +308,16 @@ impl ImageOp { Format::Jpeg(q) => { img.write_to(&mut f, ImageOutputFormat::Jpeg(q))?; } + Format::Avif(q) => { + let mut avif: Vec = Vec::new(); + AvifEncoder::new_with_speed_quality(&mut avif, 1, q).write_image( + &img.as_bytes(), + img.dimensions().0, + img.dimensions().1, + ColorType::Rgb8, + )?; + std::io::Write::write_all(&mut f, &avif)?; + } } Ok(()) diff --git a/docs/content/documentation/content/image-processing/index.md b/docs/content/documentation/content/image-processing/index.md index bd860c378..8e9e64ced 100644 --- a/docs/content/documentation/content/image-processing/index.md +++ b/docs/content/documentation/content/image-processing/index.md @@ -28,10 +28,11 @@ resize_image(path, width, height, op, format, quality) - `"auto"` - `"jpg"` - `"png"` + - `"avif"` The default is `"auto"`, this means that the format is chosen based on input image format. JPEG is chosen for JPEGs and other lossy formats, and PNG is chosen for PNGs and other lossless formats. -- `quality` (_optional_): JPEG quality of the resized image, in percent. Only used when encoding JPEGs; default value is `75`. +- `quality` (_optional_): Quality of the resized image, in percent. Only used when encoding JPEGs or AVIFs; default value is `75`. ### Image processing and return value