add ansi24 mode

This commit is contained in:
Anatoly Bazarov 2023-04-03 13:58:50 -07:00
parent 8c191f264e
commit d7b58f9be3
3 changed files with 43 additions and 8 deletions

View File

@ -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>` | image url or file path | none |
| `-r, --render <RENDER>` | render type (irc, ansi) | irc |
| `-r, --render <RENDER>` | render type (irc, ansi, ansi24) | irc |
| `-w, --width <WIDTH>` | output image width in columns | 50 |
| `-b, --brightness=<BRIGHTNESS>` | adjust brightness (-255 to 255) | 0 |
| `-H, --hue=<HUE>` | adjust hue (-180 to 180) | 0 |

View File

@ -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::<Vec<u32>>()
.chunks(image.get_width() as usize)
.map(|x| x.to_vec())
@ -60,7 +60,16 @@ impl AnsiImage {
}
}
pub fn make_rgb(rgb: Vec<u8>) -> 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<u8>) -> 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<u32>>) -> Vec<Vec<AnsiPixelPair>> {
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::<Vec<String>>();
let bg = make_rgb_u8(pixel_pair.bottom.orig)
.to_vec()
.iter()
.map(|x| x.to_string())
.collect::<Vec<String>>();
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");

View File

@ -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);