2007. január 15., hétfő

Various color conversion routines


Problem/Question/Abstract:

Is there a routine that can take a hex color value and convert it to a Delphi formatted value like: "Cornsilk1 Cornsilk1 255 248 220 #FFF8DC" into $00DCF8FF ?

Answer:

Solve 1:

function Swap32(aLong: Longint): Longint; assembler;
asm
  BSWAP eax
end;

function HexColorToColor(HexColor: string): TColor;
{input: '#FFF8DC' -> output $DCF8FF as TColor, use IntTohex to convert output to string again if needed}
begin
  Assert(Length(hexcolor)) > 1;
  Assert(hexcolor[1] = '#');
  hexcolor[1] := '$';
  Result := Swap32(StrToInt(hexcolor));
end;


Solve 2:

The safest way to convert this is to use the following:

{ ... }
var
  r, g, b: string;
begin
  r := Copy(HexValue, 2, 2);
  g := {... same, but for the GG part}
  b := {...same, but for the BB part}
  {Finally}
  DelphiColor := RGB(STrToInt('$' + R), STrToInt('$' + G), STrToInt('$' + B));
end;

Note: You should never shift the RGB data manually as the bit order is different in various screen modes. The first two bytes you refered to as $00 is the alpha channel, or color intensity. Packages like Graphics32 that support this feature normally allows you to manipulate this directly, where $FF is normal color, while $00 is completely invisible. But all of this can be avoided by using the example above. Try it out, you will see what i mean.


Solve 3:

A HTML color string has the format #RRGGBB, the color values are coded as two digit hexadecimal numbers. Delphi's TColor is an Integer value. If the bits 24..31 = 0 then the value describes a RGB color.

RGB color:
Bit
  0.. 7: red
  8..15: green
  16..23: blue
  24..31: 0

Source code:

{exchange red and blue color values}

function ByteSwapColor(Color: TColor): TColor; assembler;
asm
  BSWAP  EAX
  SHR  EAX, 8
end;

resourcestring
  SIsNotAHTMLColorValue = '%s is not a HTML color value';

procedure ConvertHTMLtoRGBColor(HTMLColor: string; var Color: TColor): Boolean;
begin
  Result := False;
  if Length(HTMLColor) <> 7 then
    Exit;
  if HTMLColor[1] <> '#' then
    Exit;
  HTMLColor[1] := '$';
  Color := StrToIntDef(HTMLColor, -1);
  Result := (0 <= Color) and (Color <= $FFFFFF);
  if Result then
    Color := ByteSwapColor(Color);
end;

function HTMLtoRGBColor(const HTMLColor: string): TColor;
begin
  if not ConvertHTMLtoRGBColor(HTMLColor, Result) then
    raise EConvertError.CreateFmt(SIsNotAHTMLColorValue, [HTMLColor]);
end;

function RGBtoHTMLColor(Color: TColor): string;
begin
  Color := RGBColor(Color);
  Color := ByteSwapColor(Color);
  Result := Format('#%.6x', [Color]);
end;


Solve 4:

function HTMLToDelphiColor(S: string): TColor;
var
  Red, Green, Blue: LongInt;
begin
  Red := StrToInt('$' + Copy(S, 1, 2));
  Green := StrToInt('$' + Copy(S, 3, 2));
  Blue := StrToInt('$' + Copy(S, 5, 2));
  Result := (Blue shl 16) + (Green shl 8) + Red;
end;

function ColorToHTMLHex(Color: TColor): string;
begin
  Result := IntToHex(ColorToRGB(Color), 6);
  Result := '#' + Copy(Result, 5, 2) + Copy(Result, 3, 2) + Copy(Result, 1, 2);
end;

Nincsenek megjegyzések:

Megjegyzés küldése