procedure RGBtoHSB (RGB: TColor; var H, S, B : double);
  function Max (a, b : double): double;
  begin
    if a > b then
      Result := a
    else
      Result := b
  end;
  function Min (a, b : double): double;
  begin
    if a < b then
      Result := a
    else
      Result := b
  end;
var
  R, G, B, D, Cmax, Cmin: double;
begin
  R := GetRValue (RGB) / 255;
  G := GetGValue (RGB) / 255;
  B := GetBValue (RGB) / 255;
  Cmax := Max (R, Max (G, B));
  Cmin := Min (R, Min (G, B));
  B := (Cmax + Cmin) / 2;
  if Cmax = Cmin then
  begin
    H := 0;
    S := 0
  end else begin
    D := Cmax - Cmin;
    if B < 0.5 then
      S := D / (Cmax + Cmin)
    else
      S := D / (2 - Cmax - Cmin);
    if R = Cmax then
      H := (G - B) / D
    else if G = Cmax then
      H  := 2 + (B - R) /D
    else
      H := 4 + (R - G) / D;
    H := H / 6;
    if H < 0 then
      H := H + 1
  end
end;

解决方案 »

  1.   

    这段代码我知道,但是好像和PhotoShop的H/S/B不一样(乘以255以后)
      

  2.   

    要和 PhotoShop 的 HSB 兼容的话,看一下它的参考手册,上面应该有吧。我这里有段 Java 的完整代码:rgb to hsb:
    -----------
    Input:   red, green, and blue as integers scaled from 0 to 255
    Output:  hue, saturation, and brightness as floats scaled from 0.0 to 1.0    int bri = max(red, green, blue);
        if (bri == 0)
        {   // short-circuit now and avoid division by zero problems later
            brightness = 0.0;
            saturation = 0.0;
            hue        = 0.0;
            return;
        }    brightness = bri / 255.0;
        int desaturator = min(red, green, blue);
        if (bri == desaturator)
        {   // we're grey (and still have division by zero issues to bypass)
            saturation = 0.0;
            hue        = 0.0;
            return;
        }    saturation = (brightness - (desaturator / 255.0)) / brightness;
        int midigator = mid(red, green, blue);    // "domains" are 60 degrees of red, yellow, green, cyan, blue, or magenta
        // compute how far we are from a domain base
        float domainBase;
        float oneSixth = 1.0f / 6.0f;
        float domainOffset = (midigator - desaturator) /
                             (float)(bri - desaturator) / 6.0;
        if (red == bri)
        {
            if (midigator == green)
    {   // green is ascending
                domainBase = 0 / 6.0;       // red domain
    }
              else
      { // blue is descending
                domainBase = 5 / 6.0;       // magenta domain
        domainOffset = oneSixth - domainOffset;
      }
        }
          else if (grn == bri)
          {
            if (midigator == blue)
    {   // blue is ascending
                domainBase = 2 / 6.0;       // green domain
    }
              else
      { // red is descending
                domainBase = 1 / 6.0;       // yellow domain
        domainOffset = oneSixth - domainOffset;
      }
          }
          else
          {
            if (midigator == red)
    {   // red is ascending
                domainBase = 4 / 6.0;       // blue domain
    }
              else
      { // green is descending
                domainBase = 3 / 6.0;       // cyan domain
        domainOffset = oneSixth - domainOffset;
      }
          }    hue = domainBase + domainOffset;
        return;
    hsb to rgb
    ----------
    Input:   hue, saturation, and brightness as floats scaled from 0.0 to 1.0
    Output:  red, green, and blue as floats scaled from 0.0 to 1.0    if (brightness == 0.0)
        {   // safety short circuit again
            red   = 0.0;
            green = 0.0;
            blue  = 0.0;
            return;
        }    if (saturation == 0.0)
        {   // grey
            red   = brightness;
            green = brightness;
            blue  = brightness;
            return;
        }    float domainOffset;         // hue mod 1/6
        if (hue < 1.0/6)
        {   // red domain; green ascends
            domainOffset = hue;
            red   = brightness;
            blue  = brightness * (1.0 - saturation);
            green = blue + (brightness - blue) * domainOffset * 6;
        }
          else if (hue < 2.0/6)
          { // yellow domain; red descends
            domainOffset = hue - 1.0/6;
            green = brightness;
            blue  = brightness * (1.0 - saturation);
            red   = green - (brightness - blue) * domainOffset * 6;
          }
          else if (hue < 3.0/6)
          { // green domain; blue ascends
            domainOffset = hue - 2.0/6;
            green = brightness;
            red   = brightness * (1.0 - saturation);
            blue  = red + (brightness - red) * domainOffset * 6;
          }
          else if (hue < 4.0/6)
          { // cyan domain; green descends
            domainOffset = hue - 3.0/6;
            blue  = brightness;
            red   = brightness * (1.0 - saturation);
            green = blue - (brightness - red) * domainOffset * 6;
          }
          else if (hue < 5.0/6)
          { // blue domain; red ascends
            domainOffset = hue - 4.0/6;
            blue  = brightness;
            green = brightness * (1.0 - saturation);
            red   = green + (brightness - green) * domainOffset * 6;
          }
          else
          { // magenta domain; blue descends
            domainOffset = hue - 5.0/6;
            red   = brightness;
            green = brightness * (1.0 - saturation);
            blue  = red - (brightness - green) * domainOffset * 6;
          }    return;