Palette Maker is an interactive web tool that allows you to explore different approaches to extract color palettes from images. For a detailed description, please refer to this blog post that I wrote.
A demo can be found here.
To run the project:
-
Clone the repository
-
Install the dependencies by running:
npm install
- Build and package the javascript by running:
webpack
This will generate a single bundle.js
file, containing all of the code.
After building the bundle.js
file, the app can be run a few different ways.
The app is configured to work with express for remote deployments (e.g., Heroku). To run it locally, simply use:
npm start
Since the app runs entirely inside of the browser, you can use http-server to serve up the files locally.
npm install http-server -g
Then, navigate to the project root and run:
http-server ./public
I would like to add the following in the future:
-
Features
- Additional color spaces (e.g., HSL).
- Additional algorithms - perhaps other clustering techniques or image sampling.
- Improve the design of the extracted palettes, and make them more exportable.
- Add sample images.
-
Code Improvements
- Add a lightweight JS framework for better code readability and organization (probably React).
- Update the Plotly.js imports.
- Improve the page responsiveness when the algorithms run and provide progress feedback.
When the app starts, you simply browse and select a local image. The app then loads the image and plots in in three dimensional RGB space.
Three different palette extraction algorithms are currently supported.
The histogram binning approach partitions the RGB space into a NxNxN grid where N is a user provided value. The below image shows an example when N=3
. Here, the space is partitioned into 27 equally sized cells. The pixels that fall within each cell are counted, and their average color value is computed. Average colors from the most populated 10 cells are selected and displayed as the color palette.
Median cut also partitions the space, though it does to in a non-uniform way. The pixel range is computed for each color dimension (red, green, and blue). Then, the dimention with the largest range is selected, and the median value is computed. The space is then split into two halves - one above the median, and one below. This process continues recursively. Each iteration, only the subspace with greatest pixel range is split. A sample partitioning looks like this:
K-Means attempts to cluster the pixels into k distinct clusters. The user provides a k value as input.
Since k-means is notorious for getting stuck in local minima, the algorithm is re-run 10 times and the result with lowest error is selected. An example output from running k-means on the above image is shown below.