Skip to content

Commit

Permalink
Fix #4. Fix #6.
Browse files Browse the repository at this point in the history
  • Loading branch information
ian-hamlin committed May 8, 2021
1 parent 50065e8 commit d9a3a47
Show file tree
Hide file tree
Showing 7 changed files with 141 additions and 36 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "qrgen"
version = "0.4.0"
version = "0.5.0"
authors = ["ian-hamlin <[email protected]>"]
edition = "2018"

Expand Down
38 changes: 26 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,37 +43,41 @@ USAGE:

FLAGS:
-s, --skip A flag indicating if the first line of the CSV is a header and should be skipped, defaults to false
if not specified.
if not specified
-h, --help Prints help information
-l, --log A flag indicating if output will be logged, defaults to false if not specified.
--no-rect A flag indicating if the svg output should exclude the <rect /> tag. Ignored if using PNG, <rect /> tag is rendered if not specified.
-l, --log A flag indicating if output will be logged, defaults to false if not specified
--no-rect A flag indicating if the svg output should render the <rect /> tag. Ignored if using PNG
-V, --version Prints version information
-v, --verbose Verbose logging mode (-v, -vv, -vvv)

OPTIONS:
-x, --max <QR version max> The maximum version number supported in the QR Code Model 2 standard, or 40
if not specified. [default: 40]
if not specified [default: 40]
-m, --min <QR version min> The minimum version number supported in the QR Code Model 2 standard, or 1
if not specified. [default: 1]
if not specified [default: 1]
-g, --background <background> Set the foreground colour of the QR code using a six-digit hex value.
Defaults to FFFFFF [default: FFFFFF]
-b, --border <border> The size of the border on the generated QR Code, defaults to 4 if not
specified. [default: 4]
specified [default: 4]
-c, --chunk <chunk size> The number of lines to try and process in parallel, if not specified
defaults to 1 and file is processed line by line. [default: 1]
defaults to 1 and file is processed line by line [default: 1]
-e, --error <error correction level> The error correction level used in this QR Code, or High if not specified.
"Low" The QR Code can tolerate about 7% erroneous codewords. "Medium" The
QR Code can tolerate about 15% erroneous codewords. "Quartile" The QR Code
can tolerate about 25% erroneous codewords. "High" The QR Code can tolerate
about 30% erroneous codewords. [default: High]
-k, --mask <mask> The mask value to apply to the QR Code, between 0 and 7 (inclusive).
-f, --format <output format type> The target output format. Defaults to SVG if not specified. [default: SVG]
-o, --output <output path> Output path, or current working directory if not specified or - provided.
about 30% erroneous codewords [default: High]
-r, --foreground <forgeround> Set the foreground colour of the QR code using a six-digit hex value.
Defaults to 000000 [default: 000000]
-k, --mask <mask> The mask value to apply to the QR Code, between 0 and 7 (inclusive)
-f, --format <output format type> The target output format. Defaults to SVG if not specified [default: SVG]
-o, --output <output path> Output path, or current working directory if not specified or - provided
[default: -]
-a, --scale <scale> The side length (measured in pixels, must be positive) of each module,
defaults to 8. This value only applies when using the PNG format. Must be
between 1 and 255 (inclusive) [default: 8]

ARGS:
<infile>... Input file, must be specified.
<infile>... Input file, must be specified
```

## Examples
Expand All @@ -95,6 +99,16 @@ output to the current working directory.
.\qrgen.exe wiktionary_small.csv -s // This file has headers so the first line will now be skipped.
```

### Colour

Setting the background and foreground colours.

```console
# macOS
./qrgen wiktionary.csv --background ff0000 --foreground 0000ff;
./qrgen wiktionary.csv -g ff0000 -r 0000ff;
```

### Logging

Logging can be turned on with the --log/-l flag combined with zero or more -v options.
Expand Down
46 changes: 38 additions & 8 deletions src/exporter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ pub struct Exporter {
file_name: String,
scale: u8,
no_rect: bool,
foreground: (u8, u8, u8),
background: (u8, u8, u8),
}

impl Exporter {
Expand All @@ -34,6 +36,8 @@ impl Exporter {
file_name: String,
scale: u8,
no_rect: bool,
foreground: (u8, u8, u8),
background: (u8, u8, u8),
) -> Self {
Exporter {
qr_code,
Expand All @@ -43,6 +47,8 @@ impl Exporter {
file_name,
scale,
no_rect,
foreground,
background,
}
}

Expand Down Expand Up @@ -118,7 +124,10 @@ impl Exporter {
"<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" viewBox=\"0 0 {0} {0}\" stroke=\"none\">\n", dimension);

if !no_rect {
result += "\t<rect width=\"100%\" height=\"100%\" fill=\"#FFFFFF\"/>\n";
result += &format!(
"\t<rect width=\"100%\" height=\"100%\" fill=\"#{:02X}{:02X}{:02X}\"/>\n",
self.background.0, self.background.1, self.background.2
);
}

result += "\t<path d=\"";
Expand All @@ -132,7 +141,10 @@ impl Exporter {
}
}
}
result += "\" fill=\"#000000\"/>\n";
result += &format!(
"\" fill=\"#{:02X}{:02X}{:02X}\"/>\n",
self.foreground.0, self.foreground.1, self.foreground.2
);
result += "</svg>\n";
result
}
Expand Down Expand Up @@ -170,6 +182,18 @@ impl Exporter {
let mut writer = encoder.write_header()?;
let mut data = vec![255_u8; data_length as usize];

if self.background != (255, 255, 255) {
trace!("Setting background {:?}", self.background);
let mut idx = 0_usize;

while idx < data.len() {
data[idx] = self.background.0;
data[idx + 1] = self.background.1;
data[idx + 2] = self.background.2;
idx += 3;
}
}

trace!(
"version = {:?}, errorcorrectionlevel = {:?}, mask = {:?}, size = {}, data length = {}",
qr_code.version().value(),
Expand Down Expand Up @@ -198,15 +222,15 @@ impl Exporter {
let offset_xy = offset_fn(point.0, point.1, size, colour_type_samples);

if qr_code.get_module(point.1 / scale - border, point.0 / scale - border) {
data[offset_yx] = 0;
data[offset_yx + 1] = 0;
data[offset_yx + 2] = 0;
data[offset_yx] = self.foreground.0;
data[offset_yx + 1] = self.foreground.1;
data[offset_yx + 2] = self.foreground.2;
}

if qr_code.get_module(point.0 / scale - border, point.1 / scale - border) {
data[offset_xy] = 0;
data[offset_xy + 1] = 0;
data[offset_xy + 2] = 0;
data[offset_xy] = self.foreground.0;
data[offset_xy + 1] = self.foreground.1;
data[offset_xy + 2] = self.foreground.2;
}
}

Expand Down Expand Up @@ -307,6 +331,8 @@ mod tests {
"".into(),
1,
false,
(0, 0, 0),
(255, 255, 255),
);

// Act.
Expand Down Expand Up @@ -517,6 +543,8 @@ mod tests {
"".into(),
1,
true,
(0, 0, 0),
(255, 255, 255),
);

// Act.
Expand Down Expand Up @@ -725,6 +753,8 @@ mod tests {
"".into(),
1,
false,
(0, 0, 0),
(255, 255, 255),
);

// Act.
Expand Down
13 changes: 12 additions & 1 deletion src/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ impl Generator {
record[0].to_string(),
self.out_conf.scale,
self.out_conf.no_rect,
self.out_conf.foreground,
self.out_conf.background,
);
let res = exp.export();
if res.is_err() {
Expand Down Expand Up @@ -121,7 +123,7 @@ impl fmt::Display for Generator {
f,
"qr_conf = [QR Version Min:{}, QR Version Max:{}, Error Correction: {}, Mask:{}], \
proc_conf = [Chunk Size:{}, Has CSV Header:{}], \
out_conf: [Border:{}, Format: {:?}, Output: {}], \
out_conf: [Border:{}, Format: {:?}, Exclude <rect />: {:?}, Foreground: {:?}, Fackgound: {:?}, Output: {}], \
input: Files: {:?}:",
self.qr_conf.qr_version_min.value(),
self.qr_conf.qr_version_max.value(),
Expand All @@ -139,6 +141,9 @@ impl fmt::Display for Generator {
self.proc_conf.has_headers,
self.out_conf.border,
self.out_conf.format,
self.out_conf.no_rect,
self.out_conf.foreground,
self.out_conf.background,
self.out_conf.output.display(),
self.files,
)
Expand Down Expand Up @@ -175,6 +180,8 @@ pub struct OutputConfig {
format: exporter::ExportFormat,
scale: u8,
no_rect: bool,
foreground: (u8, u8, u8),
background: (u8, u8, u8),
}

impl OutputConfig {
Expand All @@ -184,13 +191,17 @@ impl OutputConfig {
format: exporter::ExportFormat,
scale: u8,
no_rect: bool,
foreground: (u8, u8, u8),
background: (u8, u8, u8),
) -> Self {
OutputConfig {
output,
border,
format,
scale,
no_rect,
foreground,
background,
}
}
}
Expand Down
47 changes: 47 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,36 @@ struct Opt {
/// A flag indicating if the svg output should render the <rect /> tag. Ignored if using PNG.
#[structopt(long = "no-rect")]
no_rect: bool,

/// Set the foreground colour of the QR code using a six-digit hex value. Defaults to 000000.
#[structopt(
short = "r",
long = "foreground",
default_value = "000000",
parse(try_from_str = parse_rgb_from_hex)
)]
forgeround: (u8, u8, u8),

/// Set the foreground colour of the QR code using a six-digit hex value. Defaults to FFFFFF.
#[structopt(
short = "g",
long = "background",
default_value = "FFFFFF",
parse(try_from_str = parse_rgb_from_hex)
)]
background: (u8, u8, u8),
}

fn parse_rgb_from_hex(src: &str) -> Result<(u8, u8, u8), String> {
if src.len() != 6 {
return Err(String::from("Please enter only a six-digit hex value."));
}

let r = u8::from_str_radix(&src[0..2], 16).unwrap_or(0);
let g = u8::from_str_radix(&src[2..4], 16).unwrap_or(0);
let b = u8::from_str_radix(&src[4..6], 16).unwrap_or(0);

return Ok((r, g, b));
}

fn parse_output_directory(src: &OsStr) -> PathBuf {
Expand Down Expand Up @@ -209,6 +239,8 @@ impl Opt {
self.format,
self.scale,
self.no_rect,
self.forgeround,
self.background,
),
generator::ProcessingConfig::new(self.chunk_size, self.has_headers),
)
Expand Down Expand Up @@ -248,6 +280,21 @@ mod tests {
assert_eq!(expect, actual);
}

#[test]
fn should_parse_rgb() {
let res = parse_rgb_from_hex("ff11c0").unwrap();
assert_eq!((255, 17, 192), res);
}

#[test]
fn should_parse_rgb_error() {
let res = parse_rgb_from_hex("ff11c0c").err();
assert_eq!(
Some("Please enter only a six-digit hex value.".to_string()),
res
);
}

#[test]
fn should_parse_qr_format_to_png() {
let res = parse_qr_format("png").unwrap();
Expand Down
29 changes: 16 additions & 13 deletions usage.txt
Original file line number Diff line number Diff line change
@@ -1,39 +1,42 @@
qrgen 0.4.0
ian-hamlin <[email protected]>
qrgen 0.5.0

USAGE:
qrgen [FLAGS] [OPTIONS] <infile>...

FLAGS:
-s, --skip A flag indicating if the first line of the CSV is a header and should be skipped, defaults to false
if not specified.
if not specified
-h, --help Prints help information
-l, --log A flag indicating if output will be logged, defaults to false if not specified.
-l, --log A flag indicating if output will be logged, defaults to false if not specified
--no-rect A flag indicating if the svg output should render the <rect /> tag. Ignored if using PNG
-V, --version Prints version information
-v, --verbose Verbose logging mode (-v, -vv, -vvv)

OPTIONS:
-x, --max <QR version max> The maximum version number supported in the QR Code Model 2 standard, or 40
if not specified. [default: 40]
if not specified [default: 40]
-m, --min <QR version min> The minimum version number supported in the QR Code Model 2 standard, or 1
if not specified. [default: 1]
if not specified [default: 1]
-g, --background <background> Set the foreground colour of the QR code using a six-digit hex value.
Defaults to FFFFFF [default: FFFFFF]
-b, --border <border> The size of the border on the generated QR Code, defaults to 4 if not
specified. [default: 4]
specified [default: 4]
-c, --chunk <chunk size> The number of lines to try and process in parallel, if not specified
defaults to 1 and file is processed line by line. [default: 1]
defaults to 1 and file is processed line by line [default: 1]
-e, --error <error correction level> The error correction level used in this QR Code, or High if not specified.
"Low" The QR Code can tolerate about 7% erroneous codewords. "Medium" The
QR Code can tolerate about 15% erroneous codewords. "Quartile" The QR Code
can tolerate about 25% erroneous codewords. "High" The QR Code can tolerate
about 30% erroneous codewords. [default: High]
-k, --mask <mask> The mask value to apply to the QR Code, between 0 and 7 (inclusive).
-f, --format <output format type> The target output format. Defaults to SVG if not specified. [default: SVG]
-o, --output <output path> Output path, or current working directory if not specified or - provided.
about 30% erroneous codewords [default: High]
-r, --foreground <forgeround> Set the foreground colour of the QR code using a six-digit hex value.
Defaults to 000000 [default: 000000]
-k, --mask <mask> The mask value to apply to the QR Code, between 0 and 7 (inclusive)
-f, --format <output format type> The target output format. Defaults to SVG if not specified [default: SVG]
-o, --output <output path> Output path, or current working directory if not specified or - provided
[default: -]
-a, --scale <scale> The side length (measured in pixels, must be positive) of each module,
defaults to 8. This value only applies when using the PNG format. Must be
between 1 and 255 (inclusive) [default: 8]

ARGS:
<infile>... Input file, must be specified.
<infile>... Input file, must be specified

0 comments on commit d9a3a47

Please sign in to comment.