Title: | High Performance Colour Space Manipulation |
---|---|
Description: | The encoding of colour can be handled in many different ways, using different colour spaces. As different colour spaces have different uses, efficient conversion between these representations are important. The 'farver' package provides a set of functions that gives access to very fast colour space conversion and comparisons implemented in C++, and offers speed improvements over the 'convertColor' function in the 'grDevices' package. |
Authors: | Thomas Lin Pedersen [cre, aut] , Berendea Nicolae [aut] (Author of the ColorSpace C++ library), Romain François [aut] , Posit, PBC [cph, fnd] |
Maintainer: | Thomas Lin Pedersen <[email protected]> |
License: | MIT + file LICENSE |
Version: | 2.1.2.9000 |
Built: | 2024-11-16 05:35:40 UTC |
Source: | https://github.com/thomasp85/farver |
There are many ways to measure the distance between colours. farver
provides 5 different algorithms, ranging from simple euclidean distance in
RGB space, to different perceptual measures such as CIE2000.
compare_colour( from, to = NULL, from_space, to_space = from_space, method = "euclidean", white_from = "D65", white_to = white_from, lightness = 2, chroma = 1 )
compare_colour( from, to = NULL, from_space, to_space = from_space, method = "euclidean", white_from = "D65", white_to = white_from, lightness = 2, chroma = 1 )
from , to
|
Numeric matrices with colours to compare - the format is the
same as that for |
from_space , to_space
|
The colour space of |
method |
The method to use for comparison. Either |
white_from , white_to
|
The white reference of the from and to colour
space. Will only have an effect for relative colour spaces such as Lab and
luv. Any value accepted by |
lightness , chroma
|
Weight of lightness vs chroma when using CMC. Common
values are |
A numeric matrix with the same number of rows as colours in from
and the same number of columns as colours in to
. If to
is not given, only
the upper triangle will be returned.
NA
, NaN
, -Inf
, and Inf
are treated as invalid input and will result
in NA
values for the colour. If a given colourspace has finite bounds in
some of their channels, the input will be capped before conversion, and the
output will be capped before returning, so that both input and output colours
are valid colours in their respective space. This means that converting back
and forth between two colourspaces may result in a change in the colour if
the gamut of one of the spaces is less than the other.
r <- decode_colour(rainbow(10)) h <- decode_colour(heat.colors(15)) # Compare two sets of colours compare_colour(r, h, 'rgb', method = 'cie2000') # Compare a set of colours with itself compare_colour(r, from_space = 'rgb', method = 'cmc') # Compare colours from different colour spaces h_luv <- convert_colour(h, 'rgb', 'luv') compare_colour(r, h_luv, 'rgb', 'luv')
r <- decode_colour(rainbow(10)) h <- decode_colour(heat.colors(15)) # Compare two sets of colours compare_colour(r, h, 'rgb', method = 'cie2000') # Compare a set of colours with itself compare_colour(r, from_space = 'rgb', method = 'cmc') # Compare colours from different colour spaces h_luv <- convert_colour(h, 'rgb', 'luv') compare_colour(r, h_luv, 'rgb', 'luv')
This function lets you convert between different representations of colours.
The API is reminiscent of grDevices::convertColor()
, but the performance is
much better. It is not assured that grDevices::convertColor()
and
convert_colour()
provide numerically equivalent conversion at 16bit level as
the formula used are potentially slightly different. For all intend and
purpose, the resulting colours will be equivalent though.
convert_colour(colour, from, to, white_from = "D65", white_to = white_from)
convert_colour(colour, from, to, white_from = "D65", white_to = white_from)
colour |
A numeric matrix (or an object coercible to one) with colours
encoded in the rows and the different colour space values in the columns. For
all colourspaces except |
from , to
|
The input and output colour space. Allowed values are: |
white_from , white_to
|
The white reference of the from and to colour
space. Will only have an effect for relative colour spaces such as Lab and
luv. Any value accepted by |
A numeric matrix with the same number of rows as colour
and either
3 or 4 columns depending on the value of to
. If colour
is given as a
data.frame
the output will be a data.frame as well
NA
, NaN
, -Inf
, and Inf
are treated as invalid input and will result
in NA
values for the colour. If a given colourspace has finite bounds in
some of their channels, the input will be capped before conversion, and the
output will be capped before returning, so that both input and output colours
are valid colours in their respective space. This means that converting back
and forth between two colourspaces may result in a change in the colour if
the gamut of one of the spaces is less than the other.
This function and convertColor()
are not
numerically equivalent due to rounding errors, but for all intend and purpose
they give the same results.
grDevices::convertColor()
, grDevices::col2rgb()
spectrum <- decode_colour(rainbow(10)) spec_lab <- convert_colour(spectrum, 'rgb', 'lab') spec_lab # Convert between different white references convert_colour(spec_lab, 'lab', 'lab', white_from = 'D65', white_to = 'F10')
spectrum <- decode_colour(rainbow(10)) spec_lab <- convert_colour(spectrum, 'rgb', 'lab') spec_lab # Convert between different white references convert_colour(spec_lab, 'lab', 'lab', white_from = 'D65', white_to = 'F10')
This is a version of grDevices::col2rgb()
that returns the colour values in
the standard form expected by farver (matrix with a row per colour). As with
encode_colour()
it can do colour conversion on the fly, meaning that you can
decode a hex string directly into any of the supported colour spaces.
decode_colour(colour, alpha = FALSE, to = "rgb", white = "D65", na_value = NA)
decode_colour(colour, alpha = FALSE, to = "rgb", white = "D65", na_value = NA)
colour |
A character vector of hex-encoded values or a valid colour name
as given in |
alpha |
If |
to |
The output colour space. Allowed values are: |
white |
The white reference of the output colour space. Will only have
an effect for relative colour spaces such as Lab and luv. Any value accepted
by |
na_value |
A valid colour string or |
A numeric matrix with a row for each element in colour
and either
3, 4, or 5 columns depending on the value of alpha
and to
.
NA
, NaN
, -Inf
, and Inf
are treated as invalid input and will result
in NA
values for the colour. If a given colourspace has finite bounds in
some of their channels, the input will be capped before conversion, and the
output will be capped before returning, so that both input and output colours
are valid colours in their respective space. This means that converting back
and forth between two colourspaces may result in a change in the colour if
the gamut of one of the spaces is less than the other.
Other encoding and decoding functions:
encode_colour()
,
manip_channel
# basic use decode_colour(c('#43e1f6', 'steelblue', '#67ce9fe4')) # Return alpha as well (no alpha value is interpreted as 1) decode_colour(c('#43e1f6', 'steelblue', '#67ce9fe4'), alpha = TRUE) # Decode directly into specific colour space decode_colour(c('#43e1f6', 'steelblue', '#67ce9fe4'), to = 'lch')
# basic use decode_colour(c('#43e1f6', 'steelblue', '#67ce9fe4')) # Return alpha as well (no alpha value is interpreted as 1) decode_colour(c('#43e1f6', 'steelblue', '#67ce9fe4'), alpha = TRUE) # Decode directly into specific colour space decode_colour(c('#43e1f6', 'steelblue', '#67ce9fe4'), to = 'lch')
This is a version of grDevices::rgb()
that works with the standard colour
format used in farver (matrix or data.frame with colours in rows). It further
support taking input from any colour space.
encode_colour(colour, alpha = NULL, from = "rgb", white = "D65")
encode_colour(colour, alpha = NULL, from = "rgb", white = "D65")
colour |
A numeric matrix (or an object coercible to one) with colours
encoded in the rows and the different colour space values in the columns. For
all colourspaces except |
alpha |
A numeric vector between 0 and 1. Will be recycled to the number
of rows in |
from |
The input colour space. Allowed values are: |
white |
The white reference of the input colour space. Will only have an
effect for relative colour spaces such as Lab and luv. Any value accepted by
|
A character vector with colours encoded as #RRGGBB(AA)
NA
, NaN
, -Inf
, and Inf
are treated as invalid input and will result
in NA
values for the colour. If a given colourspace has finite bounds in
some of their channels, the input will be capped before conversion, and the
output will be capped before returning, so that both input and output colours
are valid colours in their respective space. This means that converting back
and forth between two colourspaces may result in a change in the colour if
the gamut of one of the spaces is less than the other.
The output may differ slightly from that of grDevices::rgb()
since
rgb()
doesn't round numeric values correctly.
Other encoding and decoding functions:
decode_colour()
,
manip_channel
spectrum <- decode_colour(rainbow(10)) encode_colour(spectrum) # Attach alpha values encode_colour(spectrum, alpha = c(0.5, 1)) # Encode from a different colour space spectrum_hcl <- convert_colour(spectrum, 'rgb', 'hcl') encode_colour(spectrum_hcl, from = 'hcl')
spectrum <- decode_colour(rainbow(10)) encode_colour(spectrum) # Attach alpha values encode_colour(spectrum, alpha = c(0.5, 1)) # Encode from a different colour space spectrum_hcl <- convert_colour(spectrum, 'rgb', 'hcl') encode_colour(spectrum_hcl, from = 'hcl')
This set of functions allows you to modify colours as given by strings, whithout first decoding them. For large vectors of colour values this should provide a considerable speedup.
set_channel( colour, channel, value, space = "rgb", white = "D65", na_value = NA ) add_to_channel( colour, channel, value, space = "rgb", white = "D65", na_value = NA ) multiply_channel( colour, channel, value, space = "rgb", white = "D65", na_value = NA ) raise_channel( colour, channel, value, space = "rgb", white = "D65", na_value = NA ) cap_channel( colour, channel, value, space = "rgb", white = "D65", na_value = NA ) get_channel(colour, channel, space = "rgb", white = "D65", na_value = NA)
set_channel( colour, channel, value, space = "rgb", white = "D65", na_value = NA ) add_to_channel( colour, channel, value, space = "rgb", white = "D65", na_value = NA ) multiply_channel( colour, channel, value, space = "rgb", white = "D65", na_value = NA ) raise_channel( colour, channel, value, space = "rgb", white = "D65", na_value = NA ) cap_channel( colour, channel, value, space = "rgb", white = "D65", na_value = NA ) get_channel(colour, channel, space = "rgb", white = "D65", na_value = NA)
colour |
A character string giving colours, either as hexadecimal strings or accepted colour names. |
channel |
The channel to modify or extract as a single letter, or
|
value |
The value to modify with |
space |
The colour space the channel pertains to. Allowed values are:
|
white |
The white reference of the channel colour space. Will only have
an effect for relative colour spaces such as Lab and luv. Any value accepted
by |
na_value |
A valid colour string or |
A character vector of the same length as colour
(or a numeric
vector in the case of get_channel()
)
Other encoding and decoding functions:
decode_colour()
,
encode_colour()
spectrum <- rainbow(10) # set a specific channel set_channel(spectrum, 'r', c(10, 50)) set_channel(spectrum, 'l', 50, space = 'lab') set_channel(spectrum, 'alpha', c(0.5, 1)) # Add value to channel add_to_channel(spectrum, 'r', c(10, 50)) add_to_channel(spectrum, 'l', 50, space = 'lab') # Multiply a channel multiply_channel(spectrum, 'r', c(10, 50)) multiply_channel(spectrum, 'l', 50, space = 'lab') # set a lower bound on a channel raise_channel(spectrum, 'r', c(10, 50)) raise_channel(spectrum, 'l', 20, space = 'lab') # set an upper bound on a channel cap_channel(spectrum, 'r', c(100, 50)) cap_channel(spectrum, 'l', 20, space = 'lab')
spectrum <- rainbow(10) # set a specific channel set_channel(spectrum, 'r', c(10, 50)) set_channel(spectrum, 'l', 50, space = 'lab') set_channel(spectrum, 'alpha', c(0.5, 1)) # Add value to channel add_to_channel(spectrum, 'r', c(10, 50)) add_to_channel(spectrum, 'l', 50, space = 'lab') # Multiply a channel multiply_channel(spectrum, 'r', c(10, 50)) multiply_channel(spectrum, 'l', 50, space = 'lab') # set a lower bound on a channel raise_channel(spectrum, 'r', c(10, 50)) raise_channel(spectrum, 'l', 20, space = 'lab') # set an upper bound on a channel cap_channel(spectrum, 'r', c(100, 50)) cap_channel(spectrum, 'l', 20, space = 'lab')
Colours in R are internally encoded as integers when they are passed around
to graphics devices. The encoding splits the 32 bit in the integer between
red, green, blue, and alpha, so that each get 8 bit, equivalent to 256
values. It is very seldom that an R user is subjected to this representation,
but it is present in the nativeRaster
format which can be obtained from
e.g. capturing the content of a graphic device (using dev.capture()
) or reading
in PNG files using png::readPNG(native = TRUE)
. It is very rare that you
might need to convert back and forth between this format, but it is provided
here for completeness.
encode_native(colour, ...) decode_native(colour)
encode_native(colour, ...) decode_native(colour)
colour |
For |
... |
Arguments passed on to |
encode_native()
returns an integer vector and decode_native()
returns a character vector, both matching the length of the input.
# Get native representation of navyblue and #228B22 native_col <- encode_native(c('navyblue', '#228B22')) native_col # Convert back decode_native(native_col)
# Get native representation of navyblue and #228B22 native_col <- encode_native(c('navyblue', '#228B22')) native_col # Convert back decode_native(native_col)