Add scaling mode "Fill"
- Image covers the entire screen - Aspect ratio preserved - Excess image cropped (centered)
This commit is contained in:
parent
f95ff94dfc
commit
84186d3d66
@ -1,11 +1,11 @@
|
||||
use anyhow::Result;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::{args, config};
|
||||
use crate::{args, config, wallpaper};
|
||||
|
||||
pub struct WallpaperSettings {
|
||||
pub path: PathBuf,
|
||||
pub mode: crate::wallpaper::ScalingMode,
|
||||
pub mode: wallpaper::ScalingMode,
|
||||
}
|
||||
|
||||
pub fn resolve_wallpaper(
|
||||
@ -50,7 +50,8 @@ pub fn resolve_wallpaper(
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let mode = crate::wallpaper::ScalingMode::Stretch; // Default for now. Fix later
|
||||
//let mode = wallpaper::ScalingMode::Stretch; //
|
||||
let mode = wallpaper::ScalingMode::Fill; // Default
|
||||
|
||||
Ok(WallpaperSettings { path, mode })
|
||||
}
|
||||
|
||||
@ -4,12 +4,11 @@ use std::path::Path;
|
||||
|
||||
/// Supported wallpaper scaling modes.
|
||||
///
|
||||
/// Only `Stretch` is implemented for now.
|
||||
/// Others are defined so the public API does not need to change later.
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum ScalingMode {
|
||||
Stretch,
|
||||
// Fill,
|
||||
Fill,
|
||||
// Fit,
|
||||
}
|
||||
|
||||
@ -38,6 +37,40 @@ fn rgba_to_bgra(mut pixels: Vec<u8>) -> Vec<u8> {
|
||||
pixels
|
||||
}
|
||||
|
||||
/// Fill mode:
|
||||
/// - Image covers the entire screen
|
||||
/// - Aspect ratio is preserved
|
||||
/// - Excess image is cropped (centered)
|
||||
fn prepare_fill(img: &RgbaImage, screen_width: u32, screen_height: u32) -> PreparedWallpaper {
|
||||
let img_w = img.width() as f32;
|
||||
let img_h = img.height() as f32;
|
||||
|
||||
let screen_w = screen_width as f32;
|
||||
let screen_h = screen_height as f32;
|
||||
|
||||
// Scale so that BOTH dimensions cover the screen
|
||||
let scale = (screen_w / img_w).max(screen_h / img_h);
|
||||
|
||||
let scaled_w = (img_w * scale).round() as u32;
|
||||
let scaled_h = (img_h * scale).round() as u32;
|
||||
|
||||
let resized = imageops::resize(img, scaled_w, scaled_h, imageops::FilterType::Lanczos3);
|
||||
|
||||
// Center the image; negative offsets cause cropping
|
||||
let offset_x = (screen_width as i32 - scaled_w as i32) / 2;
|
||||
let offset_y = (screen_height as i32 - scaled_h as i32) / 2;
|
||||
|
||||
let pixels = rgba_to_bgra(resized.into_raw());
|
||||
|
||||
PreparedWallpaper {
|
||||
pixels,
|
||||
width: scaled_w,
|
||||
height: scaled_h,
|
||||
offset_x,
|
||||
offset_y,
|
||||
}
|
||||
}
|
||||
|
||||
/// Stretch mode:
|
||||
/// - Image is resized to exactly match screen dimensions
|
||||
/// - Aspect ratio is not preserved
|
||||
@ -85,6 +118,7 @@ pub fn prepare_wallpaper(
|
||||
|
||||
let prepared = match mode {
|
||||
ScalingMode::Stretch => prepare_stretch(&img, screen_width, screen_height),
|
||||
ScalingMode::Fill => prepare_fill(&img, screen_width, screen_height),
|
||||
};
|
||||
|
||||
Ok(prepared)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user