Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/tlux/tint

An Elixir library to work with colors, convert between different colorspaces and calculate color distances.
https://github.com/tlux/tint

ciede2000 cielab cmyk color color-conversion color-converter color-distance colorspaces complementary-colors convert-colors elixir-library euclidean-distances hex hex-codes hsv rgb rgb-colors

Last synced: 5 days ago
JSON representation

An Elixir library to work with colors, convert between different colorspaces and calculate color distances.

Awesome Lists containing this project

README

        

# Tint

[![Build](https://github.com/tlux/tint/actions/workflows/elixir.yml/badge.svg)](https://github.com/tlux/tint/actions/workflows/elixir.yml)
[![Coverage Status](https://coveralls.io/repos/github/tlux/tint/badge.svg?branch=main)](https://coveralls.io/github/tlux/tint?branch=main)
[![Module Version](https://img.shields.io/hexpm/v/tint.svg)](https://hex.pm/packages/tint)
[![Hex Docs](https://img.shields.io/badge/hex-docs-lightgreen.svg)](https://hexdocs.pm/tint/)
[![License](https://img.shields.io/hexpm/l/tint.svg)](https://github.com/tlux/tint/blob/main/LICENSE.md)
[![Last Updated](https://img.shields.io/github/last-commit/tlux/tint.svg)](https://github.com/tlux/tint/commits/main)

An Elixir library allowing calculations with colors and conversions between
different colorspaces.

Currently supports the following color models:

- [RGB](https://en.wikipedia.org/wiki/RGB_color_space)
- [CMYK](https://en.wikipedia.org/wiki/CMYK_color_model)
- [HSV](https://en.wikipedia.org/wiki/HSL_and_HSV)
- L\*a\*b\* ([CIELAB](https://en.wikipedia.org/wiki/CIELAB_color_space))
- XYZ ([CIE 1931](https://en.wikipedia.org/wiki/CIE_1931_color_space))
- [DIN99](https://de.wikipedia.org/wiki/DIN99-Farbraum)

## Prerequisites

- Elixir 1.14 or greater

## Installation

The package can be installed by adding `tint` to your list of dependencies in
`mix.exs`:

```elixir
def deps do
[
{:tint, "~> 1.2"}
]
end
```

## Usage

### Colorspaces

#### RGB

```elixir
iex> Tint.RGB.new(255, 0, 0)
#Tint.RGB<255,0,0 (#FF0000)>
```

or

```elixir
iex> import Tint.Sigil
...> ~K[255, 0, 0]r
#Tint.RGB<255,0,0 (#FF0000)>
```

Using hex codes:

```elixir
iex> Tint.RGB.from_hex("#FF0000")
{:ok, #Tint.RGB<255,0,0 (#FF0000)>}

iex> Tint.RGB.from_hex("#F00")
{:ok, #Tint.RGB<255,0,0 (#FF0000)>}

iex> Tint.RGB.from_hex("FF0000")
{:ok, #Tint.RGB<255,0,0 (#FF0000)>}

iex> Tint.RGB.from_hex!("F00")
#Tint.RGB<255,0,0 (#FF0000)>

iex> Tint.RGB.from_hex("invalid")
:error

iex> Tint.RGB.from_hex!("invalid")
** (ArgumentError) Invalid hex code: invalid
```

or

```elixir
iex> import Tint.Sigil
...> ~K[#FF0000]
#Tint.RGB<255,0,0 (#FF0000)>
```

To convert RGB colors back to hex codes:

```elixir
iex> color = Tint.RGB.new(255, 0, 0)
...> Tint.RGB.to_hex(color)
"#FF0000"
```

#### CMYK

```elixir
iex> Tint.CMYK.new(0.55, 0.26, 0.24, 0.65)
#Tint.CMYK<55%,26%,24%,65%>
```

or

```elixir
iex> import Tint.Sigil
...> ~K[0.55, 0.26, 0.24, 0.65]c
#Tint.CMYK<55%,26%,24%,65%>
```

#### HSV

```elixir
iex> Tint.HSV.new(25.8, 0.882, 1)
#Tint.HSV<25.8°,88.2%,100%>
```

or

```elixir
iex> import Tint.Sigil
...> ~K[25.8, 0.882, 1]h
#Tint.HSV<25.8°,88.2%,100%>
```

#### CIELAB

```elixir
iex> Tint.Lab.new(53.2329, 80.1068, 67.2202)
#Tint.Lab<53.2329,80.1068,67.2202>
```

or

```elixir
iex> import Tint.Sigil
...> ~K[53.2329, 80.1068, 67.2202]c
#Tint.Lab<53.2329,80.1068,67.2202>
```

#### DIN99

```elixir
iex> Tint.DIN99.new(53.2329, 80.1068, 67.2202)
#Tint.DIN99<53.2329,80.1068,67.2202>
```

or

```elixir
iex> import Tint.Sigil
...> ~K[53.2329, 80.1068, 67.2202]d
#Tint.DIN99<53.2329,80.1068,67.2202>
```

### Conversion

```elixir
iex> rgb = Tint.RGB.new(255, 0, 0)
...> Tint.to_hsv(rgb)
#Tint.HSV<0°,100%,100%>
```

The complete list:

```elixir
Tint.to_cmyk(color)
Tint.to_din99(color)
Tint.to_hsv(color)
Tint.to_lab(color)
Tint.to_rgb(color)
Tint.to_xyz(color)
```

Alternatively you can use `convert/2` and `convert!/2`:

```elixir
Tint.convert(color, :rgb)
Tint.convert(color, Tint.RGB)
Tint.convert!(color, :hsv)
```

Currently, only RGB can be converted to any other colorspace.

### Color Distance

There are a couple of functions to calculate the distance between two colors.

#### Euclidean Distance

The
[Euclidean distance](https://en.wikipedia.org/wiki/Color_difference#Euclidean)
can be calculated on RGB colors. Calculating the Euclidean distance is very fast
but may not be very precise. If you want maximum precision use the CIEDE2000
algorithm.

```elixir
iex> Tint.RGB.euclidean_distance(~K[#FFFFFF], ~K[#000000])
441.6729559300637
```

You can also define weights for the individual red, green and blue color
channels:

```elixir
iex> Tint.RGB.euclidean_distance(~K[#FFFFFF], ~K[#000000], weights: {2, 4, 3})
765.0
```

To find the nearest color from a given palette:

```elixir
iex> Tint.RGB.nearest_color(~K[#CC0000], [~K[#009900], ~K[#FF0000]])
#Tint.RGB<255,0,0 (#FF0000)>
```

#### CIEDE2000

[CIEDE2000](https://en.wikipedia.org/wiki/Color_difference#CIEDE2000) is an
algorithm that operates on the CIELAB colorspace. It is very slow compared to
the Euclidean distance algorithm but it is optimized to human color perception.

```elixir
iex> Tint.Lab.ciede2000_distance(~K[#FF0000], ~K[#000000])
50.3905024704449
```

To find the nearest color from a given palette:

```elixir
iex> Tint.Lab.nearest_color(~K[#FF0000], [~K[#009900], ~K[#CC0000]])
#Tint.RGB<204,0,0 (#CC0000)>
```

### Complementary Color

```elixir
iex> Tint.RGB.complementary_color(~K[#FF0000])
#Tint.RGB<0,255,255 (#00FFFF)>
```

## Docs

The API docs can be found at [HexDocs](https://hexdocs.pm/tint).