Skip to main content

Expand the README to explain how the tool works

ID
8674013
date
2021-11-27 10:16:21+00:00
author
Alex Chan <alex@alexwlchan.net>
parent
27f690f
message
Expand the README to explain how the tool works
changed files
4 files, 96 additions, 15 deletions

Changed files

README.md (225) → README.md (2669)

diff --git a/README.md b/README.md
index 19e75f5..c31fb94 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,85 @@
-https://alexwlchan.net/2021/04/coloured-squares/
-https://docs.rs/clap/2.33.3/clap/
-https://rosettacode.org/wiki/Check_output_device_is_a_terminal#Rust
-https://github.com/okaneco/kmeans-colors/tree/master/src/bin/kmeans_colors
\ No newline at end of file
+# dominant_colours
+
+This is a command-line tool for finding the dominant colours of an image.
+It prints their hex codes to the terminal, along with a preview of the colour (in terminals that support ANSI escape codes):
+
+![Left: a photo of a red and white lighthouse set against a blue sky. Right: the terminal output of three invocations of 'dominant_colours' against 'lighthouse.jpg', with hex colours printed to the terminal.](screenshot.png)
+
+
+
+## Installation
+
+You need Rust installed; I recommend using [Rustup].
+Then clone this repository and compile the code:
+
+```console
+$ git clone "https://github.com/alexwlchan/dominant_colours.git"
+$ cd dominant_colours
+$ cargo install --path .
+```
+
+[Rustup]: https://rustup.rs/
+
+
+
+## Usage examples
+
+Pass the path of an image you want to look at:
+
+```console
+$ dominant_colours /path/to/cats.jpg
+▇ #d0c6b2
+▇ #3f3336
+▇ #f3f2ee
+▇ #786356
+▇ #aa9781
+```
+
+By default, it finds (up to) five dominant colours.
+If you want more or less, pass the `--max-colours` flag.
+For example:
+
+```console
+$ dominant_colours /path/to/corgis.jpg --max-colours=3
+▇ #7c8442
+▇ #ccbe8f
+▇ #2d320e
+```
+
+The colours are printed as hex codes, with colour previews in your terminal.
+If you just want the hex codes and no colour preview, pass the `--no-palette` flag:
+
+```console
+$ dominant_colours /path/to/crustaceans.png --no-palette
+#e6401b
+#be5e36
+#734f48
+#d6c0bd
+#b1948f
+```
+
+This is useful if your terminal doesn't support ANSI escape codes, or you're passing the output to another tool.
+
+
+
+## Further reading
+
+-   [Getting a tint colour from an image with Python and k-means](https://alexwlchan.net/2019/08/finding-tint-colours-with-k-means/) – a blog post I wrote in August 2019 explaining how to find dominant colours.
+
+    My original implementation was in Python.
+    I've replaced it with a standalone Rust tool so I can easily share it across multiple projects, and because Rust is noticeably faster for this sort of thing.
+
+-   [Collyn O'Kane's kmeans-colors project](https://github.com/okaneco/kmeans-colors) – a Rust command-line tool and library for finding the average colours in an image using k-means.
+
+    The command-line tool has a lot of features, more than I need.
+    I wanted a very simple tool that does one thing, so I wrote dominant_colours as a wrapper around the library.
+
+-   [Drawing coloured squares/text in my terminal with Python](https://alexwlchan.net/2021/04/coloured-squares/) – a blog post I wrote in April 2021 explaining how to use ANSI escape codes to print arbitrary colours in a terminal.
+
+    I used the same escape codes to get the coloured output in this tool.
+
+
+
+## License
+
+MIT.

lighthouse.jpg (0) → lighthouse.jpg (176328)

diff --git a/lighthouse.jpg b/lighthouse.jpg
new file mode 100644
index 0000000..60198ca
Binary files /dev/null and b/lighthouse.jpg differ

screenshot.png (0) → screenshot.png (401303)

diff --git a/screenshot.png b/screenshot.png
new file mode 100644
index 0000000..904f28d
Binary files /dev/null and b/screenshot.png differ

src/main.rs (7611) → src/main.rs (7683)

diff --git a/src/main.rs b/src/main.rs
index 0a228ac..146f2f9 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -21,8 +21,8 @@ fn main() {
                     .index(1)
             )
             .arg(
-                Arg::with_name("count")
-                    .long("count")
+                Arg::with_name("max-colours")
+                    .long("max-colours")
                     .help("how many colours to find")
                     .default_value("5")
                     .takes_value(true)
@@ -38,9 +38,9 @@ fn main() {
     // This .unwrap() is safe because "path" is a required param
     let path = matches.value_of("path").unwrap();
 
-    // Get the count as a number.
+    // Get the max colours as a number.
     // See https://github.com/clap-rs/clap/blob/v2.33.1/examples/12_typed_values.rs
-    let count = value_t!(matches, "count", usize).unwrap_or_else(|e| e.exit());
+    let max_colours = value_t!(matches, "max-colours", usize).unwrap_or_else(|e| e.exit());
 
     let img = match image::open(&path) {
         Ok(im) => im,
@@ -82,7 +82,7 @@ fn main() {
     let verbose = false;
     let seed: u64 = 0;
 
-    let result = get_kmeans_hamerly(count, max_iterations, converge, verbose, &lab, seed);
+    let result = get_kmeans_hamerly(max_colours, max_iterations, converge, verbose, &lab, seed);
 
     let rgb = &result.centroids
         .iter()
@@ -113,7 +113,7 @@ mod tests {
 
     #[test]
     fn it_prints_the_color_with_ansi_escape_codes() {
-        let output = get_success(&["./src/tests/red.png", "--count=1"]);
+        let output = get_success(&["./src/tests/red.png", "--max-colours=1"]);
 
         assert_eq!(output.exit_code, 0);
 
@@ -128,7 +128,7 @@ mod tests {
 
     #[test]
     fn it_omits_the_escape_codes_with_no_palette() {
-        let output = get_success(&["./src/tests/red.png", "--count=1"]);
+        let output = get_success(&["./src/tests/red.png", "--max-colours=1"]);
 
         assert_eq!(output.exit_code, 0);
 
@@ -149,15 +149,15 @@ mod tests {
     }
 
     #[test]
-    fn it_lets_you_choose_the_count() {
-        let output = get_success(&["./src/tests/noise.jpg", "--count=8"]);
+    fn it_lets_you_choose_the_max_colours() {
+        let output = get_success(&["./src/tests/noise.jpg", "--max-colours=8"]);
 
         assert_eq!(output.stdout.matches("\n").count(), 8, "stdout = {:?}", output.stdout);
     }
 
     #[test]
-    fn it_fails_if_you_pass_an_invalid_count() {
-        let output = get_failure(&["./src/tests/red.png", "--count=NaN"]);
+    fn it_fails_if_you_pass_an_invalid_max_colours() {
+        let output = get_failure(&["./src/tests/red.png", "--max-colours=NaN"]);
 
         assert_eq!(output.exit_code, 1);
         assert_eq!(output.stdout, "");