A CLI tool to find the dominant colours in an image 🎨

Overview

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.

Installation

You need Rust installed; I recommend using Rustup. Then clone this repository and compile the code:

$ git clone "https://github.com/alexwlchan/dominant_colours.git"
$ cd dominant_colours
$ cargo install --path .

Usage examples

Pass the path of an image you want to look at:

$ 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:

$ 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:

$ 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 – 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 – 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 – 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.

Comments
  • Allow selecting colour output format

    Allow selecting colour output format

    This PR attempts to close #5.

    Here's some output using the three accepted arguments for --output with the lighthouse.

    --output=hex (default)
    #e9e4d7
    #858b88
    #4576bb
    #2c231b
    #c53b4e
    
    --output=rgb255
    rgb(233, 228, 215)
    rgb(133, 139, 136)
    rgb(69, 118, 187)
    rgb(44, 35, 27)
    rgb(197, 59, 78)
    
    --output=rgb01
    rgb(0.914, 0.894, 0.843)
    rgb(0.522, 0.545, 0.533)
    rgb(0.271, 0.463, 0.733)
    rgb(0.173, 0.137, 0.106)
    rgb(0.773, 0.231, 0.306)
    

    rgb01 formats the floats so that there is always 3 digits after the decimal. 3-digits after the decimal was chosen because 1 / 255 is roughly 0.004, so 2 digits would lose some precision. A side effect of this is that you always get 3-digits after the decimal, so a channel at its maximum will print "1.000" which I'm not sure is desirable behavior. It's quite verbose.

    opened by gennyble 3
  • Allow choosing the output format from hex/integer/float tuples

    Allow choosing the output format from hex/integer/float tuples

    Something like:

    --output=(hex | rgb255 | rgb01)
    

    where hex is the default, rgb255 gives you an RGB tuple with integer values (0–255) and rgb01 gives you an RGB tuple with float values (0-1).

    enhancement 
    opened by alexwlchan 1
  • Add support for TIFF images

    Add support for TIFF images

    Plus bump the version of the image crate.

    I looked at bumping the version of palette, but then I get issues with the kmeans_colors crate and I can't be bothered to deal with that today.

    opened by alexwlchan 0
  • Add a flag for `--best-contrast-with={background}`

    Add a flag for `--best-contrast-with={background}`

    This flag should return a single colour, filtering for a 4.5:1 contrast ratio and then maxing for saturation. Essentially replicating the logic from docstore: https://github.com/alexwlchan/docstore/blob/main/src/docstore/tint_colors.py

    opened by alexwlchan 0
  • Fix --no-palette test

    Fix --no-palette test

    πŸ‘‹πŸΎ hello Alex! I was working on adding tests for #5 (PR incoming) and I noticed that the test for --no-palette was the same as the test without it. Seems like a copy paste error. I think this test is correct now, it passes!

    Also I really like how you structure and name your tests. Tests have been something I am not-so-good-at and I am definitely going to try and mimic the way you do them. I didn't know there was a way to call the binary cargo outputs either! That's very nice.

    opened by gennyble 0
  • Provider a nicer error message if you try to look at an unsupported image format

    Provider a nicer error message if you try to look at an unsupported image format

    $ ./target/debug/dominant_colours ./README.md
    thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Unsupported(UnsupportedError { format: PathExtension("md"), kind: Format(PathExtension("md")) })', src/main.rs:60:34
    stack backtrace:
       0: rust_begin_unwind
                 at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/std/src/panicking.rs:515:5
       1: core::panicking::panic_fmt
                 at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/core/src/panicking.rs:92:14
       2: core::result::unwrap_failed
                 at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/core/src/result.rs:1355:5
       3: core::result::Result<T,E>::unwrap
                 at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/core/src/result.rs:1037:23
       4: dominant_colours::main
                 at ./src/main.rs:60:15
       5: core::ops::function::FnOnce::call_once
                 at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/core/src/ops/function.rs:227:5
    note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
    
    $ ./target/debug/dominant_colours ./holepunch-clouds.tiff
    thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Unsupported(UnsupportedError { format: Exact(Tiff), kind: Format(Exact(Tiff)) })', src/main.rs:60:34
    stack backtrace:
       0: rust_begin_unwind
                 at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/std/src/panicking.rs:515:5
       1: core::panicking::panic_fmt
                 at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/core/src/panicking.rs:92:14
       2: core::result::unwrap_failed
                 at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/core/src/result.rs:1355:5
       3: core::result::Result<T,E>::unwrap
                 at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/core/src/result.rs:1037:23
       4: dominant_colours::main
                 at ./src/main.rs:60:15
       5: core::ops::function::FnOnce::call_once
                 at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/core/src/ops/function.rs:227:5
    note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
    
    opened by alexwlchan 0
  • Provide a nicer error message if you try to look at a non-existent image file

    Provide a nicer error message if you try to look at a non-existent image file

    Currently:

    $ ./target/debug/dominant_colours  ./doesnotexist.jpg
    thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: IoError(Os { code: 2, kind: NotFound, message: "No such file or directory" })', src/main.rs:60:34
    stack backtrace:
       0: rust_begin_unwind
                 at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/std/src/panicking.rs:515:5
       1: core::panicking::panic_fmt
                 at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/core/src/panicking.rs:92:14
       2: core::result::unwrap_failed
                 at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/core/src/result.rs:1355:5
       3: core::result::Result<T,E>::unwrap
                 at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/core/src/result.rs:1037:23
       4: dominant_colours::main
                 at ./src/main.rs:60:15
       5: core::ops::function::FnOnce::call_once
                 at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/core/src/ops/function.rs:227:5
    note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
    
    opened by alexwlchan 0
Releases(v1.1.8)
Owner
Alex Chan
Working on digital preservation at @WellcomeCollection Β· Making software and weird magical realism Β· they/she
Alex Chan
fd is a program to find entries in your filesystem. It is a simple, fast and user-friendly alternative to find

fd is a program to find entries in your filesystem. It is a simple, fast and user-friendly alternative to find. While it does not aim to support all of find's powerful functionality, it provides sensible (opinionated) defaults for a majority of use cases.

David Peter 25.9k Jan 9, 2023
fas stand for Find all stuff and it's a go app that simplify the find command and allow you to easily search everything you nedd

fas fas stands for Find all stuff and it's a rust app that simplify the find command and allow you to easily search everything you need. Note: current

M4jrT0m 1 Dec 24, 2021
Save image from your clipboard πŸ“‹ as an image file directly from your command line! πŸ”₯

Clpy ?? Save copied image from clipboard as an image file directly from your command line! Note It works only on windows as of now. I'll be adding sup

Piyush Suthar 13 Nov 28, 2022
Conference Monitoring Project based on Image Recognition that uses Rust Language and AWS Rekognition service to get the level of image similarity.

Conference Monitoring System based on Image Recognition in Rust This is a Conference Monitoring Project based on Image Recognition that uses Rust Lang

Pankaj Chaudhary 6 Dec 18, 2022
CLI tool to find duplicate files based on their hashes.

Dupper Dupper is a CLI tool that helps you identify duplicate files based on their hashes (using the Seahash hashing algorithm). Installation You can

RubΓ©n J.R. 4 Dec 27, 2022
A CLI tool connected to GPT-3 to help find the right terminal command

Command Recall A CLI tool connected to GPT-3 to help find the right terminal command Install to install the cli: cargo install --git https://github.co

Camille Moatti 102 Feb 18, 2023
Quick, lightweight find and replace cli tool.

quick-replace A fast, lightweight find and replace tool Usage quick-replace [OPTIONS] <FROM> <TO> <path/to/file.txt> Options Flag Description -h Displ

Liam Watts 3 Apr 7, 2023
CLI tool to convert image files.

?? F1sh CLI tool to convert image files. ??️ Supported formats File Supported AviF βœ… BMP βœ… DDS βœ… Farbfeld βœ… GIF βœ… HEIF ❌ ICO βœ… JPEG βœ… OpenEXR βœ… PNG βœ…

Sammwy 5 Apr 3, 2023
Intuitive find & replace CLI (sed alternative)

sd - s[earch] & d[isplace] sd is an intuitive find & replace CLI. The Pitch Why use it over any existing tools? Painless regular expressions sd uses r

Gregory 4k Jan 4, 2023
Save cli commands and fuzzy find them later

crow - cli command memorizer What is crow? | Installation | Usage | FAQ What is crow? crow (command row) is a CLI tool to help you memorize CLI comman

sandstorm 7 Feb 17, 2022
A (aspiring to be fast) tool to find duplicate files.

find-duplicates A decenly fast tool to find duplicate files. Handles symbolic and hard links and treats them seperately to duplicates. Quickstart Inst

dylan 1 Jan 21, 2022
Tool that was built quickly for personal needs, you might find it useful though

COPYCAT Produced with stable-diffusion Clipboard (copy/paste) history buffer for terminal emulators, MAC OS gui and VIM* environment usage. Rrequireme

Dragan Jovanović 4 Dec 9, 2022
Preview Image in CLI.

PIC ?? PIC (Preview Image in CLI ) is a lightweight Rust tool to preview images in your terminal! With support for various image protocols (Kitty, Six

emanuel 23 Mar 3, 2023
A command-line tool and Docker image to automatically backup Git repositories from GitHub or anywhere

A command-line tool and Docker image to automatically backup Git repositories from GitHub or anywhere

Jake Wharton 256 Dec 27, 2022
A command-line tool aiming to upload the local image used in your markdown file to the GitHub repo and replace the local file path with the returned URL.

Pup A command line tool aiming to upload the local image used in your markdown file to the GitHub repo and replace the local file path with the return

SteveLau 11 Aug 17, 2022
A container image builder tool for OCI (distrobox/toolbox, also podman/docker)

Distrobox Boost A container image builder tool for Open Container Initiative (distrobox/toolbox, also podman/docker). Distrobox is good enough in runn

xz-dev 6 Aug 15, 2023
A CLI tool to get help with CLI tools πŸ™

A CLI tool to get help with CLI tools ?? halp aims to help find the correct arguments for command-line tools by checking the predefined list of common

Orhun ParmaksΔ±z 566 Apr 16, 2023
Eslint - Find and fix problems in your JavaScript code.

ESLint Website | Configuring | Rules | Contributing | Reporting Bugs | Code of Conduct | Twitter | Mailing List | Chat Room ESLint is a tool for ident

ESLint 22k Jan 9, 2023
🧠 A command-line utility for switching git branches more easily. Switch branches interactively or use a fuzzy search to find that long-forgotten branch name.

git-smart-checkout A git command extension for switching git branches more efficiently. About Interactively switch branches or fuzzy search for that f

Cezar Craciun 51 Dec 29, 2022