Colour
From HaskellWiki
(type annotation for pureColour) |
(black is now exported from Data.Colour) |
||
| (14 intermediate revisions not shown.) | |||
| Line 1: | Line 1: | ||
| + | [[Category:Libraries]] | ||
| + | |||
This page provides a short introduction to using the [http://hackage.haskell.org/package/colour colour package] on hackage. | This page provides a short introduction to using the [http://hackage.haskell.org/package/colour colour package] on hackage. | ||
| Line 11: | Line 13: | ||
You may wish to make a type synonym for this type in your program if you will use it everywhere. | You may wish to make a type synonym for this type in your program if you will use it everywhere. | ||
| - | You can always use | + | You can always use <hask>colourConvert</hask> to change to a different internal representation type. |
== Creating colours == | == Creating colours == | ||
| Line 45: | Line 47: | ||
</haskell> | </haskell> | ||
| - | will create a new colour that is 25% red, and 75% green. The weight parameter (the first parameter) should be between 0 and 1, otherwise an out of gamut colour could result. | + | will create a new colour that is 25% red, and 75% green. The weight parameter (the first parameter) should be between 0 and 1, otherwise an out-of-gamut colour could result. |
If you need to blend more than two colours, you can use multiple applications of <hask>blend</hask>, or you can use <hask>affineCombo</hask>. For example, | If you need to blend more than two colours, you can use multiple applications of <hask>blend</hask>, or you can use <hask>affineCombo</hask>. For example, | ||
| Line 53: | Line 55: | ||
</haskell> | </haskell> | ||
| - | will create a new colour that is 25% red, 50% green, and 25% violet. Again the weights should all be non-negative and the sum of the weights should be no more than 1, otherwise an out of gamut colour could result. | + | will create a new colour that is 25% red, 50% green, and 25% violet. Again the weights should all be non-negative and the sum of the weights should be no more than 1, otherwise an out-of-gamut colour could result. |
| - | + | Colour intensity can be changed by using <hask>darken</hask>. For example, | |
<haskell> | <haskell> | ||
| Line 62: | Line 64: | ||
will produce a turquoise that is only 40% of the intensity of normal turquoise. | will produce a turquoise that is only 40% of the intensity of normal turquoise. | ||
| - | The weight parameter (the first parameter) should be between 0 and 1, otherwise an out of gamut colour could result. However if you know that the intensity is low enough, you may | + | The weight parameter (the first parameter) should be between 0 and 1, otherwise an out-of-gamut colour could result. However if you know that the intensity is low enough, you may safely "darken" by values greater than 1 (which will actually lighten the colour). |
| - | Lastly, colours are instance of a [[Monoid]] so colours can be "added" by using <hask>mappend</hask> (and <hask>mempty</hask> is a quick way to get black). However, like spotlights, adding colours makes more intense colours. Adding colours could take you out of gamut. Unless you specifically know you want to be adding colours, you probably want to be using <hask>blend</hask> instead. | + | Lastly, colours are instance of a [[Monoid]] so colours can be "added" by using <hask>mappend</hask> (and <hask>mempty</hask> is a quick way to get black). However, like spotlights, adding colours makes more intense colours. Adding colours could take you out of gamut by making colours too intense. Unless you specifically know you want to be adding colours (for example, when writing a ray-tracer), you probably want to be using <hask>blend</hask> instead. |
== Getting colour coordinates out == | == Getting colour coordinates out == | ||
| Line 78: | Line 80: | ||
=== RGB triples === | === RGB triples === | ||
| - | The type <hask>RGB</hask> is special type of (strict) triple used to store colour coordinates. The functions <hask>channelRed</hask>, <hask>channelGreen</hask>, and <hask>channelBlue</hask> can be used to access the three fields. The constructor <hask>RGB</hask> will | + | The type <hask>RGB</hask> is special type of (strict) triple used to store colour coordinates. The functions <hask>channelRed</hask>, <hask>channelGreen</hask>, and <hask>channelBlue</hask> can be used to access the three fields. The constructor <hask>RGB</hask> will create such a triple. For example, |
<haskell> | <haskell> | ||
| Line 91: | Line 93: | ||
</haskell> | </haskell> | ||
| - | useful when working with functions that operate on RGB triples. | + | useful when working with functions that operate on RGB triples. These functions can be found in <hask>Data.Colour.RGBSpace</hask>. |
=== Back to colour coordinates === | === Back to colour coordinates === | ||
| Line 109: | Line 111: | ||
</haskell> | </haskell> | ||
| - | will produce an <hask>RGB Word8</hask>. Out of gamut channels be clamped | + | will produce an <hask>RGB Word8</hask>. Out-of-gamut channels will be clamped to the range 0 to 255. |
Lastly, the functions <hask>sRGB24show</hask> and <hask>sRGB24shows</hask> will produce colour strings of the form <hask>"#00aaff"</hask>. | Lastly, the functions <hask>sRGB24show</hask> and <hask>sRGB24shows</hask> will produce colour strings of the form <hask>"#00aaff"</hask>. | ||
| Line 115: | Line 117: | ||
== Transparent Colour == | == Transparent Colour == | ||
| - | Colours that are semi transparent are represented by the <hask>AlphaColour a</hask> type found in <hask>Data.Colour</hask>. Again the <hask>a</hask> type parameter represents the data type used for the internal representation and would typically be <hask>Double</hask>. | + | Colours that are semi transparent are represented by the <hask>AlphaColour a</hask> type found in <hask>Data.Colour</hask>. Again the <hask>a</hask> type parameter represents the data type used for the internal representation and would typically be <hask>Double</hask>. You can use <hask>alphaColourConvert</hask> to change the internal representation type of a semi-transparent colour. |
| - | Opaque | + | Opaque <hask>AlphaColour</hask>s are created from <hask>Colour</hask>s using <hask>opaque</hask>. For example. |
<haskell> | <haskell> | ||
| Line 141: | Line 143: | ||
</haskell> | </haskell> | ||
| - | will return a semi-transparent colour that is 60% of the opacity of <hask>ac</hask>. | + | will return a semi-transparent colour that is 60% of the opacity of <hask>ac</hask>. |
One should avoid dissolving with weights (the first parameter) greater than 1, as you may create invalid "super-opaque" colours. If you know the opacity is less than <hask>x</hask> then you can safely use weights no more than <hask>(recip x)</hask>. Negative weights will also produce invalid "super-transparent" colours. | One should avoid dissolving with weights (the first parameter) greater than 1, as you may create invalid "super-opaque" colours. If you know the opacity is less than <hask>x</hask> then you can safely use weights no more than <hask>(recip x)</hask>. Negative weights will also produce invalid "super-transparent" colours. | ||
| Line 149: | Line 151: | ||
</haskell> | </haskell> | ||
| - | Lastly, | + | Lastly, the key operation on transparent colours is compositing. Given two semitransparent colours <hask>acTop</hask> and <hask>acBottom</hask> |
<haskell> | <haskell> | ||
| Line 163: | Line 165: | ||
The opacity of a semi-transparent colour can be retrieved by the <hask>alphaChannel</hask> function. | The opacity of a semi-transparent colour can be retrieved by the <hask>alphaChannel</hask> function. | ||
| - | The pure colour of a semi-transparent colour <hask>ac</hask> can be retrieved by first compositing the colour | + | The pure colour of a semi-transparent colour <hask>ac</hask> can be retrieved by first compositing the colour over black, then darkening by the reciprocal of the alpha channel. |
<haskell> | <haskell> | ||
pureColour :: AlphaColour a -> Colour a | pureColour :: AlphaColour a -> Colour a | ||
| - | pureColour ac | a > 0 = darken (recip a) (ac `over` | + | pureColour ac | a > 0 = darken (recip a) (ac `over` black) |
| otherwise = error "transparent has no pure colour" | | otherwise = error "transparent has no pure colour" | ||
where | where | ||
Current revision
This page provides a short introduction to using the colour package on hackage.
Contents |
1 The Colour data type
TheColour DoubleYou may wish to make a type synonym for this type in your program if you will use it everywhere.
You can always use2 Creating colours
A collections of colours given by name can be found in thesRGB24 red green blue
will create the colour with those sRGB colour coordinates.
If you have threesRGB red green blue
3 Manipulating Colours
The colour operations are found in thethe function
blend 0.25 red greenwill create a new colour that is 25% red, and 75% green. The weight parameter (the first parameter) should be between 0 and 1, otherwise an out-of-gamut colour could result.
If you need to blend more than two colours, you can use multiple applications ofaffineCombo [(0.25,red),(0.5,green)] violet
will create a new colour that is 25% red, 50% green, and 25% violet. Again the weights should all be non-negative and the sum of the weights should be no more than 1, otherwise an out-of-gamut colour could result.
Colour intensity can be changed by usingdarken 0.4 turquoisewill produce a turquoise that is only 40% of the intensity of normal turquoise. The weight parameter (the first parameter) should be between 0 and 1, otherwise an out-of-gamut colour could result. However if you know that the intensity is low enough, you may safely "darken" by values greater than 1 (which will actually lighten the colour).
Lastly, colours are instance of a Monoid so colours can be "added" by using4 Getting colour coordinates out
To retrieve the sRGB coordinates of a colour, use the functions found in thetoSRGB chartreuse
4.1 RGB triples
The typeRGB 0.5 0.4 0.6
You might find the functions
curryRGB :: (RGB a -> b) -> a -> a -> a -> b uncurryRGB :: (a -> a -> a -> b) -> RGB a -> b
4.2 Back to colour coordinates
Recall that
toSRGB chartreuse
toSRGB24 khaki
5 Transparent Colour
Colours that are semi transparent are represented by theopaque goldenrod
moccasin `withOpacity` 0.7creates a colour that is 70% opaque and hence 30% transparent.
The valuedissolve 0.6 acanyColour `withOpacity` opacity == disolve opacity (opaque anyColour)
acTop `over` acBottom
5.1 Getting semi-transparent coordinates
The opacity of a semi-transparent colour can be retrieved by thepureColour :: AlphaColour a -> Colour a pureColour ac | a > 0 = darken (recip a) (ac `over` black) | otherwise = error "transparent has no pure colour" where a = alphaChannel ac
Note however, that transparent has no pure colour, and this case needs to be handled specially.
This operation is not natively provided because it is an operation that should be avoided. It is only really useful for interfacing with libraries that require pure colour components. Ideally it would be these libraries that implement conversion to and from