How to Calculate Required Hue-Rotate to Generate Specific Colour

How to calculate required hue-rotate to generate specific colour?

The only way to get the exact match is to use an SVG color matrix filter.

For RGB color `#689d94`, which is `rgb(104, 157, 148)`, divide each primary color's value by 255:

$\frac{{\color{Red} 104}}{255}={\color{Red} 0.40784} ~~~~~~ \frac{{\color{DarkGreen} 157}}{255}={\color{DarkGreen} 0.61569} ~~~~~~ \frac{{\color{Blue} 148}}{255}={\color{Blue} 0.58039}$

Put these weights into the SVG `<filter>` matrix (5ᵗʰ column in the first 3 rows):

``<svg xmlns="http://www.w3.org/2000/svg">  <defs>    <filter id="689d94" color-interpolation-filters="sRGB">      <feColorMatrix type="matrix"         values="0 0 0 0 0.40784                 0 0 0 0 0.61569                 0 0 0 0 0.58039                 0 0 0 1 0"/>    </filter>  </defs></svg>``

The `<filter>` has to have id (I used the RGB hex code `689d94`), so we can use it as a reference.

Since some browsers (e.g. Firefox) don't see/use the SVG filter if the `display` property of the SVG element is set to `none`, and having this SVG element in HTML code would inconveniently occupy some space, the best way is to convert this SVG into a pure inline CSS filter.

To get an inline filter value, take the above listed SVG code, transform it into a single line by remove line breaks and unnecessary spaces, then prepend `url('data:image/svg+xml,` and append the previously mentioned id as `#689d94')`:

``div {  background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="71.063" height="60.938"><path d="M33.938 0l-16.97 19.906H1.625L0 21.781v8.781l1.25 1.407h4.781l5.875 28.969h46.969l6.188-28.97h4.687l1.313-1.343v-8.844L69.5 19.906H54.656L37.312 0h-3.375zm1.593 7.594l9.594 12.312H26.25l9.281-12.312zm-20.281 16s-.405 2.9 1.594 3.844c1.998.942 4.406.03 4.406.03-1.666 2.763-3.638 3.551-5.469 2.688-3.312-1.562-.531-6.562-.531-6.562zm41.188.031s2.749 4.969-.563 6.531c-2.487 1.162-4.848-1.541-5.438-2.656 0 0 2.377.88 4.375-.063 1.999-.942 1.625-3.812 1.625-3.812z"/></svg>') no-repeat; // optimized from http://richard.parnaby-king.co.uk/basket.svg  background-size: 100%;  display: inline-block;  height: 5em;  width: 5em;}#colored {  filter: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg"><defs><filter id="689d94" color-interpolation-filters="sRGB"><feColorMatrix type="matrix" values="0 0 0 0 0.40784 0 0 0 0 0.61569 0 0 0 0 0.58039 0 0 0 1 0"/></filter></defs></svg>#689d94');  margin-left: 20px;}``
``<!-- No <svg> in HTML; pure CSS --><div></div><div id="colored"></div><p style="background: #689d94">​</p>``

Why is hue-rotate(180deg) not its own inverse?

`hue-rotate(X) hue-rotate(X)` is not equivalent to `hue-rotate(X+X)` as shown below:

``.square {  height: 3rem;  padding: 1rem;  background: linear-gradient( 90deg, rgba(255, 0, 0, 1) 0%, rgba(255, 154, 0, 1) 10%, rgba(208, 222, 33, 1) 20%, rgba(79, 220, 74, 1) 30%, rgba(63, 218, 216, 1) 40%, rgba(47, 201, 226, 1) 50%, rgba(28, 127, 238, 1) 60%, rgba(95, 21, 242, 1) 70%, rgba(186, 12, 248, 1) 80%, rgba(251, 7, 217, 1) 90%, rgba(255, 0, 0, 1) 100%);  font-family: monospace;  font-weight: bold;  color: white;}.single-invert {  filter: hue-rotate(360deg);}.double-invert {  filter: hue-rotate(180deg) hue-rotate(180deg);}``
``<div class="square">filter: none</div><div class="square single-invert">filter: hue-rotate(360deg) </div><div class="square double-invert">filter: hue-rotate(180deg) hue-rotate(180deg)</div>``

Shift hue of an RGB Color

Edit per comment changed "are all" to "can be linearly approximated by".

Essentially, the steps you want are

``RBG->HSV->Update hue->RGB``

Since these can be approximated by linear matrix transforms (i.e. they are associative), you can perform it in a single step without any nasty conversion or loss of precision. You just multiple the transform matrices with each other, and use that to transform your colors.

There's a quick step by step here http://beesbuzz.biz/code/hsv_color_transforms.php

Here's the C++ code (With the saturation and value transforms removed):

``Color TransformH(    const Color &in,  // color to transform    float H){  float U = cos(H*M_PI/180);  float W = sin(H*M_PI/180);  Color ret;  ret.r = (.299+.701*U+.168*W)*in.r    + (.587-.587*U+.330*W)*in.g    + (.114-.114*U-.497*W)*in.b;  ret.g = (.299-.299*U-.328*W)*in.r    + (.587+.413*U+.035*W)*in.g    + (.114-.114*U+.292*W)*in.b;  ret.b = (.299-.3*U+1.25*W)*in.r    + (.587-.588*U-1.05*W)*in.g    + (.114+.886*U-.203*W)*in.b;  return ret;}``