Show DEV: colorSpace - smart background removal with canvas 🖼️
Tags: showdev, math, canvas
Published: 2019-01-25 17:28:16

---
title: Show DEV: colorSpace - smart background removal with canvas 🖼️
published: true
cover_image: https://thepracticaldev.s3.amazonaws.com/i/w8rop00gr25ue3dpts8r.png
description: Measuring euclidian distance to compare colors 📐
tags: showdev, math, canvas
---

Hey all you DEVs!

Just a couple weeks ago, I built [colorSpace](https://color.4ty2.fun?ref=dev) in a few hours - It was a fun idea I wanted to explore, not even being sure if it was possible at all!



![Demo gif](https://thepracticaldev.s3.amazonaws.com/i/kcmzs76sovhr4y7q77n4.gif)


It turned out to be possible, and actually even accurate!

My idea was pretty straightforward - usually, an image with a background has one dominant color to remove. Because of shadows and lighting angles - this color won't remain the exact same across all its pixels, but maybe it'd be possible to measure color similarity somehow 🤔

I googled it - and saw a few stack overflow posts asking the same question, and learned that it was fairly trivial to get the euclidian distance between colors, since they're usually represented in a three axis system eg. `R, G, B`  `H, S, L` 
 `Y, I, Q` - there are some more listed [here](https://en.wikipedia.org/wiki/List_of_color_spaces_and_their_uses#Luma_plus_chroma/chrominance)

That means we can use the distance formula, representing a color as a co-ordinate in the `x`, `y` and `z` *axes* (I had to google `axis plural` 😂)

![An image of a 3D co-ordinate system](https://thepracticaldev.s3.amazonaws.com/i/pgi8ngtp80p3w3uml3fy.gif) 
<figcaption>From <a href="https://brilliant.org/wiki/3d-coordinate-geometry-distance">Brilliant</a></figcaption>

It comes down add up the squared difference, and finding its square root, i.e:

![Image of the 3D distance formula](https://thepracticaldev.s3.amazonaws.com/i/bytxs42ost1evrnkcr8w.png)

It'd be pretty simple to do this with RGB colors - but the RGB colorspace wasn't designed keeping the `ΔE` - or distance function in mind. This means that the euclidian distance between colors in the RGB space will not always correspond to the difference us humans see between the colors.

I DIDN'T give up yet though 😅 Turns out [CIE](https://en.wikipedia.org/wiki/International_Commission_on_Illumination) (the W3C of the color world) designed the [L*a*b](https://en.wikipedia.org/wiki/CIELAB_color_space) colorspace to be perceptually uniform with human color vision - which means, an accurate and useful `ΔE` function 🚀

![Front view of the CIELAB colorspace](https://thepracticaldev.s3.amazonaws.com/i/08key4dxj1qnsram8iou.png)
<figcaption>This is what the L*a*b colorspace looks like from the front</figcaption>

From here, it was just a bit of plug and play into JS! I reused the frontend from [Santafy](https://santa.4ty2.fun) - a fun christmas project I'd built 🎅

I found the [rgb-lab](https://github.com/antimatter15/rgb-lab) library which let me convert RGB to LAB, and back. I could also use the `ΔE` function right within this library!

The [color-sampler](https://github.com/emn178/color-sampler) library needed me to add jquery to the project, but I have no complaints - it works very well, and has a nice UI for color selection 👇


![color-sampler demo](https://thepracticaldev.s3.amazonaws.com/i/lo5n90jolffpsdov9hdj.gif)




To summarize the code I wrote - It takes an image from visitors, and loads it up into a canvas. From there, a pixel is selected using the color sampler - and all pixels in the canvas are converted to the `L*a*b` colorspace, and compared to the selected pixel with the `ΔE` function - if any pixel's color falls within the treshold, the transparency for it is set to 100%


And *all* that happens in the canvas, completely on the frontend!


If you haven't already, you can try [colorSpace here](https://color.4ty2.fun)!


The code is fully open source, you can check it out and instantly fork it on this [repl](https://repl.it/@jajoosam/colorspace) 👨‍💻

{% replit @jajoosam/colorspace %}


That's it - I'd love to hear your thoughts and feedback 😄

*I'm a 15 year old maker* 👨‍💻  *For more cool things to make and to stay updated with my progress, sign up for [my newsletter](https://buttondown.email/jajoosam)* 📧