Skip to content

Commit

Permalink
Merge pull request #1 from elasticrash/bigger_images
Browse files Browse the repository at this point in the history
Bigger images
  • Loading branch information
elasticrash authored Jun 6, 2023
2 parents 5a2fc9c + ddda53d commit 8a4decd
Show file tree
Hide file tree
Showing 3 changed files with 204 additions and 139 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -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
Expand Down
339 changes: 202 additions & 137 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,162 +3,227 @@ use std::env;
use yansi::Paint;

#[derive(Debug)]
enum MatchDimension {
BBh,
BS,
SB,
BBw,
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<String> = 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 <filename> <logging>");
}
}
}

fn draw(filename: &str, extended_logging: bool) {
let vip_char = '█';

let img = image::open(filename).unwrap();

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
};

match scaler.0 {
MatchDimension::BBh => {
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));
}
}
for y in 0..ps.height {
if y % 2 == 0 {
continue;
}
MatchDimension::BS => {
let ratio: f32 = image_width as f32 / term_width as f32;

for y in 0..(term_width as f32 * scaler.3) as u32 {
if y % 2 == 0 {
continue;
}
for x in 0..term_width 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!();
}

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));
}
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!();
}
println!();
}
}

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,
};

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,
};
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)
};
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)
};
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 {
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
};
if exlog {
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, 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
}
);
}
}

0 comments on commit 8a4decd

Please sign in to comment.