From 74657ec046d53ade9aaefe6387ce879485f5c2bd Mon Sep 17 00:00:00 2001 From: stefanos kouroupis Date: Tue, 6 Jun 2023 00:00:07 +0100 Subject: [PATCH 1/2] a better approach to generate bigger images --- src/main.rs | 163 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 104 insertions(+), 59 deletions(-) diff --git a/src/main.rs b/src/main.rs index faac07f..1316835 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,6 +10,20 @@ enum MatchDimension { BBw, } +#[derive(Debug)] +pub struct View { + term_width: u32, + term_height: u32, + image_width: u32, + image_height: u32, +} + +#[derive(Debug, PartialEq)] +pub struct PrintSize { + width: u32, + height: u32, +} + fn main() { let args: Vec = env::args().collect(); let filename = &args[1]; @@ -27,7 +41,7 @@ fn main() { term_height, image_width as f32 / image_height as f32, ) - } else if image_height < image_width && term_height > term_width { + } else if image_height < image_width && term_height > term_width { ( MatchDimension::BS, image_width, @@ -52,16 +66,23 @@ fn main() { panic!("Something went wrong") }; + let ps = size(View { + term_width: term_width as u32, + term_height: term_height as u32, + image_width: image_width as u32, + image_height: image_height as u32, + }); + match scaler.0 { - MatchDimension::BBh => { - let ratio: f32 = image_height as f32 / term_height as f32; + MatchDimension::BBh | MatchDimension::SB => { + let ratio: f32 = image_height as f32 / term_height as f32; - for y in 0..term_height as u32 { + for y in 0..ps.height { if y % 2 == 0 { continue; } - for x in 0..(term_height as f32 * scaler.3) as u32 { + for x in 0..ps.width { let new_x = (x as f32 * ratio) as u32; let new_y = (y as f32 * ratio) as u32; @@ -81,14 +102,14 @@ fn main() { } } } - MatchDimension::BS => { - let ratio: f32 = image_width as f32 / term_width as f32; + MatchDimension::BS | MatchDimension::BBw => { + let ratio: f32 = image_width as f32 / term_width as f32; - for y in 0..(term_width as f32 * scaler.3) as u32 { + for y in 0..ps.height { if y % 2 == 0 { continue; } - for x in 0..term_width as u32 { + for x in 0..ps.width { let new_x = (x as f32 * ratio) as u32; let new_y = (y as f32 * ratio) as u32; let x_d = if new_x < img.dimensions().0 { @@ -107,58 +128,82 @@ fn main() { println!(); } } - MatchDimension::SB => { - let ratio: f32 = image_height as f32 / term_height as f32; - - for y in 0..term_height as u32 { - if y % 2 == 0 { - continue; - } + } +} - for x in 0..(term_height as f32 * scaler.3) as u32 { - let new_x = (x as f32 * ratio) as u32; - let new_y = (y as f32 * ratio) as u32; - let x_d = if new_x < img.dimensions().0 { - new_x - } else { - img.dimensions().0 - 1 - }; - let y_d = if new_y < img.dimensions().1 { - new_y - } else { - img.dimensions().1 - 1 - }; - let pixel = img.get_pixel(x_d, y_d); - print!("{}", Paint::rgb(pixel[0], pixel[1], pixel[2], vip_char)); - } - println!(); - } +fn size(view: View) -> PrintSize { + println!("TERMINAL: {:?} {:?}", view.term_width, view.term_height); + println!("IMAGE: {:?} {:?}", view.image_width, view.image_height); + let new_width = (view.image_width as f32 / view.image_height as f32) * view.term_height as f32; + let size_a = PrintSize { + width: new_width as u32, + height: view.term_height, + }; + println!("PSIZE A: {:?}", size_a); + + let new_height = (view.image_height as f32 / view.image_width as f32) * view.term_width as f32; + + let size_b = PrintSize { + width: view.term_width, + height: new_height as u32, + }; + + println!("PSIZE B: {:?}", size_b); + + // get bigger + let comparison = if size_a.width > size_b.width && size_a.height > size_b.height { + (size_a, size_b) + } else { + (size_b, size_a) + }; + + println!("BIGGER: {:?}", comparison); + + // if it doesnt fit get smaller + let fit = if comparison.0.width > view.term_width || comparison.0.height > view.term_height { + (comparison.1, comparison.0) + } else { + (comparison.0, comparison.1) + }; + + println!("FIT: {:?}", fit); + + // check if smaller can fit twice + let double_fit = if fit.0.width * 2 <= view.term_width && fit.0.height <= view.term_height { + PrintSize { + width: fit.0.width * 2, + height: fit.0.height * 2, } - MatchDimension::BBw => { - let ratio: f32 = image_height as f32 / term_height as f32; - - for y in 0..(term_height as f32 * scaler.3) as u32 { - if y % 2 == 0 { - continue; - } - for x in 0..term_height as u32 { - let new_x = (x as f32 * ratio) as u32; - let new_y = (y as f32 * ratio) as u32; - let x_d = if new_x < img.dimensions().0 { - new_x - } else { - img.dimensions().0 - 1 - }; - let y_d = if new_y < img.dimensions().1 { - new_y - } else { - img.dimensions().1 - 1 - }; - let pixel = img.get_pixel(x_d, y_d); - print!("{}", Paint::rgb(pixel[0], pixel[1], pixel[2], vip_char)); - } - println!(); + } else { + fit.0 + }; + + println!("DOUBLE: {:?}", double_fit); + + double_fit +} + +#[cfg(test)] +mod tests { + use crate::size; + use crate::PrintSize; + use crate::View; + #[test] + fn test_size_wide_terminal_wide_image() { + let view = View { + term_width: 200, + term_height: 50, + image_width: 1000, + image_height: 800, + }; + + println!("view: {:?}", view); + assert_eq!( + size(view), + PrintSize { + width: 124, + height: 100 } - } + ); } } From ddda53d21cfe3dcb67d9e8fcbf13774142814ca5 Mon Sep 17 00:00:00 2001 From: Stefanos Kouroupis Date: Tue, 6 Jun 2023 10:01:04 +0100 Subject: [PATCH 2/2] refactor, bigger more correct sizes --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/main.rs | 246 ++++++++++++++++++++++++++++------------------------ 3 files changed, 135 insertions(+), 115 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4e7c255..1d86f08 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -262,7 +262,7 @@ dependencies = [ [[package]] name = "image-peek" -version = "0.1.0" +version = "0.1.1" dependencies = [ "image", "termsize", diff --git a/Cargo.toml b/Cargo.toml index ba52df6..432ba08 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "image-peek" -version = "0.1.0" +version = "0.1.1" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/src/main.rs b/src/main.rs index 1316835..730ffb1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,14 +2,6 @@ use image::GenericImageView; use std::env; use yansi::Paint; -#[derive(Debug)] -enum MatchDimension { - BBh, - BS, - SB, - BBw, -} - #[derive(Debug)] pub struct View { term_width: u32, @@ -26,7 +18,25 @@ pub struct PrintSize { fn main() { let args: Vec = env::args().collect(); - let filename = &args[1]; + + match args.len() { + 2 => { + let filename = &args[1]; + draw(filename, false); + } + 3 => { + let filename = &args[1]; + let extended_logging_arg = &args[2]; + let extended_logging = extended_logging_arg == "true"; + draw(filename, extended_logging); + } + _ => { + println!("Usage: image-peek "); + } + } +} + +fn draw(filename: &str, extended_logging: bool) { let vip_char = '█'; let img = image::open(filename).unwrap(); @@ -34,140 +44,93 @@ fn main() { let (term_height, term_width) = termsize::get().map(|size| (size.rows, size.cols)).unwrap(); let (image_width, image_height) = img.dimensions(); - let scaler = if image_height > image_width && term_height > term_width { - ( - MatchDimension::BBh, - image_height, - term_height, - image_width as f32 / image_height as f32, - ) - } else if image_height < image_width && term_height > term_width { - ( - MatchDimension::BS, + let ps = size( + View { + term_width: term_width as u32, + term_height: term_height as u32, image_width, - term_height, - image_height as f32 / image_width as f32, - ) - } else if image_height > image_width && term_height < term_width { - ( - MatchDimension::SB, image_height, - term_width, - image_width as f32 / image_height as f32, - ) - } else if image_height < image_width && term_height < term_width { - ( - MatchDimension::BBw, - image_width, - term_width, - image_height as f32 / image_width as f32, - ) + }, + extended_logging, + ); + + let ratio = if ps.width > ps.height { + image_width as f32 / ps.width as f32 } else { - panic!("Something went wrong") + image_height as f32 / ps.height as f32 }; - let ps = size(View { - term_width: term_width as u32, - term_height: term_height as u32, - image_width: image_width as u32, - image_height: image_height as u32, - }); - - match scaler.0 { - MatchDimension::BBh | MatchDimension::SB => { - let ratio: f32 = image_height as f32 / term_height as f32; - - for y in 0..ps.height { - if y % 2 == 0 { - continue; - } - - for x in 0..ps.width { - let new_x = (x as f32 * ratio) as u32; - let new_y = (y as f32 * ratio) as u32; - - let x_d = if new_x < img.dimensions().0 { - new_x - } else { - img.dimensions().0 - 1 - }; - let y_d = if new_y < img.dimensions().1 { - new_y - } else { - img.dimensions().1 - 1 - }; - - let pixel = img.get_pixel(x_d, y_d); - print!("{}", Paint::rgb(pixel[0], pixel[1], pixel[2], vip_char)); - } - } + for y in 0..ps.height { + if y % 2 == 0 { + continue; } - MatchDimension::BS | MatchDimension::BBw => { - let ratio: f32 = image_width as f32 / term_width as f32; - - for y in 0..ps.height { - if y % 2 == 0 { - continue; - } - for x in 0..ps.width { - let new_x = (x as f32 * ratio) as u32; - let new_y = (y as f32 * ratio) as u32; - let x_d = if new_x < img.dimensions().0 { - new_x - } else { - img.dimensions().0 - 1 - }; - let y_d = if new_y < img.dimensions().1 { - new_y - } else { - img.dimensions().1 - 1 - }; - let pixel = img.get_pixel(x_d, y_d); - print!("{}", Paint::rgb(pixel[0], pixel[1], pixel[2], vip_char)); - } - println!(); - } + + for x in 0..ps.width { + let new_x = (x as f32 * ratio) as u32; + let new_y = (y as f32 * ratio) as u32; + + let x_d = if new_x < img.dimensions().0 { + new_x + } else { + img.dimensions().0 - 1 + }; + let y_d = if new_y < img.dimensions().1 { + new_y + } else { + img.dimensions().1 - 1 + }; + + let pixel = img.get_pixel(x_d, y_d); + print!("{}", Paint::rgb(pixel[0], pixel[1], pixel[2], vip_char)); } + println!(); } } -fn size(view: View) -> PrintSize { - println!("TERMINAL: {:?} {:?}", view.term_width, view.term_height); - println!("IMAGE: {:?} {:?}", view.image_width, view.image_height); +fn size(view: View, exlog: bool) -> PrintSize { + if exlog { + println!("TERMINAL: {:?} {:?}", view.term_width, view.term_height); + println!( + "IMAGE: {:?} {:?}", + view.image_width, view.image_height + ); + } let new_width = (view.image_width as f32 / view.image_height as f32) * view.term_height as f32; let size_a = PrintSize { width: new_width as u32, height: view.term_height, }; - println!("PSIZE A: {:?}", size_a); + if exlog { + println!("PSIZE A: {size_a:?}"); + } let new_height = (view.image_height as f32 / view.image_width as f32) * view.term_width as f32; let size_b = PrintSize { width: view.term_width, height: new_height as u32, }; - - println!("PSIZE B: {:?}", size_b); - + if exlog { + println!("PSIZE B: {size_b:?}"); + } // get bigger let comparison = if size_a.width > size_b.width && size_a.height > size_b.height { (size_a, size_b) } else { (size_b, size_a) }; - - println!("BIGGER: {:?}", comparison); - + if exlog { + println!("BIGGER: {comparison:?}"); + } // if it doesnt fit get smaller let fit = if comparison.0.width > view.term_width || comparison.0.height > view.term_height { (comparison.1, comparison.0) } else { (comparison.0, comparison.1) }; - - println!("FIT: {:?}", fit); - + if exlog { + println!("FIT: {fit:?}"); + } // check if smaller can fit twice let double_fit = if fit.0.width * 2 <= view.term_width && fit.0.height <= view.term_height { PrintSize { @@ -177,9 +140,9 @@ fn size(view: View) -> PrintSize { } else { fit.0 }; - - println!("DOUBLE: {:?}", double_fit); - + if exlog { + println!("DOUBLE: {double_fit:?}"); + } double_fit } @@ -199,11 +162,68 @@ mod tests { println!("view: {:?}", view); assert_eq!( - size(view), + size(view, true), PrintSize { width: 124, height: 100 } ); } + + #[test] + fn test_size_narrow_terminal_wide_image() { + let view = View { + term_width: 50, + term_height: 200, + image_width: 1000, + image_height: 800, + }; + + println!("view: {:?}", view); + assert_eq!( + size(view, true), + PrintSize { + width: 50, + height: 40 + } + ); + } + + #[test] + fn test_size_wide_terminal_narrow_image() { + let view = View { + term_width: 200, + term_height: 50, + image_width: 800, + image_height: 1000, + }; + + println!("view: {:?}", view); + assert_eq!( + size(view, true), + PrintSize { + width: 80, + height: 100 + } + ); + } + + #[test] + fn test_size_narrow_terminal_narrow_image() { + let view = View { + term_width: 50, + term_height: 200, + image_width: 800, + image_height: 1000, + }; + + println!("view: {:?}", view); + assert_eq!( + size(view, true), + PrintSize { + width: 50, + height: 62 + } + ); + } }