 Mirror

Convert between RGB and HSB color spaces and back (Views: 100)

 Problem/Question/Abstract:Is there any way to convert a set of colors that look good on a random background, and have them look "complimentary" and have good contrast with the background? What I have is a chart with an arbitrary background color. What I want to do is to automatically come up with a set of colors for channels that will look good on that arbitarary background color.Answer:I found some C++ functions to convert between RGB and HSB, and converted them to Pascal (hopefully correctly):procedure TForm1.RGBtoHSB(const r, g, b: Integer; var h, s, br: Double);var  largestColor: Integer; {holds the largest color (RGB) at the start}  lowestColor: Integer; {opposite of above}  hue: Double; {it puts the "H" in "HSB"}  saturation: Double; {S}  brightness: Double; {and the B}  redRatio: Double;  greenRatio: Double;  blueRatio: Double;begin  {assign largestColor to the greater of the red or green}  if (r <= g) then    largestColor := g  else    largestColor := r;  {now see if blue is bigger}  if (b > largestColor) then    largestColor := b;  {set lowestColor = to the smallest value}  if (g < r) then    lowestColor := g  else    lowestColor := r;  if (b < lowestColor) then    lowestColor := b;  {brightness is calculated like so:}  brightness := largestColor / 255.0;  {if the largestColor isn't zero (so we don't divide by zero) set the variable to  the difference of the two as a percentage of the largest}  if (largestColor <> 0) then    saturation := (largestColor - lowestColor) / largestColor  else    saturation := 0.0;  if (saturation = 0.0) then    hue := 0.0  else  begin    {some temporary variables to figure out the hue}    redRatio := (largestColor - r) / (largestColor - lowestColor);    greenRatio := (largestColor - g) / (largestColor - lowestColor);    blueRatio := (largestColor - b) / (largestColor - lowestColor);    {depending on which of the 3 was the highest, we calculate our hue}    if (r = largestColor) then      hue := blueRatio - greenRatio    else if (g = largestColor) then      hue := (2.0 + redRatio) - blueRatio    else {blue is largest}      hue := (4.0 + greenRatio) - redRatio;    {divide it by 6}    hue := hue / 6.0;    {I don't know if this prevents us from being negative                 (as in theworst outcome from the above operations is -1, or if this does    something different)    if (hue < 0.0) then      hue := hue + 1;    end;{pass back values}    h := hue;    s := saturation;    br := brightness;  end;procedure TForm1.HSBtoRGB(const hue, saturation, brightness: Double; var r, g, b:  Integer);const  max = 255;var  h: Double;  f: Double;  p: Double;  q: Double;  t: Double;begin  if (saturation = 0) then  begin    r := trunc(brightness * 255);    g := trunc(brightness * 255);    b := trunc(brightness * 255);  end  else  begin    h := (hue - floor(hue)) * 6.0;    f := h - floor(h);    p := brightness * (1.0 - saturation);    q := brightness * (1.0 - saturation * f);    t := brightness * (1.0 - (saturation * (1.0 - f)));    case trunc(h) of      0:        begin          r := trunc(brightness * 255);          g := trunc(t * max);          b := trunc(p * max);        end;      1:        begin          r := trunc(q * max);          g := trunc(brightness * max);          b := trunc(p * max);        end;      2:        begin          r := trunc(p * max);          g := trunc(brightness * max);          b := trunc(t * max);        end;      3:        begin          r := trunc(p * max);          g := trunc(q * max);          b := trunc(brightness * max);        end;      4:        begin          r := trunc(t * max);          g := trunc(p * max);          b := trunc(brightness * max);        end;      5:        begin          r := trunc(brightness * max);          g := trunc(p * max);          b := trunc(q * max);        end;    end;  end;end;I then convert each color and the background to HSB, add the Hues of both colors, and then convert the color back to RGB. It works most of the time, but generally the brightness of some of the colors are too bright when the background is too bright, or too dark when the background is too dark.

<< Back to main page