## 2011. április 12., kedd

### Convert hex color values into Delphi formatted ones

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 ?

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 (untested):

{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;