From c3c4734beb7b9650936b3c74df21d72a597cd94c Mon Sep 17 00:00:00 2001 From: metamuffin Date: Sun, 6 Aug 2023 13:52:09 +0200 Subject: transcode images --- transcoder/Cargo.toml | 5 +++++ transcoder/src/image.rs | 46 ++++++++++++++++++++++++++++++++++++++++++++++ transcoder/src/lib.rs | 1 + 3 files changed, 52 insertions(+) create mode 100644 transcoder/src/image.rs (limited to 'transcoder') diff --git a/transcoder/Cargo.toml b/transcoder/Cargo.toml index bfdbedf..6fe4f05 100644 --- a/transcoder/Cargo.toml +++ b/transcoder/Cargo.toml @@ -4,5 +4,10 @@ version = "0.1.0" edition = "2021" [dependencies] +jellycommon = { path = "../common" } +jellybase = { path = "../base" } log = "0.4.19" ravif = "0.11.2" +image = "0.24.6" +anyhow = "1.0.72" +rgb = "0.8.36" diff --git a/transcoder/src/image.rs b/transcoder/src/image.rs new file mode 100644 index 0000000..d721e7b --- /dev/null +++ b/transcoder/src/image.rs @@ -0,0 +1,46 @@ +use jellybase::{cache_file, AssetLocationExt}; +use jellycommon::AssetLocation; +use log::info; +use rgb::FromSlice; +use std::{ + fs::File, + io::{BufReader, Write}, + path::PathBuf, +}; + +pub fn transcode( + asset: AssetLocation, + quality: f32, + speed: u8, + width: usize, +) -> anyhow::Result { + let original_path = asset.path(); + let path = cache_file(&[ + original_path.as_os_str().to_str().unwrap(), + &format!("{width} {quality} {speed}"), + ]); + if !path.exists() { + info!("encoding {path:?} (speed={speed}, quality={quality}, width={width})"); + let reader = image::io::Reader::new(BufReader::new(File::open(original_path)?)) + .with_guessed_format()?; + let original = reader.decode()?.to_rgba8(); + let image = image::imageops::resize( + &original, + width as u32, + width as u32 * original.height() / original.width(), + image::imageops::FilterType::Lanczos3, + ); + let pixels = image.to_vec(); + let encoded = ravif::Encoder::new() + .with_speed(speed.clamp(1, 10)) + .with_quality(quality.clamp(1., 100.)) + .encode_rgba(ravif::Img::new( + pixels.as_rgba(), + image.width() as usize, + image.height() as usize, + ))?; + info!("writing to cache: {path:?}"); + File::create(&path)?.write_all(&encoded.avif_file)?; + } + Ok(path) +} diff --git a/transcoder/src/lib.rs b/transcoder/src/lib.rs index 6ddc2a4..e74a7f5 100644 --- a/transcoder/src/lib.rs +++ b/transcoder/src/lib.rs @@ -3,3 +3,4 @@ which is licensed under the GNU Affero General Public License (version 3); see /COPYING. Copyright (C) 2023 metamuffin */ +pub mod image; -- cgit v1.2.3-70-g09d2