colorium 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- colorium-1.0.0/PKG-INFO +358 -0
- colorium-1.0.0/README.md +329 -0
- colorium-1.0.0/pyproject.toml +68 -0
- colorium-1.0.0/setup.cfg +4 -0
- colorium-1.0.0/src/colorium/__init__.py +98 -0
- colorium-1.0.0/src/colorium/color.py +1187 -0
- colorium-1.0.0/src/colorium/constants.py +463 -0
- colorium-1.0.0/src/colorium/constants_colors.py +390 -0
- colorium-1.0.0/src/colorium/converters.py +994 -0
- colorium-1.0.0/src/colorium/core.py +535 -0
- colorium-1.0.0/src/colorium/filter_base.py +324 -0
- colorium-1.0.0/src/colorium/filters.py +736 -0
- colorium-1.0.0/src/colorium/utils.py +199 -0
- colorium-1.0.0/src/colorium.egg-info/PKG-INFO +358 -0
- colorium-1.0.0/src/colorium.egg-info/SOURCES.txt +24 -0
- colorium-1.0.0/src/colorium.egg-info/dependency_links.txt +1 -0
- colorium-1.0.0/src/colorium.egg-info/requires.txt +7 -0
- colorium-1.0.0/src/colorium.egg-info/top_level.txt +1 -0
- colorium-1.0.0/tests/test_color.py +350 -0
- colorium-1.0.0/tests/test_color_formats.py +296 -0
- colorium-1.0.0/tests/test_constants.py +414 -0
- colorium-1.0.0/tests/test_converters.py +315 -0
- colorium-1.0.0/tests/test_core.py +262 -0
- colorium-1.0.0/tests/test_distance.py +305 -0
- colorium-1.0.0/tests/test_filters.py +793 -0
- colorium-1.0.0/tests/test_utils.py +203 -0
colorium-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: colorium
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: A comprehensive color manipulation library for Python
|
|
5
|
+
Author-email: Abolfazl Hosseini <tryuzr@gmail.com>
|
|
6
|
+
License: MIT License
|
|
7
|
+
Project-URL: Source Code, https://github.com/inject3r/colorium
|
|
8
|
+
Project-URL: Bug Tracker, https://github.com/inject3r/colorium/issues
|
|
9
|
+
Project-URL: Documentation, https://inject3r.github.io/colorium
|
|
10
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
20
|
+
Classifier: Operating System :: OS Independent
|
|
21
|
+
Requires-Python: >=3.8
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
Provides-Extra: dev
|
|
24
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
25
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
26
|
+
Requires-Dist: black>=22.0.0; extra == "dev"
|
|
27
|
+
Requires-Dist: flake8>=5.0.0; extra == "dev"
|
|
28
|
+
Requires-Dist: mypy>=0.990; extra == "dev"
|
|
29
|
+
|
|
30
|
+
# Colorium
|
|
31
|
+
|
|
32
|
+
[](https://www.python.org/downloads/)
|
|
33
|
+
[](LICENSE)
|
|
34
|
+
[](https://github.com/inject3r/colorium)
|
|
35
|
+
|
|
36
|
+
A comprehensive, pure Python color manipulation library with support for 10+ color spaces, filters, and color distance calculations.
|
|
37
|
+
|
|
38
|
+
## Features
|
|
39
|
+
|
|
40
|
+
- **10+ Color Spaces**: RGB, HSL, HWB, CMYK, NCOL, OKLCH, LAB, LCH, Display P3
|
|
41
|
+
- **Color Filters**: Sepia, Grayscale, Invert, Contrast, Brightness, Saturation, Hue Rotation, Posterize, Temperature, Vignette
|
|
42
|
+
- **Filter Presets**: Clarendon, Gingham, Moon, Lark, Toaster, Valencia, Amaro (Instagram-style)
|
|
43
|
+
- **Color Distance**: CIE76, CIE94, CIEDE2000 (industry standard)
|
|
44
|
+
- **Color Similarity**: Perceptual similarity scoring (0.0 to 1.0)
|
|
45
|
+
- **Named Colors**: All 147 CSS named colors with case-insensitive lookup
|
|
46
|
+
- **Color Constants**: RED, BLUE, GREEN, WHITE, BLACK, and 100+ more
|
|
47
|
+
- **Multiple Formats**: Hex, RGB, HSL, HWB, CMYK, NCOL, OKLCH, LAB, LCH, P3
|
|
48
|
+
- **Zero Dependencies**: Pure Python, no external libraries required
|
|
49
|
+
|
|
50
|
+
## Installation
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
# Install from PyPI (when published)
|
|
54
|
+
pip install colorium
|
|
55
|
+
|
|
56
|
+
# Install in development mode
|
|
57
|
+
git clone https://github.com/inject3r/colorium.git
|
|
58
|
+
cd colorium
|
|
59
|
+
pip install -e ".[dev]"
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Quick Start
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
from colorium import Color, from_string, RED, BLUE, WHITE, BLACK
|
|
66
|
+
|
|
67
|
+
# Create colors from various formats
|
|
68
|
+
red = Color(255, 0, 0)
|
|
69
|
+
blue = from_string("blue")
|
|
70
|
+
hex_color = from_string("#FF0000")
|
|
71
|
+
named = from_string("crimson")
|
|
72
|
+
|
|
73
|
+
# Use color constants
|
|
74
|
+
bg = WHITE
|
|
75
|
+
text = BLACK
|
|
76
|
+
primary = RED
|
|
77
|
+
secondary = BLUE
|
|
78
|
+
|
|
79
|
+
# Convert between color spaces
|
|
80
|
+
print(red.to_hsl_string()) # hsl(0, 100%, 50%)
|
|
81
|
+
print(red.to_hwb_string()) # hwb(0, 0%, 0%)
|
|
82
|
+
print(red.to_hex_string()) # #FF0000
|
|
83
|
+
print(red.to_cmyk_string()) # cmyk(0%, 100%, 100%, 0%)
|
|
84
|
+
|
|
85
|
+
# Get color values
|
|
86
|
+
hsl = red.to_hsl() # {'h': 0, 's': 1.0, 'l': 0.5}
|
|
87
|
+
rgb = red.to_rgb() # {'r': 255, 'g': 0, 'b': 0}
|
|
88
|
+
|
|
89
|
+
# Manipulate colors
|
|
90
|
+
red.lighter(0.3) # Make brighter
|
|
91
|
+
red.darker(0.2) # Make darker
|
|
92
|
+
red.saturate(0.5) # Increase saturation
|
|
93
|
+
red.desaturate(0.3) # Decrease saturation
|
|
94
|
+
|
|
95
|
+
# Check if color is dark
|
|
96
|
+
if red.is_dark():
|
|
97
|
+
print("Dark color!")
|
|
98
|
+
|
|
99
|
+
# Get color name
|
|
100
|
+
print(red.to_name()) # "Red"
|
|
101
|
+
|
|
102
|
+
# Blend colors
|
|
103
|
+
purple = RED.blend(BLUE, 0.5) # Equal blend
|
|
104
|
+
pink = RED.blend(WHITE, 0.7) # 70% white blend
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Color Filters
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
from colorium import (
|
|
111
|
+
Color,
|
|
112
|
+
SepiaFilter,
|
|
113
|
+
GrayscaleFilter,
|
|
114
|
+
ContrastFilter,
|
|
115
|
+
BrightnessFilter,
|
|
116
|
+
FilterPresets
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
color = Color(200, 150, 100)
|
|
120
|
+
|
|
121
|
+
# Single filter
|
|
122
|
+
sepia = SepiaFilter(0.7)
|
|
123
|
+
result = sepia(color)
|
|
124
|
+
|
|
125
|
+
# Chain filters
|
|
126
|
+
from colorium import CompositeFilter
|
|
127
|
+
vintage = CompositeFilter([
|
|
128
|
+
SepiaFilter(0.5),
|
|
129
|
+
ContrastFilter(1.1),
|
|
130
|
+
BrightnessFilter(0.9)
|
|
131
|
+
])
|
|
132
|
+
vintage_result = vintage(color)
|
|
133
|
+
|
|
134
|
+
# Use presets
|
|
135
|
+
clarendon = FilterPresets.clarendon()
|
|
136
|
+
clarendon_result = clarendon(color)
|
|
137
|
+
|
|
138
|
+
moon = FilterPresets.moon() # Black and white
|
|
139
|
+
moon_result = moon(color)
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Color Distance and Similarity
|
|
143
|
+
|
|
144
|
+
```python
|
|
145
|
+
from colorium import Color
|
|
146
|
+
|
|
147
|
+
color1 = Color(100, 150, 200)
|
|
148
|
+
color2 = Color(120, 130, 180)
|
|
149
|
+
|
|
150
|
+
# Calculate color difference (Delta E)
|
|
151
|
+
distance = color1.delta_e(color2, "cie2000")
|
|
152
|
+
print(f"Delta E: {distance:.2f}")
|
|
153
|
+
|
|
154
|
+
# Get similarity score (0.0 to 1.0)
|
|
155
|
+
similarity = color1.similarity(color2)
|
|
156
|
+
print(f"Similarity: {similarity:.2f}")
|
|
157
|
+
|
|
158
|
+
# Check if colors are similar
|
|
159
|
+
if color1.is_similar_to(color2, threshold=0.8):
|
|
160
|
+
print("Colors are very similar!")
|
|
161
|
+
|
|
162
|
+
# Different methods available
|
|
163
|
+
cie76 = color1.delta_e(color2, "cie76")
|
|
164
|
+
cie94 = color1.delta_e(color2, "cie94")
|
|
165
|
+
cie2000 = color1.delta_e(color2, "cie2000")
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## Modern Color Spaces (CSS Color Level 4)
|
|
169
|
+
|
|
170
|
+
```python
|
|
171
|
+
from colorium import Color
|
|
172
|
+
|
|
173
|
+
# OKLCH - Perceptually uniform
|
|
174
|
+
color = Color.from_oklch(0.5, 0.2, 180)
|
|
175
|
+
print(color.to_oklch_string()) # oklch(50.0% 0.200 180.0)
|
|
176
|
+
|
|
177
|
+
# CIE L*a*b*
|
|
178
|
+
color = Color.from_lab(50, 20, -30)
|
|
179
|
+
print(color.to_lab_string()) # lab(50.0% 20.0 -30.0)
|
|
180
|
+
|
|
181
|
+
# CIE LCH
|
|
182
|
+
color = Color.from_lch(50, 30, 180)
|
|
183
|
+
print(color.to_lch_string()) # lch(50.0% 30.0 180.0)
|
|
184
|
+
|
|
185
|
+
# Display P3 Wide Gamut
|
|
186
|
+
color = Color.from_p3(0.8, 0.3, 0.5)
|
|
187
|
+
print(color.to_p3_string()) # color(display-p3 0.800 0.300 0.500)
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## Color Constants
|
|
191
|
+
|
|
192
|
+
```python
|
|
193
|
+
from colorium import (
|
|
194
|
+
RED, BLUE, GREEN, WHITE, BLACK,
|
|
195
|
+
SUCCESS, ERROR, WARNING, INFO,
|
|
196
|
+
FACEBOOK_BLUE, TWITTER_BLUE, YOUTUBE_RED,
|
|
197
|
+
ORANGE, PURPLE, PINK, BROWN,
|
|
198
|
+
LIGHT_BLUE, DARK_BLUE, NAVY, ROYAL_BLUE,
|
|
199
|
+
LIGHT_GREEN, DARK_GREEN, FOREST_GREEN,
|
|
200
|
+
TRANSPARENT
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
# Use constants directly
|
|
204
|
+
status = SUCCESS if valid else ERROR
|
|
205
|
+
bg = WHITE
|
|
206
|
+
text = BLACK
|
|
207
|
+
|
|
208
|
+
# Blend constants
|
|
209
|
+
purple = RED.blend(BLUE, 0.5)
|
|
210
|
+
|
|
211
|
+
# Use as defaults
|
|
212
|
+
def create_button(text: str, color: Color = PRIMARY):
|
|
213
|
+
return {"text": text, "color": color}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## API Reference
|
|
217
|
+
|
|
218
|
+
### Color Class
|
|
219
|
+
|
|
220
|
+
| Method | Description |
|
|
221
|
+
| -------------------------------------- | ------------------------------------------ |
|
|
222
|
+
| `Color(red, green, blue, opacity=1.0)` | Create from RGB |
|
|
223
|
+
| `to_rgb_string()` | RGB string: `rgb(255, 0, 0)` |
|
|
224
|
+
| `to_rgba_string()` | RGBA string: `rgba(255, 0, 0, 0.5)` |
|
|
225
|
+
| `to_hsl_string()` | HSL string: `hsl(0, 100%, 50%)` |
|
|
226
|
+
| `to_hwb_string()` | HWB string: `hwb(0, 0%, 0%)` |
|
|
227
|
+
| `to_cmyk_string()` | CMYK string: `cmyk(0%, 100%, 100%, 0%)` |
|
|
228
|
+
| `to_hex_string()` | Hex string: `#FF0000` |
|
|
229
|
+
| `to_oklch_string()` | OKLCH string: `oklch(50% 0.2 180)` |
|
|
230
|
+
| `to_lab_string()` | LAB string: `lab(50% 20 -30)` |
|
|
231
|
+
| `to_lch_string()` | LCH string: `lch(50% 30 180)` |
|
|
232
|
+
| `to_p3_string()` | P3 string: `color(display-p3 0.8 0.3 0.5)` |
|
|
233
|
+
| `to_name()` | CSS color name: `"Red"` |
|
|
234
|
+
| `to_rgb()` | RGB dict: `{'r': 255, 'g': 0, 'b': 0}` |
|
|
235
|
+
| `to_hsl()` | HSL dict: `{'h': 0, 's': 1.0, 'l': 0.5}` |
|
|
236
|
+
| `delta_e(other, method)` | Color difference (CIE76, CIE94, CIEDE2000) |
|
|
237
|
+
| `similarity(other, method)` | Similarity score (0.0 to 1.0) |
|
|
238
|
+
| `is_similar_to(other, threshold)` | Check similarity |
|
|
239
|
+
| `blend(other, ratio)` | Blend two colors |
|
|
240
|
+
| `is_dark(threshold=128)` | Check if dark |
|
|
241
|
+
| `saturate(amount)` | Increase saturation |
|
|
242
|
+
| `desaturate(amount)` | Decrease saturation |
|
|
243
|
+
| `lighter(amount)` | Increase lightness |
|
|
244
|
+
| `darker(amount)` | Decrease lightness |
|
|
245
|
+
| `clone()` | Create a copy |
|
|
246
|
+
|
|
247
|
+
### Factory Functions
|
|
248
|
+
|
|
249
|
+
| Function | Description |
|
|
250
|
+
| ------------------------------------ | ---------------------- |
|
|
251
|
+
| `from_string(color_str)` | Parse any color string |
|
|
252
|
+
| `from_hex(hex_str)` | Create from hex |
|
|
253
|
+
| `from_rgb(r, g, b, opacity=1.0)` | Create from RGB |
|
|
254
|
+
| `from_hsl(h, s, l, opacity=1.0)` | Create from HSL |
|
|
255
|
+
| `from_hwb(h, w, b, opacity=1.0)` | Create from HWB |
|
|
256
|
+
| `from_cmyk(c, m, y, k, opacity=1.0)` | Create from CMYK |
|
|
257
|
+
| `from_oklch(l, c, h, opacity=1.0)` | Create from OKLCH |
|
|
258
|
+
| `from_lab(l, a, b, opacity=1.0)` | Create from LAB |
|
|
259
|
+
| `from_lch(l, c, h, opacity=1.0)` | Create from LCH |
|
|
260
|
+
| `from_p3(r, g, b, opacity=1.0)` | Create from P3 |
|
|
261
|
+
|
|
262
|
+
### Filters
|
|
263
|
+
|
|
264
|
+
| Filter | Description |
|
|
265
|
+
| ------------------------------------- | --------------------- |
|
|
266
|
+
| `SepiaFilter(intensity=1.0)` | Warm sepia tone |
|
|
267
|
+
| `GrayscaleFilter(method="luminance")` | Black and white |
|
|
268
|
+
| `InvertFilter()` | Negative effect |
|
|
269
|
+
| `ContrastFilter(amount=1.2)` | Contrast adjustment |
|
|
270
|
+
| `BrightnessFilter(amount=1.2)` | Brightness adjustment |
|
|
271
|
+
| `SaturationFilter(amount=0.5)` | Saturation adjustment |
|
|
272
|
+
| `HueRotateFilter(degrees=90)` | Hue rotation |
|
|
273
|
+
| `PosterizeFilter(levels=4)` | Color quantization |
|
|
274
|
+
| `TemperatureFilter(kelvin=5500)` | Warm/cool shift |
|
|
275
|
+
| `VignetteFilter(intensity=0.5)` | Edge darkening |
|
|
276
|
+
|
|
277
|
+
### Filter Presets
|
|
278
|
+
|
|
279
|
+
| Preset | Description |
|
|
280
|
+
| --------------------------- | ------------------------------------------ |
|
|
281
|
+
| `FilterPresets.clarendon()` | Increased contrast, brightness, saturation |
|
|
282
|
+
| `FilterPresets.gingham()` | Warm, soft vintage |
|
|
283
|
+
| `FilterPresets.moon()` | High-contrast black and white |
|
|
284
|
+
| `FilterPresets.lark()` | Cool, vibrant modern |
|
|
285
|
+
| `FilterPresets.toaster()` | Warm, retro vintage |
|
|
286
|
+
| `FilterPresets.valencia()` | Warm, soft vintage |
|
|
287
|
+
| `FilterPresets.amaro()` | Rich, warm, slightly dark |
|
|
288
|
+
|
|
289
|
+
## Development
|
|
290
|
+
|
|
291
|
+
### Running Tests
|
|
292
|
+
|
|
293
|
+
```bash
|
|
294
|
+
# Run all tests
|
|
295
|
+
pytest
|
|
296
|
+
|
|
297
|
+
# Run with coverage
|
|
298
|
+
pytest --cov=colorium
|
|
299
|
+
|
|
300
|
+
# Run specific test file
|
|
301
|
+
pytest tests/test_color.py
|
|
302
|
+
|
|
303
|
+
# Run specific test
|
|
304
|
+
pytest tests/test_color.py::TestColor::test_initialization
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
### Code Style
|
|
308
|
+
|
|
309
|
+
The project uses:
|
|
310
|
+
|
|
311
|
+
- **Black** for code formatting
|
|
312
|
+
- **Flake8** for linting
|
|
313
|
+
- **Mypy** for type checking
|
|
314
|
+
|
|
315
|
+
```bash
|
|
316
|
+
# Format code
|
|
317
|
+
black src/ tests/
|
|
318
|
+
|
|
319
|
+
# Run linter
|
|
320
|
+
flake8 src/ tests/
|
|
321
|
+
|
|
322
|
+
# Type check
|
|
323
|
+
mypy src/
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
## License
|
|
327
|
+
|
|
328
|
+
MIT License - see [LICENSE](LICENSE) for details.
|
|
329
|
+
|
|
330
|
+
## Author
|
|
331
|
+
|
|
332
|
+
**Abolfazl Hosseini**
|
|
333
|
+
|
|
334
|
+
- Email: tryuzr@gmail.com
|
|
335
|
+
- GitHub: [@inject3r](https://github.com/inject3r)
|
|
336
|
+
|
|
337
|
+
## Links
|
|
338
|
+
|
|
339
|
+
- [Source Code](https://github.com/inject3r/colorium)
|
|
340
|
+
- [Bug Tracker](https://github.com/inject3r/colorium/issues)
|
|
341
|
+
- [Documentation](https://inject3r.github.io/colorium)
|
|
342
|
+
|
|
343
|
+
## Contributing
|
|
344
|
+
|
|
345
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
346
|
+
|
|
347
|
+
1. Fork the repository
|
|
348
|
+
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
|
|
349
|
+
3. Commit your changes (`git commit -m 'Add amazing feature'`)
|
|
350
|
+
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
351
|
+
5. Open a Pull Request
|
|
352
|
+
|
|
353
|
+
## Acknowledgments
|
|
354
|
+
|
|
355
|
+
- CSS Color Module Level 4 specification
|
|
356
|
+
- CIE color science standards
|
|
357
|
+
- Natural Color System (NCS) for NCOL notation
|
|
358
|
+
- Instagram filter effects for inspiration
|
colorium-1.0.0/README.md
ADDED
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
# Colorium
|
|
2
|
+
|
|
3
|
+
[](https://www.python.org/downloads/)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
[](https://github.com/inject3r/colorium)
|
|
6
|
+
|
|
7
|
+
A comprehensive, pure Python color manipulation library with support for 10+ color spaces, filters, and color distance calculations.
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- **10+ Color Spaces**: RGB, HSL, HWB, CMYK, NCOL, OKLCH, LAB, LCH, Display P3
|
|
12
|
+
- **Color Filters**: Sepia, Grayscale, Invert, Contrast, Brightness, Saturation, Hue Rotation, Posterize, Temperature, Vignette
|
|
13
|
+
- **Filter Presets**: Clarendon, Gingham, Moon, Lark, Toaster, Valencia, Amaro (Instagram-style)
|
|
14
|
+
- **Color Distance**: CIE76, CIE94, CIEDE2000 (industry standard)
|
|
15
|
+
- **Color Similarity**: Perceptual similarity scoring (0.0 to 1.0)
|
|
16
|
+
- **Named Colors**: All 147 CSS named colors with case-insensitive lookup
|
|
17
|
+
- **Color Constants**: RED, BLUE, GREEN, WHITE, BLACK, and 100+ more
|
|
18
|
+
- **Multiple Formats**: Hex, RGB, HSL, HWB, CMYK, NCOL, OKLCH, LAB, LCH, P3
|
|
19
|
+
- **Zero Dependencies**: Pure Python, no external libraries required
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
# Install from PyPI (when published)
|
|
25
|
+
pip install colorium
|
|
26
|
+
|
|
27
|
+
# Install in development mode
|
|
28
|
+
git clone https://github.com/inject3r/colorium.git
|
|
29
|
+
cd colorium
|
|
30
|
+
pip install -e ".[dev]"
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Quick Start
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
from colorium import Color, from_string, RED, BLUE, WHITE, BLACK
|
|
37
|
+
|
|
38
|
+
# Create colors from various formats
|
|
39
|
+
red = Color(255, 0, 0)
|
|
40
|
+
blue = from_string("blue")
|
|
41
|
+
hex_color = from_string("#FF0000")
|
|
42
|
+
named = from_string("crimson")
|
|
43
|
+
|
|
44
|
+
# Use color constants
|
|
45
|
+
bg = WHITE
|
|
46
|
+
text = BLACK
|
|
47
|
+
primary = RED
|
|
48
|
+
secondary = BLUE
|
|
49
|
+
|
|
50
|
+
# Convert between color spaces
|
|
51
|
+
print(red.to_hsl_string()) # hsl(0, 100%, 50%)
|
|
52
|
+
print(red.to_hwb_string()) # hwb(0, 0%, 0%)
|
|
53
|
+
print(red.to_hex_string()) # #FF0000
|
|
54
|
+
print(red.to_cmyk_string()) # cmyk(0%, 100%, 100%, 0%)
|
|
55
|
+
|
|
56
|
+
# Get color values
|
|
57
|
+
hsl = red.to_hsl() # {'h': 0, 's': 1.0, 'l': 0.5}
|
|
58
|
+
rgb = red.to_rgb() # {'r': 255, 'g': 0, 'b': 0}
|
|
59
|
+
|
|
60
|
+
# Manipulate colors
|
|
61
|
+
red.lighter(0.3) # Make brighter
|
|
62
|
+
red.darker(0.2) # Make darker
|
|
63
|
+
red.saturate(0.5) # Increase saturation
|
|
64
|
+
red.desaturate(0.3) # Decrease saturation
|
|
65
|
+
|
|
66
|
+
# Check if color is dark
|
|
67
|
+
if red.is_dark():
|
|
68
|
+
print("Dark color!")
|
|
69
|
+
|
|
70
|
+
# Get color name
|
|
71
|
+
print(red.to_name()) # "Red"
|
|
72
|
+
|
|
73
|
+
# Blend colors
|
|
74
|
+
purple = RED.blend(BLUE, 0.5) # Equal blend
|
|
75
|
+
pink = RED.blend(WHITE, 0.7) # 70% white blend
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Color Filters
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
from colorium import (
|
|
82
|
+
Color,
|
|
83
|
+
SepiaFilter,
|
|
84
|
+
GrayscaleFilter,
|
|
85
|
+
ContrastFilter,
|
|
86
|
+
BrightnessFilter,
|
|
87
|
+
FilterPresets
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
color = Color(200, 150, 100)
|
|
91
|
+
|
|
92
|
+
# Single filter
|
|
93
|
+
sepia = SepiaFilter(0.7)
|
|
94
|
+
result = sepia(color)
|
|
95
|
+
|
|
96
|
+
# Chain filters
|
|
97
|
+
from colorium import CompositeFilter
|
|
98
|
+
vintage = CompositeFilter([
|
|
99
|
+
SepiaFilter(0.5),
|
|
100
|
+
ContrastFilter(1.1),
|
|
101
|
+
BrightnessFilter(0.9)
|
|
102
|
+
])
|
|
103
|
+
vintage_result = vintage(color)
|
|
104
|
+
|
|
105
|
+
# Use presets
|
|
106
|
+
clarendon = FilterPresets.clarendon()
|
|
107
|
+
clarendon_result = clarendon(color)
|
|
108
|
+
|
|
109
|
+
moon = FilterPresets.moon() # Black and white
|
|
110
|
+
moon_result = moon(color)
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Color Distance and Similarity
|
|
114
|
+
|
|
115
|
+
```python
|
|
116
|
+
from colorium import Color
|
|
117
|
+
|
|
118
|
+
color1 = Color(100, 150, 200)
|
|
119
|
+
color2 = Color(120, 130, 180)
|
|
120
|
+
|
|
121
|
+
# Calculate color difference (Delta E)
|
|
122
|
+
distance = color1.delta_e(color2, "cie2000")
|
|
123
|
+
print(f"Delta E: {distance:.2f}")
|
|
124
|
+
|
|
125
|
+
# Get similarity score (0.0 to 1.0)
|
|
126
|
+
similarity = color1.similarity(color2)
|
|
127
|
+
print(f"Similarity: {similarity:.2f}")
|
|
128
|
+
|
|
129
|
+
# Check if colors are similar
|
|
130
|
+
if color1.is_similar_to(color2, threshold=0.8):
|
|
131
|
+
print("Colors are very similar!")
|
|
132
|
+
|
|
133
|
+
# Different methods available
|
|
134
|
+
cie76 = color1.delta_e(color2, "cie76")
|
|
135
|
+
cie94 = color1.delta_e(color2, "cie94")
|
|
136
|
+
cie2000 = color1.delta_e(color2, "cie2000")
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Modern Color Spaces (CSS Color Level 4)
|
|
140
|
+
|
|
141
|
+
```python
|
|
142
|
+
from colorium import Color
|
|
143
|
+
|
|
144
|
+
# OKLCH - Perceptually uniform
|
|
145
|
+
color = Color.from_oklch(0.5, 0.2, 180)
|
|
146
|
+
print(color.to_oklch_string()) # oklch(50.0% 0.200 180.0)
|
|
147
|
+
|
|
148
|
+
# CIE L*a*b*
|
|
149
|
+
color = Color.from_lab(50, 20, -30)
|
|
150
|
+
print(color.to_lab_string()) # lab(50.0% 20.0 -30.0)
|
|
151
|
+
|
|
152
|
+
# CIE LCH
|
|
153
|
+
color = Color.from_lch(50, 30, 180)
|
|
154
|
+
print(color.to_lch_string()) # lch(50.0% 30.0 180.0)
|
|
155
|
+
|
|
156
|
+
# Display P3 Wide Gamut
|
|
157
|
+
color = Color.from_p3(0.8, 0.3, 0.5)
|
|
158
|
+
print(color.to_p3_string()) # color(display-p3 0.800 0.300 0.500)
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Color Constants
|
|
162
|
+
|
|
163
|
+
```python
|
|
164
|
+
from colorium import (
|
|
165
|
+
RED, BLUE, GREEN, WHITE, BLACK,
|
|
166
|
+
SUCCESS, ERROR, WARNING, INFO,
|
|
167
|
+
FACEBOOK_BLUE, TWITTER_BLUE, YOUTUBE_RED,
|
|
168
|
+
ORANGE, PURPLE, PINK, BROWN,
|
|
169
|
+
LIGHT_BLUE, DARK_BLUE, NAVY, ROYAL_BLUE,
|
|
170
|
+
LIGHT_GREEN, DARK_GREEN, FOREST_GREEN,
|
|
171
|
+
TRANSPARENT
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
# Use constants directly
|
|
175
|
+
status = SUCCESS if valid else ERROR
|
|
176
|
+
bg = WHITE
|
|
177
|
+
text = BLACK
|
|
178
|
+
|
|
179
|
+
# Blend constants
|
|
180
|
+
purple = RED.blend(BLUE, 0.5)
|
|
181
|
+
|
|
182
|
+
# Use as defaults
|
|
183
|
+
def create_button(text: str, color: Color = PRIMARY):
|
|
184
|
+
return {"text": text, "color": color}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## API Reference
|
|
188
|
+
|
|
189
|
+
### Color Class
|
|
190
|
+
|
|
191
|
+
| Method | Description |
|
|
192
|
+
| -------------------------------------- | ------------------------------------------ |
|
|
193
|
+
| `Color(red, green, blue, opacity=1.0)` | Create from RGB |
|
|
194
|
+
| `to_rgb_string()` | RGB string: `rgb(255, 0, 0)` |
|
|
195
|
+
| `to_rgba_string()` | RGBA string: `rgba(255, 0, 0, 0.5)` |
|
|
196
|
+
| `to_hsl_string()` | HSL string: `hsl(0, 100%, 50%)` |
|
|
197
|
+
| `to_hwb_string()` | HWB string: `hwb(0, 0%, 0%)` |
|
|
198
|
+
| `to_cmyk_string()` | CMYK string: `cmyk(0%, 100%, 100%, 0%)` |
|
|
199
|
+
| `to_hex_string()` | Hex string: `#FF0000` |
|
|
200
|
+
| `to_oklch_string()` | OKLCH string: `oklch(50% 0.2 180)` |
|
|
201
|
+
| `to_lab_string()` | LAB string: `lab(50% 20 -30)` |
|
|
202
|
+
| `to_lch_string()` | LCH string: `lch(50% 30 180)` |
|
|
203
|
+
| `to_p3_string()` | P3 string: `color(display-p3 0.8 0.3 0.5)` |
|
|
204
|
+
| `to_name()` | CSS color name: `"Red"` |
|
|
205
|
+
| `to_rgb()` | RGB dict: `{'r': 255, 'g': 0, 'b': 0}` |
|
|
206
|
+
| `to_hsl()` | HSL dict: `{'h': 0, 's': 1.0, 'l': 0.5}` |
|
|
207
|
+
| `delta_e(other, method)` | Color difference (CIE76, CIE94, CIEDE2000) |
|
|
208
|
+
| `similarity(other, method)` | Similarity score (0.0 to 1.0) |
|
|
209
|
+
| `is_similar_to(other, threshold)` | Check similarity |
|
|
210
|
+
| `blend(other, ratio)` | Blend two colors |
|
|
211
|
+
| `is_dark(threshold=128)` | Check if dark |
|
|
212
|
+
| `saturate(amount)` | Increase saturation |
|
|
213
|
+
| `desaturate(amount)` | Decrease saturation |
|
|
214
|
+
| `lighter(amount)` | Increase lightness |
|
|
215
|
+
| `darker(amount)` | Decrease lightness |
|
|
216
|
+
| `clone()` | Create a copy |
|
|
217
|
+
|
|
218
|
+
### Factory Functions
|
|
219
|
+
|
|
220
|
+
| Function | Description |
|
|
221
|
+
| ------------------------------------ | ---------------------- |
|
|
222
|
+
| `from_string(color_str)` | Parse any color string |
|
|
223
|
+
| `from_hex(hex_str)` | Create from hex |
|
|
224
|
+
| `from_rgb(r, g, b, opacity=1.0)` | Create from RGB |
|
|
225
|
+
| `from_hsl(h, s, l, opacity=1.0)` | Create from HSL |
|
|
226
|
+
| `from_hwb(h, w, b, opacity=1.0)` | Create from HWB |
|
|
227
|
+
| `from_cmyk(c, m, y, k, opacity=1.0)` | Create from CMYK |
|
|
228
|
+
| `from_oklch(l, c, h, opacity=1.0)` | Create from OKLCH |
|
|
229
|
+
| `from_lab(l, a, b, opacity=1.0)` | Create from LAB |
|
|
230
|
+
| `from_lch(l, c, h, opacity=1.0)` | Create from LCH |
|
|
231
|
+
| `from_p3(r, g, b, opacity=1.0)` | Create from P3 |
|
|
232
|
+
|
|
233
|
+
### Filters
|
|
234
|
+
|
|
235
|
+
| Filter | Description |
|
|
236
|
+
| ------------------------------------- | --------------------- |
|
|
237
|
+
| `SepiaFilter(intensity=1.0)` | Warm sepia tone |
|
|
238
|
+
| `GrayscaleFilter(method="luminance")` | Black and white |
|
|
239
|
+
| `InvertFilter()` | Negative effect |
|
|
240
|
+
| `ContrastFilter(amount=1.2)` | Contrast adjustment |
|
|
241
|
+
| `BrightnessFilter(amount=1.2)` | Brightness adjustment |
|
|
242
|
+
| `SaturationFilter(amount=0.5)` | Saturation adjustment |
|
|
243
|
+
| `HueRotateFilter(degrees=90)` | Hue rotation |
|
|
244
|
+
| `PosterizeFilter(levels=4)` | Color quantization |
|
|
245
|
+
| `TemperatureFilter(kelvin=5500)` | Warm/cool shift |
|
|
246
|
+
| `VignetteFilter(intensity=0.5)` | Edge darkening |
|
|
247
|
+
|
|
248
|
+
### Filter Presets
|
|
249
|
+
|
|
250
|
+
| Preset | Description |
|
|
251
|
+
| --------------------------- | ------------------------------------------ |
|
|
252
|
+
| `FilterPresets.clarendon()` | Increased contrast, brightness, saturation |
|
|
253
|
+
| `FilterPresets.gingham()` | Warm, soft vintage |
|
|
254
|
+
| `FilterPresets.moon()` | High-contrast black and white |
|
|
255
|
+
| `FilterPresets.lark()` | Cool, vibrant modern |
|
|
256
|
+
| `FilterPresets.toaster()` | Warm, retro vintage |
|
|
257
|
+
| `FilterPresets.valencia()` | Warm, soft vintage |
|
|
258
|
+
| `FilterPresets.amaro()` | Rich, warm, slightly dark |
|
|
259
|
+
|
|
260
|
+
## Development
|
|
261
|
+
|
|
262
|
+
### Running Tests
|
|
263
|
+
|
|
264
|
+
```bash
|
|
265
|
+
# Run all tests
|
|
266
|
+
pytest
|
|
267
|
+
|
|
268
|
+
# Run with coverage
|
|
269
|
+
pytest --cov=colorium
|
|
270
|
+
|
|
271
|
+
# Run specific test file
|
|
272
|
+
pytest tests/test_color.py
|
|
273
|
+
|
|
274
|
+
# Run specific test
|
|
275
|
+
pytest tests/test_color.py::TestColor::test_initialization
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### Code Style
|
|
279
|
+
|
|
280
|
+
The project uses:
|
|
281
|
+
|
|
282
|
+
- **Black** for code formatting
|
|
283
|
+
- **Flake8** for linting
|
|
284
|
+
- **Mypy** for type checking
|
|
285
|
+
|
|
286
|
+
```bash
|
|
287
|
+
# Format code
|
|
288
|
+
black src/ tests/
|
|
289
|
+
|
|
290
|
+
# Run linter
|
|
291
|
+
flake8 src/ tests/
|
|
292
|
+
|
|
293
|
+
# Type check
|
|
294
|
+
mypy src/
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
## License
|
|
298
|
+
|
|
299
|
+
MIT License - see [LICENSE](LICENSE) for details.
|
|
300
|
+
|
|
301
|
+
## Author
|
|
302
|
+
|
|
303
|
+
**Abolfazl Hosseini**
|
|
304
|
+
|
|
305
|
+
- Email: tryuzr@gmail.com
|
|
306
|
+
- GitHub: [@inject3r](https://github.com/inject3r)
|
|
307
|
+
|
|
308
|
+
## Links
|
|
309
|
+
|
|
310
|
+
- [Source Code](https://github.com/inject3r/colorium)
|
|
311
|
+
- [Bug Tracker](https://github.com/inject3r/colorium/issues)
|
|
312
|
+
- [Documentation](https://inject3r.github.io/colorium)
|
|
313
|
+
|
|
314
|
+
## Contributing
|
|
315
|
+
|
|
316
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
317
|
+
|
|
318
|
+
1. Fork the repository
|
|
319
|
+
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
|
|
320
|
+
3. Commit your changes (`git commit -m 'Add amazing feature'`)
|
|
321
|
+
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
322
|
+
5. Open a Pull Request
|
|
323
|
+
|
|
324
|
+
## Acknowledgments
|
|
325
|
+
|
|
326
|
+
- CSS Color Module Level 4 specification
|
|
327
|
+
- CIE color science standards
|
|
328
|
+
- Natural Color System (NCS) for NCOL notation
|
|
329
|
+
- Instagram filter effects for inspiration
|