Add the background option 🥰
This commit is contained in:
parent
b885cc3fb7
commit
b180ca5f56
3 changed files with 26 additions and 48 deletions
|
@ -19,6 +19,9 @@ pub mod args {
|
||||||
/// The output scale (1 is the original size)
|
/// The output scale (1 is the original size)
|
||||||
#[arg(short, long, default_value="4")]
|
#[arg(short, long, default_value="4")]
|
||||||
pub scale: u32,
|
pub scale: u32,
|
||||||
|
/// The background color to use
|
||||||
|
#[arg(short, long, default_value=None)]
|
||||||
|
pub background: Option<String>,
|
||||||
/// The output file to write to (if output_method is file)
|
/// The output file to write to (if output_method is file)
|
||||||
#[arg(short, long, default_value="ascii_image.txt")]
|
#[arg(short, long, default_value="ascii_image.txt")]
|
||||||
pub output: String,
|
pub output: String,
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use clap::arg;
|
use clap::arg;
|
||||||
|
use clap::builder::Str;
|
||||||
use image::{GenericImageView, DynamicImage};
|
use image::{GenericImageView, DynamicImage};
|
||||||
use colored::{ColoredString, Colorize};
|
use colored::{ColoredString, Colorize};
|
||||||
use crate::args::{
|
use crate::args::{
|
||||||
|
@ -6,7 +7,7 @@ use crate::args::{
|
||||||
enums::Mode
|
enums::Mode
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn generate_ascii(image: DynamicImage, args: &Arguments) -> Result<Vec<ColoredString>, error::ASCIIProcessingError> {
|
pub fn generate_ascii(image: DynamicImage, args: &Arguments) -> Vec<ColoredString> {
|
||||||
let characters = args.characters.chars().collect::<Vec<char>>();
|
let characters = args.characters.chars().collect::<Vec<char>>();
|
||||||
trace!("Characters: {:?}, length: {}", characters, characters.len());
|
trace!("Characters: {:?}, length: {}", characters, characters.len());
|
||||||
let mut output = Vec::new();
|
let mut output = Vec::new();
|
||||||
|
@ -15,7 +16,11 @@ pub fn generate_ascii(image: DynamicImage, args: &Arguments) -> Result<Vec<Color
|
||||||
for y in 0..height {
|
for y in 0..height {
|
||||||
for x in 0..width {
|
for x in 0..width {
|
||||||
if y % (args.scale * 2) == 0 && x % args.scale == 0 {
|
if y % (args.scale * 2) == 0 && x % args.scale == 0 {
|
||||||
output.push(get_character(image.get_pixel(x, y), &characters, args.mode));
|
output.push(get_character(
|
||||||
|
image.get_pixel(x, y),
|
||||||
|
&characters, args.mode,
|
||||||
|
&args.background
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Add a new line at the end of each row
|
// Add a new line at the end of each row
|
||||||
|
@ -24,51 +29,30 @@ pub fn generate_ascii(image: DynamicImage, args: &Arguments) -> Result<Vec<Color
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(output)
|
output
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_character(pixel: image::Rgba<u8>, characters: &Vec<char>, mode: Mode) -> ColoredString {
|
fn get_character(
|
||||||
|
pixel: image::Rgba<u8>,
|
||||||
|
characters: &Vec<char>, mode: Mode,
|
||||||
|
background: &Option<String>
|
||||||
|
) -> ColoredString {
|
||||||
let intent = if pixel[3] == 0 { 0 } else { pixel[0] / 3 + pixel[1] / 3 + pixel[2] / 3 };
|
let intent = if pixel[3] == 0 { 0 } else { pixel[0] / 3 + pixel[1] / 3 + pixel[2] / 3 };
|
||||||
|
|
||||||
let ch = characters[(intent / (32 + 7 - (7 + (characters.len() - 7)) as u8)) as usize];
|
let ch = characters[(intent / (32 + 7 - (7 + (characters.len() - 7)) as u8)) as usize];
|
||||||
|
|
||||||
let ch = String::from(ch);
|
let ch = String::from(ch);
|
||||||
|
|
||||||
match mode {
|
let ch = match mode {
|
||||||
Mode::NormalAscii => ColoredString::from(&*ch),
|
Mode::NormalAscii => ColoredString::from(&*ch),
|
||||||
Mode::COLORED => {
|
Mode::COLORED => {
|
||||||
ch.to_string()
|
ch.to_string()
|
||||||
.truecolor(pixel[0], pixel[1], pixel[2])
|
.truecolor(pixel[0], pixel[1], pixel[2])
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
|
||||||
|
|
||||||
mod error {
|
match background {
|
||||||
use std::error::Error;
|
Some(bg) => ch.on_color(bg.to_string()),
|
||||||
use std::fmt::{Debug, Display, Formatter};
|
None => ch
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct ASCIIProcessingError {
|
|
||||||
message: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ASCIIProcessingError {
|
|
||||||
pub fn new(message: String) -> Self {
|
|
||||||
ASCIIProcessingError {
|
|
||||||
message
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display for ASCIIProcessingError {
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
||||||
write!(f, "{}", self.message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Error for ASCIIProcessingError {
|
|
||||||
fn description(&self) -> &str {
|
|
||||||
&self.message
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
15
src/main.rs
15
src/main.rs
|
@ -1,7 +1,7 @@
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use image::GenericImageView;
|
use image::GenericImageView;
|
||||||
use colored::Colorize;
|
|
||||||
|
|
||||||
extern crate pretty_env_logger;
|
extern crate pretty_env_logger;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
@ -12,7 +12,7 @@ mod ascii_processor;
|
||||||
|
|
||||||
use crate::args::{
|
use crate::args::{
|
||||||
args::Arguments,
|
args::Arguments,
|
||||||
enums::{Mode, OutputMethod},
|
enums::OutputMethod,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::ascii_processor::generate_ascii;
|
use crate::ascii_processor::generate_ascii;
|
||||||
|
@ -52,17 +52,8 @@ fn main() {
|
||||||
trace!("Image dimensions: {:?}", image.dimensions());
|
trace!("Image dimensions: {:?}", image.dimensions());
|
||||||
|
|
||||||
// Process the image
|
// Process the image
|
||||||
let output = match generate_ascii(image, &arguments) {
|
let output = generate_ascii(image, &arguments);
|
||||||
Ok(out) => {
|
|
||||||
info!("Successfully processed image");
|
info!("Successfully processed image");
|
||||||
out
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
error!("Failed to process image: {:?}", e);
|
|
||||||
eprintln!("Failed to process image: {:?}", e);
|
|
||||||
std::process::exit(1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Output the image
|
// Output the image
|
||||||
info!("Outputting image");
|
info!("Outputting image");
|
||||||
|
|
Loading…
Reference in a new issue