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}"), ]) .path(); 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(imgref::Img::new( pixels.as_rgba(), image.width() as usize, image.height() as usize, ))?; info!("transcode finished"); File::create(&path)?.write_all(&encoded.avif_file)?; } Ok(path) }