Metadata-Version: 2.4
Name: chromaverse
Version: 0.1.0
Summary: Bibliotheque Python exhaustive pour tout ce qui touche a la couleur : espaces colorimetriques, manipulation, harmonies, science perceptuelle, accessibilite et extraction depuis des images.
Author: Loup0007A
License: MIT
Project-URL: Homepage, https://github.com/chromaverse/chromaverse
Project-URL: Documentation, https://github.com/chromaverse/chromaverse#readme
Project-URL: Repository, https://github.com/chromaverse/chromaverse
Project-URL: Issues, https://github.com/chromaverse/chromaverse/issues
Project-URL: Changelog, https://github.com/chromaverse/chromaverse/blob/main/CHANGELOG.md
Keywords: color,couleur,rgb,hsv,hsl,lab,oklab,cmyk,colorimetry,palette,design-system,accessibility,wcag,color-science,delta-e,colorblindness,image-processing
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: Topic :: Multimedia :: Graphics
Classifier: Topic :: Scientific/Engineering :: Visualization
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Operating System :: OS Independent
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.22
Provides-Extra: vision
Requires-Dist: Pillow>=9.0; extra == "vision"
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0; extra == "dev"
Requires-Dist: build>=1.0; extra == "dev"
Requires-Dist: twine>=4.0; extra == "dev"
Requires-Dist: Pillow>=9.0; extra == "dev"
Dynamic: license-file

# chromaverse

**La boite a outils Python complete pour tout ce qui touche a la couleur.**

`chromaverse` reunit en une seule bibliotheque tout ce dont vous avez besoin
pour manipuler des couleurs : conversions entre espaces colorimetriques
(vectorisees avec numpy), manipulation et melange, harmonies et generation
de palettes, science perceptuelle (Delta E, contraste WCAG), accessibilite
et design systems, et extraction de couleurs depuis des images.

```python
import chromaverse as cc

c = cc.Color("#3498db")
c.lighten(0.15).hex            # '#75B9E7'
c.complementary().hex          # '#DB7734'
cc.wcag_contrast(c, "white")   # 3.15
c.simulate_colorblindness("deuteranopia").hex  # '#5A52C7'
```

---

## Sommaire

- [Installation](#installation)
- [Demarrage rapide](#demarrage-rapide)
- [La classe `Color`](#la-classe-color)
- [Espaces colorimetriques](#espaces-colorimetriques)
- [Manipulation](#manipulation)
- [Harmonies et palettes](#harmonies-et-palettes)
- [Science de la couleur](#science-de-la-couleur)
- [Accessibilite et design systems](#accessibilite-et-design-systems)
- [Vision par ordinateur](#vision-par-ordinateur)
- [Fonctions basiques et utilitaires](#fonctions-basiques-et-utilitaires)
- [Reference API condensee](#reference-api-condensee)
- [Performance et vectorisation](#performance-et-vectorisation)
- [Developpement](#developpement)
- [Licence](#licence)

---

## Installation

```bash
pip install chromaverse
```

Le module d'extraction de couleurs depuis des images (`chromaverse.vision`)
necessite [Pillow](https://pypi.org/project/Pillow/) :

```bash
pip install chromaverse[vision]
```

Seule dependance obligatoire : [numpy](https://numpy.org/) (`>=1.22`).
Compatible Python 3.9+.

---

## Demarrage rapide

```python
import chromaverse as cc
from chromaverse import Color

# Construire une couleur de tres nombreuses manieres
Color("#3498db")
Color("cornflowerblue")
Color(52, 152, 219)
Color.from_hsl(204, 0.70, 0.53)
Color.from_lab(60.16, -6.10, -42.23)

c = Color("#3498db")
print(c.hex, c.rgb, c.hsl, c.lab)
```

---

## La classe `Color`

`Color` est **immuable** : chaque transformation retourne une nouvelle
instance, l'originale n'est jamais modifiee.

### Constructeurs

```python
Color("#FF0000")                 # hex (avec ou sans '#', forme courte ou longue)
Color("#FF000080")               # hex avec alpha
Color("red")                     # nom CSS (148 couleurs supportees)
Color(255, 0, 0)                 # RGB 0-255
Color(1.0, 0.0, 0.0)             # RGB 0-1
Color.from_rgb(255, 0, 0)
Color.from_hsv(0, 1, 1)
Color.from_hsl(0, 1, 0.5)
Color.from_hsi(0, 1, 0.33)
Color.from_hwb(0, 0, 0)
Color.from_cmyk(0, 1, 1, 0)
Color.from_cmy(0, 1, 1)
Color.from_xyz(0.4124, 0.2127, 0.0193)
Color.from_lab(53.24, 80.09, 67.20)
Color.from_lch(53.24, 104.55, 40.0)
Color.from_luv(53.24, 175.0, 37.76)
Color.from_oklab(0.628, 0.225, 0.126)
Color.from_oklch(0.628, 0.258, 29.2)
Color.from_yuv(0.299, -0.147, 0.615)
Color.from_yiq(0.299, 0.596, 0.211)
Color.from_ycbcr(76, 84.4, 255)
Color.from_kelvin(2700)          # lumiere chaude (ampoule)
Color.random()
Color.random_pastel()
Color.random_dark()
```

### Proprietes de lecture

```python
c.rgb        # (52, 152, 219)        0-255
c.rgba       # (52, 152, 219, 255)
c.rgb01      # (0.204, 0.596, 0.859) 0-1
c.hex        # '#3498DB'
c.hexa       # avec alpha
c.hsv / c.hsl / c.hsi / c.hwb
c.cmyk / c.cmy
c.xyz / c.lab / c.lch / c.luv
c.oklab / c.oklch
c.yuv / c.yiq / c.ycbcr
c.kelvin     # temperature de couleur correlee estimee
c.name       # nom CSS exact si correspondance parfaite, sinon None
c.nearest_name()  # nom CSS le plus proche
```

### Methodes

```python
c.lighten(0.1) / c.darken(0.1)
c.saturate(0.1) / c.desaturate(0.1)
c.invert() / c.grayscale()
c.rotate_hue(180)
c.mix(other, ratio=0.5, space="lab")     # 'rgb' | 'hsl' | 'lab' | 'oklab'
c.blend(other, mode="multiply")          # 12 modes de fusion
c.complementary()
c.with_alpha(0.5)

c.luminance()                  # luminance relative WCAG
c.contrast_ratio(other)        # ratio de contraste WCAG
c.delta_e(other, method="cie2000")
c.is_dark() / c.is_light()
c.best_text_color()            # noir ou blanc, selon le meilleur contraste
c.simulate_colorblindness("protanopia")
```

---

## Espaces colorimetriques

Toutes les fonctions de conversion sont **entierement vectorisees** : elles
acceptent un triplet unique ou un tableau numpy `(..., 3)`, par exemple une
image complete `(H, W, 3)`, sans changer de code.

```python
import numpy as np
from chromaverse import conversions as spaces

# Une seule couleur
spaces.rgb_to_lab([0.8, 0.2, 0.4])
# array([47.99, 56.0, 4.6])

# Une image entiere (H, W, 3) en une seule passe vectorisee
image = np.random.rand(256, 256, 3)
lab_image = spaces.rgb_to_lab(image)        # (256, 256, 3)
back = spaces.lab_to_rgb(lab_image)         # (256, 256, 3)
```

Espaces supportes (conversion bidirectionnelle avec RGB) :

| Espace | Fonctions | Notes |
|---|---|---|
| HEX | `hex_to_rgb`, `rgb_to_hex` | court/long, avec/sans alpha |
| HSV | `rgb_to_hsv`, `hsv_to_rgb` | H en degres [0,360) |
| HSL | `rgb_to_hsl`, `hsl_to_rgb` | |
| HSI | `rgb_to_hsi`, `hsi_to_rgb` | Hue/Saturation/Intensity |
| HWB | `rgb_to_hwb`, `hwb_to_rgb` | CSS Color Module 4 |
| CMY / CMYK | `rgb_to_cmy(k)`, `cmy(k)_to_rgb` | impression |
| XYZ | `rgb_to_xyz`, `xyz_to_rgb` | reference D65 |
| Lab (CIE 1976) | `rgb_to_lab`, `lab_to_rgb` | perceptuellement uniforme |
| LCh(ab) | `rgb_to_lch`, `lch_to_rgb` | Lab en coordonnees polaires |
| Luv (CIE 1976) | `rgb_to_luv`, `luv_to_rgb` | |
| YUV | `rgb_to_yuv`, `yuv_to_rgb` | analogique, BT.601 |
| YIQ | `rgb_to_yiq`, `yiq_to_rgb` | NTSC |
| YCbCr | `rgb_to_ycbcr`, `ycbcr_to_rgb` | numerique, JPEG/BT.601 |
| Oklab / Oklch | `rgb_to_oklab(ch)`, `oklab(ch)_to_rgb` | Ottosson 2020, tres uniforme |
| Kelvin | `kelvin_to_rgb`, `rgb_to_kelvin` | corps noir, approximation |

Fonctions de linearisation gamma egalement disponibles :
`srgb_to_linear`, `linear_to_srgb`.

---

## Manipulation

```python
from chromaverse import Color

c = Color("#3498db")

c.lighten(0.15)         # eclaircit (L de HSL)
c.darken(0.15)
c.saturate(0.2)
c.desaturate(0.2)
c.invert()              # negatif photographique
c.grayscale()           # ponderation ITU-R BT.601
c.rotate_hue(45)        # roue chromatique

c.mix("#e67e22", 0.5, space="lab")   # melange perceptuellement uniforme
c.blend("#e67e22", "multiply")       # mode de fusion type Photoshop
```

Modes de fusion disponibles dans `blend()` :
`normal`, `multiply`, `screen`, `overlay`, `darken`, `lighten`, `difference`,
`exclusion`, `color-dodge`, `color-burn`, `soft-light`, `hard-light`.

Fonctions additionnelles dans `chromaverse.manipulate` :
`adjust_brightness`, `adjust_contrast`, `tint` (melange avec du blanc),
`shade` (melange avec du noir), `tone` (melange avec du gris).

---

## Harmonies et palettes

```python
from chromaverse import Color
import chromaverse as cc

c = Color("#3498db")

cc.complementary(c)              # 1 couleur, +180°
cc.analogous(c, count=5)          # voisines sur la roue
cc.triadic(c)                     # 3 couleurs a 120°
cc.tetradic(c)                    # 4 couleurs (rectangle)
cc.square(c)                      # 4 couleurs a 90°
cc.split_complementary(c)         # complementaire divisee
cc.monochromatic(c, count=5)      # meme teinte, luminosite variable

cc.generate_palette(c, "triadic")            # dispatch generique
cc.generate_palette(c, "analogous", count=7, spread=15)
```

### Degrades, echelles UI et palettes generees

```python
cc.gradient(Color("red"), Color("blue"), steps=10, space="lab")
cc.multi_gradient([Color("red"), Color("white"), Color("blue")])

cc.ui_scale(c)        # {50: Color, 100: Color, ..., 900: Color} façon Tailwind
cc.distinct_colors(8) # 8 couleurs visuellement distinctes (angle dore)
```

### La classe `Palette`

```python
from chromaverse import Palette

p = Palette(["#FF0000", "#00FF00", "#0000FF"])
p.sort_by_hue()
p.to_css_variables(prefix="brand")
# :root {
#   --brand-0: #FF0000;
#   ...
# }
p.to_scss_variables(prefix="brand")
p.to_json()
p.most_accessible_pairs()   # audit WCAG de toutes les paires
```

---

## Science de la couleur

```python
import chromaverse as cc

cc.relative_luminance((0.2, 0.6, 0.9))   # luminance relative WCAG
cc.contrast_ratio((1,1,1), (0,0,0))      # 21.0

lab1, lab2 = Color("#3498db").lab, Color("#e67e22").lab
cc.delta_e_cie76(lab1, lab2)
cc.delta_e_cie94(lab1, lab2)
cc.delta_e_cie2000(lab1, lab2)           # recommande (le plus precis)
cc.delta_e(lab1, lab2, method="cie2000")

cc.color_temperature_to_rgb(2700)        # lumiere chaude -> RGB
cc.rgb_to_color_temperature((1, 1, 1))   # RGB -> CCT estimee (formule McCamy)

cc.dominant_wavelength((1, 0, 0))        # ~645 nm (approximation, rouge)
```

> **Note sur la temperature de couleur** : l'estimation `rgb_to_kelvin` /
> `rgb_to_color_temperature` (formule de McCamy) n'est fiable que pour des
> couleurs proches du locus de corps noir (blancs, gris, eclairages). Sur une
> couleur tres saturee, la valeur retournee n'a pas de sens physique.

---

## Accessibilite et design systems

```python
import chromaverse as cc

cc.wcag_contrast("#3498db", "#FFFFFF")          # 3.15
cc.meets_wcag_aa("#3498db", "#FFFFFF")          # False
cc.meets_wcag_aaa("#000000", "#FFFFFF")         # True
cc.wcag_level("#3498db", "#FFFFFF")             # 'Fail' | 'AA' | 'AAA'

cc.suggest_text_color("#3498db")                # Color('#000000') ou blanc
cc.suggest_text_color("#3498db", light="#FAFAFA", dark="#111111")

cc.simulate_colorblindness("#3498db", "deuteranopia")
# 'protanopia', 'deuteranopia', 'tritanopia', 'achromatopsia'

cc.check_palette_accessibility(["#FFFFFF", "#000000", "#3498db"])
# [{'pair': ('#FFFFFF', '#000000'), 'ratio': 21.0, 'level': 'AAA'}, ...]
```

---

## Vision par ordinateur

Necessite `pip install chromaverse[vision]` (ajoute Pillow).

```python
import chromaverse as cc

palette = cc.extract_palette("photo.jpg", n_colors=5)   # k-means numpy pur
dominant = cc.dominant_color("photo.jpg")
moyenne = cc.average_color("photo.jpg")
hist = cc.image_histogram("photo.jpg", bins=16)
# {'r': array(16), 'g': array(16), 'b': array(16), 'bin_edges': array(17)}
```

`extract_palette` accepte un chemin de fichier, une `PIL.Image`, ou un
tableau numpy `(H, W, 3)`.

---

## Fonctions basiques et utilitaires

```python
import chromaverse as cc

cc.is_valid_hex("#3498db")          # True
cc.normalize_hex("#3ab")            # '#33AABB'
cc.parse_color("cornflowerblue")    # (0.39, 0.58, 0.93, 1.0)
cc.random_hex()                     # '#A3F21C'
cc.nearest_named_color((0.2, 0.6, 0.86))  # 'dodgerblue'
cc.get_named_color("tomato")        # '#FF6347'
cc.all_named_colors()               # dict des 148 couleurs CSS/X11
```

---

## Reference API condensee

```
chromaverse
├── Color, Palette                       # objets coeur
├── conversions (alias: spaces)          # *_to_* vectorises numpy
├── manipulate                           # lighten, mix, blend, ...
├── harmony                              # complementary, triadic, ...
├── palette                              # gradient, ui_scale, distinct_colors
├── science                              # luminance, delta_e, kelvin, ...
├── accessibility                        # wcag_*, simulate_colorblindness, ...
├── vision                               # extract_palette, dominant_color, ...
├── utils                                # parse_color, clamp, random_hex, ...
├── named_colors                         # CSS_NAMED_COLORS, get_named_color
└── exceptions                           # ChromaError et sous-classes
```

---

## Performance et vectorisation

Le module `chromaverse.conversions` est concu pour fonctionner aussi bien
sur une couleur unique que sur une image complete, sans aucune boucle
Python : toutes les operations sont des operations numpy vectorisees.

```python
import numpy as np
from chromaverse import conversions as spaces

image = np.random.rand(1080, 1920, 3)   # image Full HD
lab = spaces.rgb_to_lab(image)          # conversion de 2M de pixels en une passe
```

La classe `Color`, en revanche, est concue pour la clarte d'usage (couleur
par couleur) plutot que pour la performance brute sur de gros volumes :
pour traiter des images ou de grands tableaux, preferer directement les
fonctions de `chromaverse.conversions` / `chromaverse.accessibility` (qui
exposent des variantes vectorisees comme `simulate_colorblindness_batch`).

---

## Developpement

```bash
git clone https://github.com/chromaverse/chromaverse.git
cd chromaverse
pip install -e ".[dev]"

pytest                          # suite de tests (254 tests)
pytest --cov=chromaverse        # avec couverture (95%)

python -m build                 # construire sdist + wheel
twine check dist/*              # valider avant publication
```

### Publier sur PyPI

```bash
python -m build
twine check dist/*
twine upload dist/*             # ou --repository testpypi pour tester d'abord
```

Pensez a verifier au prealable que le nom `chromaverse` est toujours
disponible sur [pypi.org](https://pypi.org), et a incrementer la version
dans `pyproject.toml` et `chromaverse.__version__` (fichier
`src/chromaverse/__init__.py`) avant chaque publication.

---

## Licence

MIT - voir [LICENSE](LICENSE).

Contributions bienvenues : ouvrez une issue ou une pull request.
