mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-23 07:41:03 +00:00
57 lines
1.5 KiB
Rust
57 lines
1.5 KiB
Rust
use std::{path::Path, sync::Arc};
|
|
|
|
use anyhow::Result;
|
|
use config::PREVIEW;
|
|
use image::{imageops::FilterType, DynamicImage, ImageFormat};
|
|
use shared::Term;
|
|
use tokio::fs;
|
|
|
|
pub struct Image;
|
|
|
|
impl Image {
|
|
pub(super) async fn crop(path: &Path, size: (u16, u16)) -> Result<DynamicImage> {
|
|
let (w, h) = Term::ratio()
|
|
.map(|(w, h)| {
|
|
let (w, h) = ((size.0 as f64 * w) as u32, (size.1 as f64 * h) as u32);
|
|
(w.min(PREVIEW.max_width), h.min(PREVIEW.max_height))
|
|
})
|
|
.unwrap_or((PREVIEW.max_width, PREVIEW.max_height));
|
|
|
|
let img = fs::read(path).await?;
|
|
let img = tokio::task::spawn_blocking(move || -> Result<DynamicImage> {
|
|
let img = image::load_from_memory(&img)?;
|
|
Ok(if img.width() > w || img.height() > h {
|
|
img.resize(w, h, FilterType::Triangle)
|
|
} else {
|
|
img
|
|
})
|
|
});
|
|
|
|
img.await?
|
|
}
|
|
|
|
pub async fn precache(img: Arc<Vec<u8>>, cache: impl AsRef<Path>) -> Result<bool> {
|
|
let cache = cache.as_ref().to_owned();
|
|
let result = tokio::task::spawn_blocking(move || {
|
|
let img = image::load_from_memory(&img)?;
|
|
let (w, h) = (PREVIEW.max_width, PREVIEW.max_height);
|
|
|
|
if img.width() <= w && img.height() <= h {
|
|
return Ok(false);
|
|
}
|
|
|
|
img.resize(w, h, FilterType::Triangle).save_with_format(cache, ImageFormat::Jpeg)?;
|
|
Ok(true)
|
|
});
|
|
|
|
result.await?
|
|
}
|
|
|
|
#[inline]
|
|
pub async fn precache_anyway(img: Arc<Vec<u8>>, cache: impl AsRef<Path>) -> Result<()> {
|
|
Ok(match Self::precache(img.clone(), &cache).await {
|
|
Ok(true) => (),
|
|
_ => fs::write(cache, &*img).await?,
|
|
})
|
|
}
|
|
}
|