• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

colour.egg-info/H03-May-2022-627438

CHANGELOG.rstH A D19-Nov-20172.3 KiB10773

LICENSEH A D19-Nov-20171.3 KiB2419

MANIFEST.inH A D19-Nov-201722 21

PKG-INFOH A D19-Nov-201722.5 KiB627438

README.rstH A D19-Nov-201714.6 KiB493340

TODO.rstH A D19-Nov-201795 84

colour.pyH A D19-Nov-201728 KiB1,125789

setup.cfgH A D19-Nov-20171.2 KiB5851

setup.pyH A D19-Nov-20171.9 KiB6642

README.rst

1======
2Colour
3======
4
5.. image:: http://img.shields.io/pypi/v/colour.svg?style=flat
6   :target: https://pypi.python.org/pypi/colour/
7   :alt: Latest PyPI version
8
9.. image:: https://img.shields.io/pypi/l/gitchangelog.svg?style=flat
10   :target: https://github.com/vaab/gitchangelog/blob/master/LICENSE
11   :alt: License
12
13.. image:: https://img.shields.io/pypi/pyversions/gitchangelog.svg?style=flat
14   :target: https://pypi.python.org/pypi/gitchangelog/
15   :alt: Compatible python versions
16
17.. image:: http://img.shields.io/pypi/dm/colour.svg?style=flat
18   :target: https://pypi.python.org/pypi/colour/
19   :alt: Number of PyPI downloads
20
21.. image:: http://img.shields.io/travis/vaab/colour/master.svg?style=flat
22   :target: https://travis-ci.org/vaab/colour/
23   :alt: Travis CI build status
24
25.. image:: https://img.shields.io/appveyor/ci/vaab/colour.svg
26   :target: https://ci.appveyor.com/project/vaab/colour/branch/master
27   :alt: Appveyor CI build status
28
29.. image:: http://img.shields.io/codecov/c/github/vaab/colour.svg?style=flat
30   :target: https://codecov.io/gh/vaab/colour/
31   :alt: Test coverage
32
33
34Converts and manipulates common color representation (RGB, HSL, web, ...)
35
36
37Feature
38=======
39
40- Damn simple and pythonic way to manipulate color representation (see
41  examples below)
42
43- Full conversion between RGB, HSL, 6-digit hex, 3-digit hex, human color
44
45- One object (``Color``) or bunch of single purpose function (``rgb2hex``,
46  ``hsl2rgb`` ...)
47
48- ``web`` format that use the smallest representation between
49  6-digit (e.g. ``#fa3b2c``), 3-digit (e.g. ``#fbb``), fully spelled
50  color (e.g. ``white``), following `W3C color naming`_ for compatible
51  CSS or HTML color specifications.
52
53- smooth intuitive color scale generation choosing N color gradients.
54
55- can pick colors for you to identify objects of your application.
56
57
58.. _W3C color naming: http://www.w3.org/TR/css3-color/#svg-color
59
60
61Installation
62============
63
64You don't need to download the GIT version of the code as ``colour`` is
65available on the PyPI. So you should be able to run::
66
67    pip install colour
68
69If you have downloaded the GIT sources, then you could add the ``colour.py``
70directly to one of your ``site-packages`` (thanks to a symlink). Or install
71the current version via traditional::
72
73    python setup.py install
74
75And if you don't have the GIT sources but would like to get the latest
76master or branch from github, you could also::
77
78    pip install git+https://github.com/vaab/colour
79
80Or even select a specific revision (branch/tag/commit)::
81
82    pip install git+https://github.com/vaab/colour@master
83
84
85Usage
86=====
87
88To get complete demo of each function, please read the source code which is
89heavily documented and provide a lot of examples in doctest format.
90
91Here is a reduced sample of a common usage scenario:
92
93
94Instantiation
95-------------
96
97Let's create blue color::
98
99    >>> from colour import Color
100    >>> c = Color("blue")
101    >>> c
102    <Color blue>
103
104Please note that all of these are equivalent examples to create the red color::
105
106    Color("red")           ## human, web compatible representation
107    Color(red=1)           ## default amount of blue and green is 0.0
108    Color("blue", hue=0)   ## hue of blue is 0.66, hue of red is 0.0
109    Color("#f00")          ## standard 3 hex digit web compatible representation
110    Color("#ff0000")       ## standard 6 hex digit web compatible representation
111    Color(hue=0, saturation=1, luminance=0.5)
112    Color(hsl=(0, 1, 0.5)) ## full 3-uple HSL specification
113    Color(rgb=(1, 0, 0))   ## full 3-uple RGB specification
114    Color(Color("red"))    ## recursion doesn't break object
115
116
117Reading values
118--------------
119
120Several representations are accessible::
121
122    >>> c.hex
123    '#00f'
124    >>> c.hsl  # doctest: +ELLIPSIS
125    (0.66..., 1.0, 0.5)
126    >>> c.rgb
127    (0.0, 0.0, 1.0)
128
129And their different parts are also independently accessible, as the different
130amount of red, blue, green, in the RGB format::
131
132    >>> c.red
133    0.0
134    >>> c.blue
135    1.0
136    >>> c.green
137    0.0
138
139Or the hue, saturation and luminance of the HSL representation::
140
141    >>> c.hue  # doctest: +ELLIPSIS
142    0.66...
143    >>> c.saturation
144    1.0
145    >>> c.luminance
146    0.5
147
148A note on the ``.hex`` property, it'll return the smallest valid value
149when possible. If you are only interested by the long value, use
150``.hex_l``::
151
152    >>> c.hex_l
153    '#0000ff'
154
155
156Modifying color objects
157-----------------------
158
159All of these properties are read/write, so let's add some red to this color::
160
161    >>> c.red = 1
162    >>> c
163    <Color magenta>
164
165We might want to de-saturate this color::
166
167    >>> c.saturation = 0.5
168    >>> c
169    <Color #bf40bf>
170
171And of course, the string conversion will give the web representation which is
172human, or 3-digit, or 6-digit hex representation depending which is usable::
173
174    >>> "%s" % c
175    '#bf40bf'
176
177    >>> c.luminance = 1
178    >>> "%s" % c
179    'white'
180
181
182Ranges of colors
183----------------
184
185You can get some color scale of variation between two ``Color`` objects quite
186easily. Here, is the color scale of the rainbow between red and blue::
187
188    >>> red = Color("red")
189    >>> blue = Color("blue")
190    >>> list(red.range_to(blue, 5))
191    [<Color red>, <Color yellow>, <Color lime>, <Color cyan>, <Color blue>]
192
193Or the different amount of gray between black and white::
194
195    >>> black = Color("black")
196    >>> white = Color("white")
197    >>> list(black.range_to(white, 6))
198    [<Color black>, <Color #333>, <Color #666>, <Color #999>, <Color #ccc>, <Color white>]
199
200
201If you have to create graphical representation with color scale
202between red and green ('lime' color is full green)::
203
204    >>> lime = Color("lime")
205    >>> list(red.range_to(lime, 5))
206    [<Color red>, <Color #ff7f00>, <Color yellow>, <Color chartreuse>, <Color lime>]
207
208Notice how naturally, the yellow is displayed in human format and in
209the middle of the scale. And that the quite unusual (but compatible)
210'chartreuse' color specification has been used in place of the
211hexadecimal representation.
212
213
214Color comparison
215----------------
216
217Sane default
218~~~~~~~~~~~~
219
220Color comparison is a vast subject. However, it might seem quite straightforward for
221you. ``Colour`` uses a configurable default way of comparing color that might suit
222your needs::
223
224    >>> Color("red") == Color("#f00") == Color("blue", hue=0)
225    True
226
227The default comparison algorithm focuses only on the "web" representation which is
228equivalent to comparing the long hex representation (e.g. #FF0000) or to be more
229specific, it is equivalent to compare the amount of red, green, and blue composition
230of the RGB representation, each of these value being quantized to a 256 value scale.
231
232This default comparison is a practical and convenient way to measure the actual
233color equivalence on your screen, or in your video card memory.
234
235But this comparison wouldn't make the difference between a black red, and a
236black blue, which both are black::
237
238   >>> black_red = Color("red", luminance=0)
239   >>> black_blue = Color("blue", luminance=0)
240
241   >>> black_red == black_blue
242   True
243
244
245Customization
246~~~~~~~~~~~~~
247
248But, this is not the sole way to compare two colors. As I'm quite lazy, I'm providing
249you a way to customize it to your needs. Thus::
250
251   >>> from colour import RGB_equivalence, HSL_equivalence
252   >>> black_red = Color("red", luminance=0, equality=HSL_equivalence)
253   >>> black_blue = Color("blue", luminance=0, equality=HSL_equivalence)
254
255   >>> black_red == black_blue
256   False
257
258As you might have already guessed, the sane default is ``RGB_equivalence``, so::
259
260   >>> black_red = Color("red", luminance=0, equality=RGB_equivalence)
261   >>> black_blue = Color("blue", luminance=0, equality=RGB_equivalence)
262
263   >>> black_red == black_blue
264   True
265
266Here's how you could implement your unique comparison function::
267
268   >>> saturation_equivalence = lambda c1, c2: c1.saturation == c2.saturation
269   >>> red = Color("red", equality=saturation_equivalence)
270   >>> blue = Color("blue", equality=saturation_equivalence)
271   >>> white = Color("white", equality=saturation_equivalence)
272
273   >>> red == blue
274   True
275   >>> white == red
276   False
277
278Note: When comparing 2 colors, *only* the equality function *of the first
279color will be used*. Thus::
280
281   >>> black_red = Color("red", luminance=0, equality=RGB_equivalence)
282   >>> black_blue = Color("blue", luminance=0, equality=HSL_equivalence)
283
284   >>> black_red == black_blue
285   True
286
287But reverse operation is not equivalent !::
288
289   >>> black_blue == black_red
290   False
291
292
293Equality to non-Colour objects
294~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
295
296As a side note, whatever your custom equality function is, it won't be
297used if you compare to anything else than a ``Colour`` instance::
298
299    >>> red = Color("red", equality=lambda c1, c2: True)
300    >>> blue = Color("blue", equality=lambda c1, c2: True)
301
302Note that these instances would compare as equal to any other color::
303
304    >>> red == blue
305    True
306
307But on another non-Colour object::
308
309    >>> red == None
310    False
311    >>> red != None
312    True
313
314Actually, ``Colour`` instances will, politely enough, leave
315the other side of the equality have a chance to decide of the output,
316(by executing its own ``__eq__``), so::
317
318    >>> class OtherColorImplem(object):
319    ...     def __init__(self, color):
320    ...         self.color = color
321    ...     def __eq__(self, other):
322    ...         return self.color == other.web
323
324    >>> alien_red = OtherColorImplem("red")
325    >>> red == alien_red
326    True
327    >>> blue == alien_red
328    False
329
330And inequality (using ``__ne__``) are also polite::
331
332    >>> class AnotherColorImplem(OtherColorImplem):
333    ...     def __ne__(self, other):
334    ...         return self.color != other.web
335
336    >>> new_alien_red = AnotherColorImplem("red")
337    >>> red != new_alien_red
338    False
339    >>> blue != new_alien_red
340    True
341
342
343Picking arbitrary color for a python object
344-------------------------------------------
345
346Basic Usage
347~~~~~~~~~~~
348
349Sometimes, you just want to pick a color for an object in your application
350often to visually identify this object. Thus, the picked color should be the
351same for same objects, and different for different object::
352
353    >>> foo = object()
354    >>> bar = object()
355
356    >>> Color(pick_for=foo)  # doctest: +ELLIPSIS
357    <Color ...>
358    >>> Color(pick_for=foo) == Color(pick_for=foo)
359    True
360    >>> Color(pick_for=foo) == Color(pick_for=bar)
361    False
362
363Of course, although there's a tiny probability that different strings yield the
364same color, most of the time, different inputs will produce different colors.
365
366Advanced Usage
367~~~~~~~~~~~~~~
368
369You can customize your color picking algorithm by providing a ``picker``. A
370``picker`` is a callable that takes an object, and returns something that can
371be instantiated as a color by ``Color``::
372
373    >>> my_picker = lambda obj: "red" if isinstance(obj, int) else "blue"
374    >>> Color(pick_for=3, picker=my_picker, pick_key=None)
375    <Color red>
376    >>> Color(pick_for="foo", picker=my_picker, pick_key=None)
377    <Color blue>
378
379You might want to use a particular picker, but enforce how the picker will
380identify two object as the same (or not). So there's a ``pick_key`` attribute
381that is provided and defaults as equivalent of ``hash`` method and if hash is
382not supported by your object, it'll default to the ``str`` of your object salted
383with the class name.
384
385Thus::
386
387    >>> class MyObj(str): pass
388    >>> my_obj_color = Color(pick_for=MyObj("foo"))
389    >>> my_str_color = Color(pick_for="foo")
390    >>> my_obj_color == my_str_color
391    False
392
393Please make sure your object is hashable or "stringable" before using the
394``RGB_color_picker`` picking mechanism or provide another color picker. Nearly
395all python object are hashable by default so this shouldn't be an issue (e.g.
396instances of ``object`` and subclasses are hashable).
397
398Neither ``hash`` nor ``str`` are perfect solution. So feel free to use
399``pick_key`` at ``Color`` instantiation time to set your way to identify
400objects, for instance::
401
402    >>> a = object()
403    >>> b = object()
404    >>> Color(pick_for=a, pick_key=id) == Color(pick_for=b, pick_key=id)
405    False
406
407When choosing a pick key, you should closely consider if you want your color
408to be consistent between runs (this is NOT the case with the last example),
409or consistent with the content of your object if it is a mutable object.
410
411Default value of ``pick_key`` and ``picker`` ensures that the same color will
412be attributed to same object between different run on different computer for
413most python object.
414
415
416Color factory
417-------------
418
419As you might have noticed, there are few attributes that you might want to see
420attached to all of your colors as ``equality`` for equality comparison support,
421or ``picker``, ``pick_key`` to configure your object color picker.
422
423You can create a customized ``Color`` factory thanks to the ``make_color_factory``::
424
425    >>> from colour import make_color_factory, HSL_equivalence, RGB_color_picker
426
427    >>> get_color = make_color_factory(
428    ...    equality=HSL_equivalence,
429    ...    picker=RGB_color_picker,
430    ...    pick_key=str,
431    ... )
432
433All color created thanks to ``CustomColor`` class instead of the default one
434would get the specified attributes by default::
435
436    >>> black_red = get_color("red", luminance=0)
437    >>> black_blue = get_color("blue", luminance=0)
438
439Of course, these are always instances of ``Color`` class::
440
441    >>> isinstance(black_red, Color)
442    True
443
444Equality was changed from normal defaults, so::
445
446    >>> black_red == black_blue
447    False
448
449This because the default equivalence of ``Color`` was set to
450``HSL_equivalence``.
451
452
453Contributing
454============
455
456Any suggestion or issue is welcome. Push request are very welcome,
457please check out the guidelines.
458
459
460Push Request Guidelines
461-----------------------
462
463You can send any code. I'll look at it and will integrate it myself in
464the code base and leave you as the author. This process can take time and
465it'll take less time if you follow the following guidelines:
466
467- check your code with PEP8 or pylint. Try to stick to 80 columns wide.
468- separate your commits per smallest concern.
469- each commit should pass the tests (to allow easy bisect)
470- each functionality/bugfix commit should contain the code, tests,
471  and doc.
472- prior minor commit with typographic or code cosmetic changes are
473  very welcome. These should be tagged in their commit summary with
474  ``!minor``.
475- the commit message should follow gitchangelog rules (check the git
476  log to get examples)
477- if the commit fixes an issue or finished the implementation of a
478  feature, please mention it in the summary.
479
480If you have some questions about guidelines which is not answered here,
481please check the current ``git log``, you might find previous commit that
482would show you how to deal with your issue.
483
484
485License
486=======
487
488Copyright (c) 2012-2017 Valentin Lab.
489
490Licensed under the `BSD License`_.
491
492.. _BSD License: http://raw.github.com/vaab/colour/master/LICENSE
493