From 08af03380c9a8b634ec5d376c1631b84b464e427 Mon Sep 17 00:00:00 2001 From: Jean-Loup Beaussart Date: Mon, 4 Nov 2024 00:24:20 +0100 Subject: [PATCH] Display test photo with automatic resize --- Cargo.toml | 3 ++- examples/ferris.png | 3 --- examples/test.jpg | 3 +++ src/dimensions.rs | 53 +++++++++++++++++++++++++++++++++++++++++ src/main.rs | 57 +++++++++++++++++++++++++++++++++++++++++---- 5 files changed, 111 insertions(+), 8 deletions(-) delete mode 100755 examples/ferris.png create mode 100755 examples/test.jpg create mode 100644 src/dimensions.rs diff --git a/Cargo.toml b/Cargo.toml index 83b4660..42fbb5a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,4 +4,5 @@ version = "0.1.0" edition = "2021" [dependencies] -macroquad = "0.4.13" +image = "0.25.4" +macroquad = { version = "0.4.13" } diff --git a/examples/ferris.png b/examples/ferris.png deleted file mode 100755 index 88e9d52..0000000 --- a/examples/ferris.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bede91fb9164a251e4ecfba29935e954e102f88a156a98f6aa8640b536bfe035 -size 33061 diff --git a/examples/test.jpg b/examples/test.jpg new file mode 100755 index 0000000..c3dcc00 --- /dev/null +++ b/examples/test.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7854923d5985c6199dfa033793598d228b91c12acb54b957922bb6f5bf76f413 +size 1861675 diff --git a/src/dimensions.rs b/src/dimensions.rs new file mode 100644 index 0000000..332ae78 --- /dev/null +++ b/src/dimensions.rs @@ -0,0 +1,53 @@ +#[derive(Debug, Clone, Copy)] +pub struct Dimensions { + pub width: u32, + pub height: u32, +} + +impl Dimensions { + pub fn new(width: u32, height: u32) -> Self { + Self { width, height } + } + + pub fn aspect_ratio(&self) -> f32 { + self.width as f32 / self.height as f32 + } +} + +/// Calculates the dimensions to resize an image to fill the screen while preserving aspect ratio. +/// The image will be scaled to fit the screen without cropping. +/// +/// # Arguments +/// +/// * `screen` - The dimensions of the screen +/// * `image` - The original dimensions of the image +/// +/// # Returns +/// +/// * `Dimensions` - The new dimensions that will fit the screen +/// +/// # Example +/// +/// ```rust +/// let screen = Dimensions::new(1920, 1080); +/// let image = Dimensions::new(3000, 2000); +/// let new_size = calculate_resize_dimensions(screen, image); +/// ``` +pub fn calculate_resize_dimensions(screen: Dimensions, image: Dimensions) -> Dimensions { + let screen_ratio = screen.aspect_ratio(); + let image_ratio = image.aspect_ratio(); + + if image_ratio > screen_ratio { + // Image is wider relative to its height than the screen + // Scale based on width + let new_width = screen.width; + let new_height = (screen.width as f32 / image_ratio).round() as u32; + Dimensions::new(new_width, new_height) + } else { + // Image is taller relative to its width than the screen + // Scale based on height + let new_height = screen.height; + let new_width = (screen.height as f32 * image_ratio).round() as u32; + Dimensions::new(new_width, new_height) + } +} diff --git a/src/main.rs b/src/main.rs index e1a8292..bdc686b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,12 +1,61 @@ +use dimensions::{calculate_resize_dimensions, Dimensions}; +use image::ImageReader; use macroquad::prelude::*; -#[macroquad::main("Texture")] +mod dimensions; + +fn window_conf() -> Conf { + Conf { + window_title: String::from("Photo"), + window_width: 2560, + window_height: 1440, + fullscreen: true, + ..Default::default() + } +} + +fn display_image(texture: &Texture2D) { + let screen_width = screen_width(); + let screen_height = screen_height(); + draw_texture( + &texture, + clamp(screen_width - texture.width(), 0.0f32, screen_width) / 2.0f32, + clamp(screen_height - texture.height(), 0.0f32, screen_height) / 2.0f32, + WHITE, + ); +} + +#[macroquad::main(window_conf)] async fn main() { - let texture: Texture2D = load_texture("examples/ferris.png").await.unwrap(); + show_mouse(false); + let image = ImageReader::open("examples/test.jpg") + .unwrap() + .decode() + .unwrap(); + + let screen_dim = Dimensions::new(screen_width() as u32, screen_height() as u32); + let image_dim = Dimensions::new(image.width(), image.height()); + + let new_dim = calculate_resize_dimensions(screen_dim, image_dim); + let image = image.resize( + new_dim.width, + new_dim.height, + image::imageops::FilterType::Lanczos3, + ); + + let texture = Texture2D::from_rgba8( + image.width().try_into().unwrap(), + image.height().try_into().unwrap(), + &image.into_rgba8().to_vec(), + ); loop { - clear_background(LIGHTGRAY); - draw_texture(&texture, 0., 0., WHITE); + clear_background(BLACK); + if is_quit_requested() || is_key_released(KeyCode::Escape) { + break; + } + + display_image(&texture); next_frame().await } }