mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
feat: add ICC profile to images for better color accuracy (#1808)
This commit is contained in:
parent
11c5f3fed4
commit
24a77d8a5f
1 changed files with 11 additions and 12 deletions
|
|
@ -11,7 +11,7 @@ pub struct Image;
|
||||||
|
|
||||||
impl Image {
|
impl Image {
|
||||||
pub async fn precache(path: &Path, cache: PathBuf) -> Result<()> {
|
pub async fn precache(path: &Path, cache: PathBuf) -> Result<()> {
|
||||||
let (mut img, orientation) = Self::decode_from(path).await?;
|
let (mut img, orientation, icc) = Self::decode_from(path).await?;
|
||||||
let (w, h) = Self::flip_size(orientation, (PREVIEW.max_width, PREVIEW.max_height));
|
let (w, h) = Self::flip_size(orientation, (PREVIEW.max_width, PREVIEW.max_height));
|
||||||
|
|
||||||
let buf = tokio::task::spawn_blocking(move || {
|
let buf = tokio::task::spawn_blocking(move || {
|
||||||
|
|
@ -25,15 +25,13 @@ impl Image {
|
||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
if img.color().has_alpha() {
|
if img.color().has_alpha() {
|
||||||
let rgba = img.into_rgba8();
|
let rgba = img.into_rgba8();
|
||||||
PngEncoder::new(&mut buf).write_image(
|
let mut encoder = PngEncoder::new(&mut buf);
|
||||||
&rgba,
|
icc.map(|b| encoder.set_icc_profile(b));
|
||||||
rgba.width(),
|
encoder.write_image(&rgba, rgba.width(), rgba.height(), ExtendedColorType::Rgba8)?;
|
||||||
rgba.height(),
|
|
||||||
ExtendedColorType::Rgba8,
|
|
||||||
)?;
|
|
||||||
} else {
|
} else {
|
||||||
JpegEncoder::new_with_quality(&mut buf, PREVIEW.image_quality)
|
let mut encoder = JpegEncoder::new_with_quality(&mut buf, PREVIEW.image_quality);
|
||||||
.encode_image(&img.into_rgb8())?;
|
icc.map(|b| encoder.set_icc_profile(b));
|
||||||
|
encoder.encode_image(&img.into_rgb8())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok::<_, ImageError>(buf)
|
Ok::<_, ImageError>(buf)
|
||||||
|
|
@ -44,7 +42,7 @@ impl Image {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) async fn downscale(path: &Path, rect: Rect) -> Result<DynamicImage> {
|
pub(super) async fn downscale(path: &Path, rect: Rect) -> Result<DynamicImage> {
|
||||||
let (mut img, orientation) = Self::decode_from(path).await?;
|
let (mut img, orientation, _) = Self::decode_from(path).await?;
|
||||||
let (w, h) = Self::flip_size(orientation, Self::max_pixel(rect));
|
let (w, h) = Self::flip_size(orientation, Self::max_pixel(rect));
|
||||||
|
|
||||||
// Fast path.
|
// Fast path.
|
||||||
|
|
@ -98,7 +96,7 @@ impl Image {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn decode_from(path: &Path) -> ImageResult<(DynamicImage, Orientation)> {
|
async fn decode_from(path: &Path) -> ImageResult<(DynamicImage, Orientation, Option<Vec<u8>>)> {
|
||||||
let mut limits = Limits::no_limits();
|
let mut limits = Limits::no_limits();
|
||||||
if TASKS.image_alloc > 0 {
|
if TASKS.image_alloc > 0 {
|
||||||
limits.max_alloc = Some(TASKS.image_alloc as u64);
|
limits.max_alloc = Some(TASKS.image_alloc as u64);
|
||||||
|
|
@ -117,8 +115,9 @@ impl Image {
|
||||||
|
|
||||||
let mut decoder = reader.with_guessed_format()?.into_decoder()?;
|
let mut decoder = reader.with_guessed_format()?.into_decoder()?;
|
||||||
let orientation = decoder.orientation().unwrap_or(Orientation::NoTransforms);
|
let orientation = decoder.orientation().unwrap_or(Orientation::NoTransforms);
|
||||||
|
let icc = decoder.icc_profile().unwrap_or_default();
|
||||||
|
|
||||||
Ok((DynamicImage::from_decoder(decoder)?, orientation))
|
Ok((DynamicImage::from_decoder(decoder)?, orientation, icc))
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
.map_err(|e| ImageError::IoError(e.into()))?
|
.map_err(|e| ImageError::IoError(e.into()))?
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue