unit RGBYUV;
interface
uses Windows,Classes,Graphics,Math;
function RGBToColor(R,G,B: Byte): TColor;overload;
function RGBToColor(Color : Longint): TColor;overload;
procedure ColorToYUV(RGB: TColor; out Y, Cb, Cr: byte);
function YUVtoColor(Y, Cb, Cr: Byte): TColor;
implementation
function RGBToColor(R,G,B: Byte): TColor;
begin
Result := R or (G shl 8) or (B shl 16);
end;
function RGBToColor(Color : Longint): TColor;
var
R,G,B,A : Byte;
begin
R := Color and $FF;
G := (Color shr 8) and $FF;
B := (Color shr 16) and $FF;
A := $00;
Result := R or (G shl 8) or (B shl 16) or (A shl 24);
end;
procedure ColorToRGB(Color: TColor; out R, G, B: Byte);
begin
R := Color and $FF;
G := (Color shr 8) and $FF;
B := (Color shr 16) and $FF;
end; procedure ColorToCMY(Color: TColor; out C, M, Y: Byte);
var
R,G,B : Byte;
begin
ColorToRGB(Color, R, G, B);
C := 255 - R;
M := 255 - G;
Y := 255 - B;
end; function CMYToColor(C, M, Y: Byte): TColor;
begin
Result := (255 - C) or ((255 - M) shl 8) or ((255 - Y) shl 16);
end; function HSLtoColor(H, S, L: Double): TColor;
var
M1, M2: double;
function HueToColourValue (Hue: double) : byte;
var
V : double;
begin
if Hue < 0 then
Hue := Hue + 1
else
if Hue > 1 then
Hue := Hue - 1;
if 6 * Hue < 1 then
V := M1 + (M2 - M1) * Hue * 6
else
if 2 * Hue < 1 then
V := M2
else
if 3 * Hue < 2 then
V := M1 + (M2 - M1) * (2/3 - Hue) * 6
else
V := M1;
Result := round (255 * V)
end;
var
R, G, B: byte;
begin
if S = 0 then
begin
R := round (255 * L);
G := R;
B := R
end
else
begin
if L <= 0.5 then
M2 := L * (1 + S)
else
M2 := L + S - L * S;
M1 := 2 * L - M2;
R := HueToColourValue (H + 1/3);
G := HueToColourValue (H);
B := HueToColourValue (H - 1/3)
end;
Result := RGB (R, G, B)
end;
procedure ColortoHSL(RGB: TColor; out H, S, L: double);
var
R, G, B : double;
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));
// calculate luminosity
L := (Cmax + Cmin) / 2;
if Cmax = Cmin then
begin
H := 0;// it's actually undefined
S := 0;
end
else
begin
D := Cmax - Cmin;
// calculate Saturation
if L < 0.5 then
S := D / (Cmax + Cmin)
else
S := D / (2 - Cmax - Cmin);
// calculate Hue
D_R := (((Cmax - R) / 6) + (D / 2)) / D;
D_G := (((Cmax - G) / 6) + (D / 2)) / D;
D_B := (((Cmax - B) / 6) + (D / 2)) / D;
if R = Cmax then H := (D_B - D_G)
else if G = Cmax then H := (1 / 3) + D_R - D_B
else if B = Cmax then H := (2 / 3) + D_G - D_R;
if H < 0 then H := H + 1;
if H > 1 then H := H - 1;
end;
end;
procedure ColorToYUV(RGB: TColor; out Y, Cb, Cr: byte);
{
Lum (Y) ranges from 16 to 235.
Cb (U) ranges from 16 to 240.
Cr (V) ranges from 16 to 240.
}
var
R,G,B : byte;
t: Double;
begin
R := GetRValue(RGB);
G := GetGValue(RGB);
B := GetBValue(RGB);
Y := Round( (0.257 * R) + (0.504 * G) + (0.098 * B) + 16 );
Cb := Round( (-0.148 * R) - (0.291 * G) + (0.439 * B) + 128 );
Cr := Round( (0.439 * R) - (0.368 * G) - (0.071 * B) + 128 );
{y := Round(0.299*R + 0.587*G + 0.114*B);
Cb := Round(0.564*(B - Y ));
Cr := Round(0.713*(R - Y )) }
end;
function YUVtoColor(Y, Cb, Cr: Byte): TColor;
{
Lum (Y) ranges from 16 to 235.
Cb (U) ranges from 16 to 240.
Cr (V) ranges from 16 to 240.
}
var
R,G,B: Byte;
begin
G := Round( (1.164 * (Y-16)) - (0.391 * (Cb-128)) - (0.813 * (Cr-128)) );
R := Round( (1.164 * (Y-16)) + (1.596 * (Cr-128)) );
B := Round( (1.164 * (Y-16)) + (2.018 * (Cb-128)) );
Result := RGBToColor(R, G, B);
end;
end.