From d7b58f9be34a74cc4b0c486f8ca4c99985dda302 Mon Sep 17 00:00:00 2001 From: Anatoly Bazarov Date: Mon, 3 Apr 2023 13:58:50 -0700 Subject: [PATCH] add ansi24 mode --- README.md | 8 ++++---- src/draw.rs | 40 +++++++++++++++++++++++++++++++++++++--- src/main.rs | 3 ++- 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 99c5b9e..ed49fca 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ -# img2irc (0.1.0) -![EVA Loader](https://i.imgur.com/wLyj1HH.png) +# img2irc (0.2.0) +![img2irc preview](https://i.imgur.com/oetHhMB.png) img2irc is a utility which converts images to halfblock irc/ansi art, with a lot of post-processing filters *halfblock* means that each row will contain two rows worth of pixels, effectively doubling the resolution -the `irc` mode has 99 colours, the `ansi` mode has 256 +the `irc` mode has 99 colours, the `ansi` mode has 256, `ansi24` has 65536 ## usage @@ -14,7 +14,7 @@ the `irc` mode has 99 colours, the `ansi` mode has 256 | option | description | default value | | ------ | ----------- | ------------- | | `` | image url or file path | none | -| `-r, --render ` | render type (irc, ansi) | irc | +| `-r, --render ` | render type (irc, ansi, ansi24) | irc | | `-w, --width ` | output image width in columns | 50 | | `-b, --brightness=` | adjust brightness (-255 to 255) | 0 | | `-H, --hue=` | adjust hue (-180 to 180) | 0 | diff --git a/src/draw.rs b/src/draw.rs index 70ebcdb..866f6f7 100644 --- a/src/draw.rs +++ b/src/draw.rs @@ -40,7 +40,7 @@ impl AnsiImage { pub fn new(image: PhotonImage) -> AnsiImage { let mut bitmap = image.get_raw_pixels() .chunks(4) - .map(|x| make_rgb(x.to_vec())) + .map(|x| make_rgb_u32(x.to_vec())) .collect::>() .chunks(image.get_width() as usize) .map(|x| x.to_vec()) @@ -60,7 +60,16 @@ impl AnsiImage { } } -pub fn make_rgb(rgb: Vec) -> u32 { +pub fn make_rgb_u8(rgb: u32) -> [u8; 3] { + // convert u32 to r,g,b + let r = (rgb >> 16) as u8; + let g = (rgb >> 8) as u8; + let b = rgb as u8; + + return [r, g, b] +} + +pub fn make_rgb_u32(rgb: Vec) -> u32 { let r = *rgb.get(0).unwrap() as u32; let g = *rgb.get(1).unwrap() as u32; let b = *rgb.get(2).unwrap() as u32; @@ -105,12 +114,37 @@ pub fn halfblock_bitmap(bitmap: &Vec>) -> Vec> { ansi_canvas } -pub fn ansi_draw(image: AnsiImage) -> String { +pub fn ansi_draw_24bit(image: AnsiImage) -> String { + let mut out: String = String::new(); + for row in image.halfblock { + for pixel_pair in row.iter() { + let fg = make_rgb_u8(pixel_pair.top.orig) + .to_vec() + .iter() + .map(|x| x.to_string()) + .collect::>(); + + let bg = make_rgb_u8(pixel_pair.bottom.orig) + .to_vec() + .iter() + .map(|x| x.to_string()) + .collect::>(); + + out.push_str(format!("\x1b[38;2;{}m\x1b[48;2;{}m{}", fg.join(";"), bg.join(";"), CHAR).as_str()); + } + out.push_str("\x1b[0m"); + out.push_str("\n"); + } + return out +} + +pub fn ansi_draw_8bit(image: AnsiImage) -> String { let mut out: String = String::new(); for row in image.halfblock { for pixel_pair in row.iter() { let fg = pixel_pair.top.ansi; let bg = pixel_pair.bottom.ansi; + out.push_str(format!("\x1b[38;5;{}m\x1b[48;5;{}m{}", fg, bg, CHAR).as_str()); } out.push_str("\x1b[0m"); diff --git a/src/main.rs b/src/main.rs index c3acb95..cc662d1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -26,7 +26,8 @@ async fn main() { None => println!("{}", draw::irc_draw(canvas).as_str()), Some(ref render) => match render.as_str() { "irc" => println!("{}", draw::irc_draw(canvas).as_str()), - "ansi" => println!("{}", draw::ansi_draw(canvas).as_str()), + "ansi" => println!("{}", draw::ansi_draw_8bit(canvas).as_str()), + "ansi24" => println!("{}", draw::ansi_draw_24bit(canvas).as_str()), _ => { eprintln!("Error: invalid render type"); exit(1);