fix: detect the preview image format from its contents

This commit is contained in:
elwrcl committed 2026-09-30 14:27:51 +03:00
1 parent 3624873f55
commit 0186cb55eb
2 files changed
+24 -4

No files matched your search

+1 -3
View File
@@ -341,9 +341,7 @@ fn handle(state: &mut State, id: u64, request: Request) -> Reply {
} }
fn add(state: &mut State, path: &Path, output_name: &str) -> Result<()> { fn add(state: &mut State, path: &Path, output_name: &str) -> Result<()> {
let image = image::open(path) let image = crate::thumbnail::load(path)?;
.with_context(|| format!("could not read {}", path.display()))?
.to_rgba8();
let outputs = state.output_list(); let outputs = state.output_list();
let output = outputs let output = outputs
.iter() .iter()
+23 -1
View File
@@ -1,6 +1,6 @@
//! One preview thumbnail: its layer surface, pixels, animation and gestures. //! One preview thumbnail: its layer surface, pixels, animation and gestures.
use std::path::PathBuf; use std::path::{Path, PathBuf};
use std::time::Instant; use std::time::Instant;
use anyhow::{Context, Result}; use anyhow::{Context, Result};
@@ -29,6 +29,18 @@ pub const NAMESPACE: &str = "valw-preview";
/// Premultiplied BGRA of the 1 px border: #e0e0e0 at 80% opacity. /// Premultiplied BGRA of the 1 px border: #e0e0e0 at 80% opacity.
const BORDER: [u8; 4] = [179, 179, 179, 204]; const BORDER: [u8; 4] = [179, 179, 179, 204];
/// Loads the screenshot a thumbnail shows. The format comes from the file's
/// contents, not its name: save.filename and -o needn't end in .png.
pub fn load(path: &Path) -> Result<RgbaImage> {
let read = || -> Result<RgbaImage> {
Ok(image::ImageReader::open(path)?
.with_guessed_format()?
.decode()?
.to_rgba8())
};
read().with_context(|| format!("could not read {}", path.display()))
}
/// The thumbnail image for `img` on an output with `scale` physical pixels /// The thumbnail image for `img` on an output with `scale` physical pixels
/// per logical pixel: returns the physical-size image and its logical size. /// per logical pixel: returns the physical-size image and its logical size.
pub fn downscale(img: &RgbaImage, scale: f64) -> (RgbaImage, (u32, u32)) { pub fn downscale(img: &RgbaImage, scale: f64) -> (RgbaImage, (u32, u32)) {
@@ -372,6 +384,16 @@ fn canvas_width(image_width: u32, scale: f64) -> u32 {
mod tests { mod tests {
use super::*; use super::*;
#[test]
fn loads_png_without_extension() {
// save.filename and -o don't have to end in .png; the bytes always are PNG.
let dir = tempfile::tempdir().unwrap();
let path = dir.path().join("shot");
let img = RgbaImage::from_pixel(3, 2, image::Rgba([1, 2, 3, 255]));
std::fs::write(&path, crate::output::encode_png(&img).unwrap()).unwrap();
assert_eq!(load(&path).unwrap(), img);
}
#[test] #[test]
fn downscale_fits_long_edge_at_scale_one() { fn downscale_fits_long_edge_at_scale_one() {
let img = RgbaImage::new(1920, 1080); let img = RgbaImage::new(1920, 1080);