@@ -261,6 +261,124 @@ def rgb(self):
261261 min (int ((green * 255 ) / self .green_max ), 255 ),
262262 min (int ((blue * 255 ) / self .blue_max ), 255 ))
263263
264+ @property
265+ def lab (self ):
266+ """
267+ Return colors in Lab color space
268+ """
269+ RGB = [0 , 0 , 0 ]
270+ XYZ = [0 , 0 , 0 ]
271+
272+ for (num , value ) in enumerate (self .rgb ):
273+ if value > 0.04045 :
274+ value = pow (((value + 0.055 ) / 1.055 ), 2.4 )
275+ else :
276+ value = value / 12.92
277+
278+ RGB [num ] = value * 100.0
279+
280+ # http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
281+ # sRGB
282+ # 0.4124564 0.3575761 0.1804375
283+ # 0.2126729 0.7151522 0.0721750
284+ # 0.0193339 0.1191920 0.9503041
285+ X = (RGB [0 ] * 0.4124564 ) + (RGB [1 ] * 0.3575761 ) + (RGB [2 ] * 0.1804375 )
286+ Y = (RGB [0 ] * 0.2126729 ) + (RGB [1 ] * 0.7151522 ) + (RGB [2 ] * 0.0721750 )
287+ Z = (RGB [0 ] * 0.0193339 ) + (RGB [1 ] * 0.1191920 ) + (RGB [2 ] * 0.9503041 )
288+
289+ XYZ [0 ] = X / 95.047 # ref_X = 95.047
290+ XYZ [1 ] = Y / 100.0 # ref_Y = 100.000
291+ XYZ [2 ] = Z / 108.883 # ref_Z = 108.883
292+
293+ for (num , value ) in enumerate (XYZ ):
294+ if value > 0.008856 :
295+ value = pow (value , (1.0 / 3.0 ))
296+ else :
297+ value = (7.787 * value ) + (16 / 116.0 )
298+
299+ XYZ [num ] = value
300+
301+ L = (116.0 * XYZ [1 ]) - 16
302+ a = 500.0 * (XYZ [0 ] - XYZ [1 ])
303+ b = 200.0 * (XYZ [1 ] - XYZ [2 ])
304+
305+ L = round (L , 4 )
306+ a = round (a , 4 )
307+ b = round (b , 4 )
308+
309+ return (L , a , b )
310+
311+ @property
312+ def hsv (self ):
313+ """
314+ HSV: Hue, Saturation, Value
315+ H: position in the spectrum
316+ S: color saturation ("purity")
317+ V: color brightness
318+ """
319+ (r , g , b ) = self .rgb
320+ maxc = max (r , g , b )
321+ minc = min (r , g , b )
322+ v = maxc
323+
324+ if minc == maxc :
325+ return 0.0 , 0.0 , v
326+
327+ s = (maxc - minc ) / maxc
328+ rc = (maxc - r ) / (maxc - minc )
329+ gc = (maxc - g ) / (maxc - minc )
330+ bc = (maxc - b ) / (maxc - minc )
331+
332+ if r == maxc :
333+ h = bc - gc
334+ elif g == maxc :
335+ h = 2.0 + rc - bc
336+ else :
337+ h = 4.0 + gc - rc
338+
339+ h = (h / 6.0 ) % 1.0
340+
341+ return (h , s , v )
342+
343+ @property
344+ def hls (self ):
345+ """
346+ HLS: Hue, Luminance, Saturation
347+ H: position in the spectrum
348+ L: color lightness
349+ S: color saturation
350+ """
351+ (r , g , b ) = self .rgb
352+ maxc = max (r , g , b )
353+ minc = min (r , g , b )
354+ l = (minc + maxc )/ 2.0
355+
356+ if minc == maxc :
357+ return 0.0 , l , 0.0
358+
359+ if l <= 0.5 :
360+ s = (maxc - minc ) / (maxc + minc )
361+ else :
362+ if 2.0 - maxc - minc == 0 :
363+ s = 0
364+ else :
365+ s = (maxc - minc ) / (2.0 - maxc - minc )
366+
367+ rc = (maxc - r ) / (maxc - minc )
368+ gc = (maxc - g ) / (maxc - minc )
369+ bc = (maxc - b ) / (maxc - minc )
370+
371+ if r == maxc :
372+ h = bc - gc
373+ elif g == maxc :
374+ h = 2.0 + rc - bc
375+ else :
376+ h = 4.0 + gc - rc
377+
378+ h = (h / 6.0 ) % 1.0
379+
380+ return (h , l , s )
381+
264382 @property
265383 def red (self ):
266384 """
0 commit comments