Feature: width
argument to calculate scale from number of available columns
#6
3 changed files with 64 additions and 2 deletions
|
@ -105,6 +105,9 @@ Options:
|
||||||
|
|
||||||
[default: 4]
|
[default: 4]
|
||||||
|
|
||||||
|
-w, --width <WIDTH>
|
||||||
|
|||||||
|
Enstablish how much wide is the output images, in columns. Overrides `scale`
|
||||||
|
|
||||||
-b, --background <BACKGROUND>
|
-b, --background <BACKGROUND>
|
||||||
The background color to use
|
The background color to use
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
/// Enstablish how much wide is the output images, in columns. Overrides `scale`
|
||||||
|
#[arg(short, long, default_value= None )]
|
||||||
|
pub width: Option<u32>,
|
||||||
/// The background color to use
|
/// The background color to use
|
||||||
#[arg(short, long, default_value = None)]
|
#[arg(short, long, default_value = None)]
|
||||||
pub background: Option<String>,
|
pub background: Option<String>,
|
||||||
|
|
|
@ -11,10 +11,11 @@ pub fn generate_ascii<W: Write>(
|
||||||
) -> io::Result<()> {
|
) -> io::Result<()> {
|
||||||
let characters = args.characters.chars().collect::<Vec<char>>();
|
let characters = args.characters.chars().collect::<Vec<char>>();
|
||||||
let (width, height) = image.dimensions();
|
let (width, height) = image.dimensions();
|
||||||
|
let actual_scale = calculate_scale(args, (width, height));
|
||||||
|
|
||||||
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 % (actual_scale * 2) == 0 && x % actual_scale == 0 {
|
||||||
let element = get_character(
|
let element = get_character(
|
||||||
image.get_pixel(x, y),
|
image.get_pixel(x, y),
|
||||||
&characters,
|
&characters,
|
||||||
|
@ -26,7 +27,7 @@ pub fn generate_ascii<W: Write>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Add a new line at the end of each row
|
// Add a new line at the end of each row
|
||||||
if y % (args.scale * 2) == 0 {
|
if y % (actual_scale * 2) == 0 {
|
||||||
buffer.write_all("\n".as_bytes())?;
|
buffer.write_all("\n".as_bytes())?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,3 +61,58 @@ fn get_character(
|
||||||
None => ch,
|
None => ch,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Determine how much scale to use in presence of `width` parameters,
|
||||||
|
/// otherwise returns regular `scale` parameter per default behaviour
|
||||||
|
///
|
||||||
|
#[inline]
|
||||||
|
fn calculate_scale(args: &Arguments, dimensions: (u32, u32)) -> u32 {
|
||||||
|
args.width.map_or_else(|| args.scale, |v| dimensions.0 / v)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use crate::args::{
|
||||||
|
args::Arguments,
|
||||||
|
enums::{Mode, OutputMethod},
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::calculate_scale;
|
||||||
|
|
||||||
|
const DIMENSIONS: (u32, u32) = (100, 100);
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_scale() {
|
||||||
|
let args = Arguments {
|
||||||
|
mode: Mode::NormalAscii,
|
||||||
|
output_method: OutputMethod::Stdout,
|
||||||
|
image: "".into(),
|
||||||
|
characters: "".into(),
|
||||||
|
scale: 4,
|
||||||
You can make this method as inline method using the You can make this method as inline method using the `#[inline]` suggests, This will can provide small but easy speed win.
https://nnethercote.github.io/perf-book/inlining.html
No problem, even if actually is called just once per run. Could gain more performance if we read the image from a file, or from No problem, even if actually is called just once per run.
Could gain more performance if we read the image from a file, or from `stdin` (for better bash integration).
I understand reading the image from a file, but what you mean with reading it from stdin? I understand reading the image from a file, but what you mean with reading it from stdin?
That would mean like how the
All That would mean like how the `-@` options works for `zip` program:
```bash
ls *.jpg | zip image_gallery.zip -@
```
All `*.jpg` files get streamed to `zip` and each one gets added to `image_gallery.zip`
But that would mean changing some of the program parameters.
|
|||||||
|
width: Some(10),
|
||||||
|
background: None,
|
||||||
|
output: "".into(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let scale = calculate_scale(&args, DIMENSIONS);
|
||||||
|
assert_eq!(scale, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_default_scale() {
|
||||||
|
let args = Arguments {
|
||||||
|
mode: Mode::NormalAscii,
|
||||||
|
output_method: OutputMethod::Stdout,
|
||||||
|
image: "".into(),
|
||||||
|
characters: "".into(),
|
||||||
|
scale: 4,
|
||||||
|
width: None,
|
||||||
|
background: None,
|
||||||
|
output: "".into(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let scale = calculate_scale(&args, DIMENSIONS);
|
||||||
|
assert_eq!(scale, 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue
Please copy this from the
aarty --help
output to save the consistency