Package: ciris
CirisCiris is a lightweight library that specializes on working with color.
The package does not rely on any third-party dependencies.The name of a library is the first letter of the word "color" and the name of the Greek goddess of color, Iris, if you were interested :)Color classCiris provides a handy Color class that provides functionality for working with color.
This class stores the color in HSV color space and allows the end user the greater
flexibility while modifying the color.Creating a Color class using HSV valuesSince the Color class uses HSV, the default constructor is set up to accept HSV values directly:fromcirisimportColorhue,saturation,value=260,90,90c=Color(hue,saturation,value)You can also use the built-in functionColor.from_hsv()to construct the Color object.fromcirisimportColorhue,saturation,value=260,90,90c=Color.from_hsv(hue,saturation,value)In this case, both methods are equivalent. The latter was added for the sake of consistency with the other constructors.Creating a Color object using RGB valuesThe Color object provides aColor.from_rgb()function which can be used to create Color object from RGB band values, like this:fromcirisimportColorr,g,b=100,0,255c=Color.from_rgb(r,g,b)Creating a Color object using CMYK valuesIn case you need to create a Color object from CMYK values, you can use theColor.from_cmyk()method:fromcirisimportColorc,m,y,k=15,0,45,2c=Color.from_cmyk(c,m,y,k)Note that CMYK values should be integers in range [0..100], not floats. For example, a CMYK color defined as (45%, 11%, 0%, 56%) should be passed asc=45, m=11, y=0, k=56Creating a Color object using a hex-stringIf you have a hex-string you can use the built-inColor.from_hex()method to create a Color object:fromcirisimportColormy_hex_str="#00FF56"c=Color.from_hex(my_hex_str)Note thatColor.from_hex()method only accepts a 7-symbol hex-string (a pound sign, 2 symbols for red, 2 symbols for green, 2 symbols for blue). Other variations, such as ARGB, are not yet supported.Representing the color as HSVSince the HSV space is the space that the Color object uses to store data, no conversion is necessary.
To represent the color as HSV values, simply call theColor.as_hsv()method:fromcirisimportColorhue,saturation,value=260,90,90c=Color.from_hsv(hue,saturation,value)hsv_tuple=c.as_hsv()This method returns a tuple with the signature(hue_value, saturation_value, value_value)Representing the color as RGBTo convert the current color to RGB, simply call theColor.as_rgb()method:fromcirisimportColorhue,saturation,value=260,90,90c=Color.from_hsv(hue,saturation,value)rgb_tuple=c.as_rgb()This method returns a tuple with the signature(r_value, g_value, b_value).Representing the color as CMYKTo convert the current color to CMYK, call theColor.as_cmyk()method:fromcirisimportColorhue,saturation,value=260,90,90c=Color.from_hsv(hue,saturation,value)cmyk_tuple=c.as_cmyk()This method returns a tuple with the signature(c_value, m_value, y_value, k_value). Note that these values are integers in range [0..100].Altering the hue of the colorTo alter the color's hue, use theColor.hue_shift()method. The method takes a required positional argumentamount: int, which specifies the amount in degrees on a color wheel that the hue will be shifted by.For example, this code will shift the color's hue by 30 degrees clockwise:fromcirisimportColorhue,saturation,value=260,90,90c=Color.from_hsv(hue,saturation,value)c.hue_shift(30)print(c.as_hsv())# (290, 90, 90)You can also pass a negative integer into the method to shift the hue counterclockwise. For example, the code below shifts the color's hue by 60 degrees counterclockwise:fromcirisimportColorhue,saturation,value=260,90,90c=Color.from_hsv(hue,saturation,value)c.hue_shift(-60)print(c.as_hsv())# (200, 90, 90)Since the hue is always in range [0..360], the method will account for this. An example:fromcirisimportColorhue,saturation,value=260,90,90c=Color.from_hsv(hue,saturation,value)c.hue_shift(120)# The shift has caused the hue to become out of acceptable range# The hue is a representation of a color wheel, which cannot be more than 360deg, so the method has corrected the hueprint(c.as_hsv())# (20, 90, 90)The same logic works for negative shifts.Altering the saturation of the colorTo alter the color's saturation, use theColor.adjust_saturation()method. It takes a required positional argumentamount: int, that indicated the amount that the saturation needs to be adjusted by.For example, this code below raises the color's saturation by 5%:fromcirisimportColorhue,saturation,value=260,90,90c=Color.from_hsv(hue,saturation,value)c.adjust_saturation(5)print(c.as_hsv())# (260, 95, 90)You can also pass a negative integer to lower the saturation level:fromcirisimportColorhue,saturation,value=260,90,90c=Color.from_hsv(hue,saturation,value)c.adjust_saturation(-10)print(c.as_hsv())# (260, 80, 90)Since the saturation level should always be in range [0..100], the method will cap any excessive adjustment:fromcirisimportColorhue,saturation,value=260,90,90c=Color.from_hsv(hue,saturation,value)c.adjust_saturation(60000)# The saturation has only been raised by 10 due to it being cappedprint(c.as_hsv())# (260, 100, 90)Altering the color's valueTo adjust color's value, use theColor.lighten()andColor.darken()methods to lighten and darken the color respectively:fromcirisimportColorhue,saturation,value=260,90,90c=Color.from_hsv(hue,saturation,value)c.lighten(10)print(c.as_hsv())# (200, 90, 100)fromcirisimportColorhue,saturation,value=260,90,90c=Color.from_hsv(hue,saturation,value)c.darken(60)print(c.as_hsv())# (260, 90, 30)These methods do accept negative integers. In that case their functionality is reversed.
Since the value should always be in range [0..100], the method will cap any excessive adjustment:fromcirisimportColorhue,saturation,value=260,90,90c=Color.from_hsv(hue,saturation,value)c.lighten(10000)print(c.as_hsv())# (200, 90, 100)fromcirisimportColorhue,saturation,value=260,90,90c=Color.from_hsv(hue,saturation,value)c.darken(600000)print(c.as_hsv())# (260, 90, 0)Inverting the colorTo invert the color, use theColor.invert()method:fromcirisimportColorhue,saturation,value=260,90,90c=Color.from_hsv(hue,saturation,value)c.invert()print(c.as_hsv())# (80, 90, 90)Applying complementary harmony rule to the colorTo apply the complementary rule to the current color, useColor.harmony_complementary()method:fromcirisimportColorhue,saturation,value=260,90,90c=Color.from_hsv(hue,saturation,value)rule=c.harmony_complementary()This method returns aHarmonyRuleobject.Applying split complementary harmony rule to the colorTo apply the split complementary rule to the current color, useColor.harmony_split_complementary()method. You can also pass an optional argumentphi: intthat indicates the offset in degrees that will be used. By default it is 150deg:fromcirisimportColorhue,saturation,value=260,90,90c=Color.from_hsv(hue,saturation,value)rule=c.harmony_split_complementary(phi=40)# The offset used is 40degThis method returns aHarmonyRuleobject.Applying triadic harmony rule to the colorTo apply the triadic rule to the current color, useColor.harmony_triadic()method.fromcirisimportColorhue,saturation,value=260,90,90c=Color.from_hsv(hue,saturation,value)rule=c.harmony_triadic()This method returns aHarmonyRuleobject.Applying tetradic harmony rule to the colorTo apply the tetradic rule to the current color, useColor.harmony_tetradic()method.fromcirisimportColorhue,saturation,value=260,90,90c=Color.from_hsv(hue,saturation,value)rule=c.harmony_tetradic()This method returns aHarmonyRuleobject.Applying analogous harmony rule to the colorTo apply the split complementary rule to the current color, useColor.harmony_analogous()method. You can also pass an optional argumentphi: intthat indicates the offset in degrees that will be used. By default it is 30deg:fromcirisimportColorhue,saturation,value=260,90,90c=Color.from_hsv(hue,saturation,value)rule=c.harmony_split_complementary(phi=40)# The offset used is 40degThis method returns aHarmonyRuleobject.Comparing the colorsTo compare Color objects, use a simple==statement.For example, the code below wil printThe colors are the same:fromcirisimportColorifColor(255,100,100)==Color.from_hsv(255,100,100):print("The colors are the same")Looking up colors in a listThe Color objects are hashable, meaning that you can easily check if the color
is already stored an a list of colors using a simpleinstatement:fromcirisimportColorb_and_w=[Color.from_hex("#FFFFFF"),Color.from_hex("#000000")]print(Color.from_rgb(0,0,0)inb_and_w)# Trueprint(Color.from_rgb(62,81,22)inb_and_w)# FalseHarmonyRule classThis class is a dataclass that is used by ciris to describe any harmony rule that has been applied to the color.It has 3 attributes:rule_type: str- This attribute stores the type of rule that was applied. Available types are:complementary,split_complementary,triadic,tetradic,analogousbase_color: Color- This attribute stores the base color (the color that the rule was applied to)secondary_colors: List[Color]- This attribute stores a list of colors that were derived from the base one according to the harmony ruleAll these attributes have their appropriate getters.Method chainingThe ciris' Color class supports method chaining, allowing you to write simple, concise and practical one-liners, such as:Color conversionfromcirisimportColorc=Color.from_hsv(260,90,90).as_hex()v=Color.from_rgb(145,90,10).as_cmyk()# ...g=Color.from_hex("#ff0097").as_hsv()Color processingfromcirisimportColornew_color=Color.from_rgb(old.r,old.g,old.b).invert().lighten(15).hue_shift(10).as_cmyk()Color Harmony SourcesHere you can find the source material that was used to create color harmony ruleshttps://en.wikipedia.org/wiki/Harmony_(color)https://blog.thepapermillstore.com/color-theory-color-harmonies/https://blog.matthewgove.com/2021/07/02/color-theory-a-simple-exercise-in-mathematics-and-graphic-design/