Matt Nemitz

Software developer | London

Image2Palette | Matt Nemitz

Image2Palette

July 05, 2022

Image to palette

Pick your own color palettes from any image!

See it live at image2palette.app

Peep the source code on Github

What it does

Given any input image, this application generates colors which are characteristic to that image. You can then pick from these images to create your own beautiful color schemes.

How it works

Many images contain hundreds of thousand of distinct colors. If we want to extract colors from images to create beautiful, balanced color schemes, we have to be smart about selection.

Ranking the distinct colors by frequency can produce nice results, but it misses out on key information about the overall distribution. If we want to see an image’s characteristic colors, we want to somehow capture the full color range of an image.

With that goal in mind, the selection of colors in this app is based on the convex hull of the image colors. In other words, if each color in the image is plotted in 3D space (where red, green, and blue color channels are the respective axes), then the set of colors returned determines a polytope within which all of the other color points are contained. This polytope is visible within the page, and can be explored by hovering over the resulting colors, allowing the user to get a feel for the “shape” of the image, when seen from color space.

Image Convex colors
Starry Night Polytope

Moreover, this polytope can also be thought of as a graph, allowing us to potentially generate color schemes based on graph traversal algorithms.

Other technical details

The site runs entirely offline, and was made with Svelte with some heavy lifting for the 3D rendering done by ThreeJS. It’s my first big Svelte project, but I was drawn to Svelte as opposed big frameworks like Vue or React because ThreeJS is relatively heavy, and not having an extra runtime for DOM stuff simplifies things a lot.

Svelte’s context API mixes quite nicely with ThreeJS too. With some pretty simple logic, it is possible to create Svelte components which effectively render inside a ThreeJS controlled canvas (see src/three-components/ThreeScene.svelte).

I will likely be porting this project to a newer version of Svelte and SMUI. With that change I also hope to convert the majority to Typescript, as well as perhaps delegate the convex hull calculation to a cloud function. Stay tuned!