Feature: width argument to calculate scale from number of available columns #6

Merged
giulio-Joshi merged 3 commits from columns_arg into master 2022-10-26 19:36:21 +00:00
3 changed files with 64 additions and 2 deletions

View file

@ -105,6 +105,9 @@ Options:
[default: 4]
-w, --width <WIDTH>
anas-elgarhy commented 2022-10-26 16:25:48 +00:00 (Migrated from github.com)
Review

Please copy this from the aarty --help output to save the consistency

Please copy this from the `aarty --help` output to save the consistency
Enstablish how much wide is the output images, in columns. Overrides `scale`
-b, --background <BACKGROUND>
The background color to use

View file

@ -19,6 +19,9 @@ pub mod args {
/// The output scale (1 is the original size)
#[arg(short, long, default_value = "4")]
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
#[arg(short, long, default_value = None)]
pub background: Option<String>,

View file

@ -11,10 +11,11 @@ pub fn generate_ascii<W: Write>(
) -> io::Result<()> {
let characters = args.characters.chars().collect::<Vec<char>>();
let (width, height) = image.dimensions();
let actual_scale = calculate_scale(args, (width, height));
for y in 0..height {
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(
image.get_pixel(x, y),
&characters,
@ -26,7 +27,7 @@ pub fn generate_ascii<W: Write>(
}
}
// 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())?;
}
}
@ -60,3 +61,58 @@ fn get_character(
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,
anas-elgarhy commented 2022-10-26 16:20:34 +00:00 (Migrated from github.com)
Review

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

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
giulio-Joshi commented 2022-10-26 17:55:27 +00:00 (Migrated from github.com)
Review

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).

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).
anas-elgarhy commented 2022-10-26 19:30:01 +00:00 (Migrated from github.com)
Review

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?
giulio-Joshi commented 2022-10-26 19:48:27 +00:00 (Migrated from github.com)
Review

That would mean like how the -@ options works for zip program:

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.

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