Metadata-Version: 2.4
Name: oklab
Version: 0.4.0
Summary: lightweight python implementation of Björn Ottosson's oklab colour space
Project-URL: Homepage, https://github.com/deftasparagusanaconda/oklab
Project-URL: Repository, https://github.com/deftasparagusanaconda/oklab
Project-URL: Issues, https://github.com/deftasparagusanaconda/oklab/issues
Author: deftasparagusanaconda
License-Expression: MIT
License-File: LICENSE
Keywords: color,colour,oklab,oklch
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Multimedia :: Graphics
Requires-Python: >=3.8
Description-Content-Type: text/markdown

lightweight python implementation of [Björn Ottosson](https://bottosson.github.io/)'s oklab/oklch colour space

i like oklab but there isnt a straightforward python package for it, so i made it

![gamut no clamp demo](<https://github.com/deftasparagusanaconda/oklab/blob/main/demos/gamut no clamp.webp>)  
![gamut hull demo](<https://github.com/deftasparagusanaconda/oklab/blob/main/demos/gamut hull demo.webp>)  
![gamut clamp demo](<https://github.com/deftasparagusanaconda/oklab/blob/main/demos/gamut clamp demo.webp>)  

# install

install it from [PyPI](https://pypi.org/project/oklab/):

```sh
python -m pip install oklab
```

# how to use?

use it in python:

```python
import oklab

oklab.lch_to_hex((0.75, 0.125, 310.0))
# '#c697e9'

oklab.hex_to_lch('#ff0000')
# (0.6279536182521783, 0.25762679148825324, 29.227131291763712)

oklab.lab_to_xyz((1.0, 0.0, 0.0))
# (0.9504559270516719, 0.9999999999999998, 1.0890577507598782)
```

or use it in the terminal:

```shell
> oklab -i lch -o hex 0.75 0.125 310
#c697e9

> oklch ff0000
(0.6279536182521783 0.25762679148825324 29.227131291763712)

> oklab -i lab -o xyz 1.0 0.0 0.0
(0.9504559270516719, 0.9999999999999998, 1.0890577507598782)
```

try this fancy demo!

```python
import os, oklab
C, R = os.get_terminal_size()
for row in range(R - 1, -1, -1):
    string = []
    for col in range(C):
        l = row / (R - 1) * 0.85 + 0.15
        c = 0.125
        h = col / (C - 1) * 360
        colour = oklab.lch_to_rgb((l, c, h))
        if not all(0 < c < 1 for c in colour):
			# out of gamut
            string.append(f' ')
            continue
        r, g, b = tuple(round(c * 255) for c in colour)
        string.append(f'\x1b[38;2;{r};{g};{b}m█')
    print(''.join(string))
```

# features

- ✅ 8 formats: `oklab`, `oklch`, `hex`, `srgb`, `dp3`, `bt2020`, `xyz`, `lms`
- ✅ 26 conversion functions
- ✅ high numerical stability
- ✅ zero dependencies
- ✅ python ≥3.8 compatibility
- ✅ sRGB, Display P3, ITU-R BT.2020 (Rec. 2020) support
- ✅ clamping: chroma reduction (default), point projection

- 🚧 CLI convenience tools (still being polished)
- 🚧 reference-grade correctness (not yet verified by Björn & CSSWG)
- 🚧 clamping: MINDE, CSS-style JND approximation

- ❌ CMYK support (non-RGB spaces and ICC profiles cause scope creep)

# sources

- function names inspired by [hsluv](https://github.com/hsluv/hsluv-python)
- outputs sanity-checked against [oklch.com](https://oklch.com/) and [wikipedia](https://en.wikipedia.org/wiki/Oklab_color_space)
- `M0` sourced from [Björn's CSSWG comment](https://github.com/w3c/csswg-drafts/issues/6642#issuecomment-945714988)
- `M2_inv` sourced from [Björn's blogpost](https://bottosson.github.io/posts/oklab/)
- matrices sourced from [colour science](https://www.colour-science.org/)
- `M1`, `M1_inv`, `M2`, … derived numerically using [numpy](https://github.com/numpy/numpy)
- `test_oklab.test_xyz` sourced from [Björn's blogpost](https://bottosson.github.io/posts/oklab/)

# conversions

the following conversions are maintained:

![graph of formats and conversions](https://github.com/deftasparagusanaconda/oklab/blob/main/graph.png)  

trivial non-oklab-related conversions such as srgb_to_xyz are not included.
