1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| const
ref_X = 95.047;
ref_Y = 100.000;
ref_Z = 108.883;
procedure CIELABtoXYZ(const CIEL,CIEa,CIEb: float; out X,Y,Z: float); inline;
var
var_X, var_Y, var_Z: float;
function ComputeaVar(aVar: float): float;
begin
if ( power(aVar, 3) > 0.008856 )
then Result := power(aVar, 3)
else Result := ( aVar - 16 / 116 ) / 7.787;
end;
begin
var_Y := ( CIEL + 16 ) / 116;
var_X := CIEa / 500 + var_Y;
var_Z := var_Y - CIEb / 200;
X := ref_X * ComputeaVar(var_X); //ref_X = 95.047 Observer= 2°, Illuminant= D65
Y := ref_Y * ComputeaVar(var_Y); //ref_Y = 100.000
Z := ref_Z * ComputeaVar(var_Z); //ref_Z = 108.883
end;
procedure XYZtoRGB(const X,Y,Z: float; out R,G,B: Byte); inline;
var
var_R, var_G, var_B: float;
var_X, var_Y, var_Z: float;
function ComputeaVar(aVar: float): float;
begin
if ( aVar > 0.0031308 )
then Result := 1.055 * power( aVar, ( 1 / 2.4 ) ) - 0.055
else Result := 12.92 * aVar;
end;
begin
var_X := X / 100; //X from 0 to 95.047 (Observer = 2°, Illuminant = D65)
var_Y := Y / 100; //Y from 0 to 100.000
var_Z := Z / 100; //Z from 0 to 108.883
var_R := var_X * 3.2406 + var_Y * -1.5372 + var_Z * -0.4986;
var_G := var_X * -0.9689 + var_Y * 1.8758 + var_Z * 0.0415;
var_B := var_X * 0.0557 + var_Y * -0.2040 + var_Z * 1.0570;
R := byte(round(ComputeaVar(var_R) * 255));
G := byte(round(ComputeaVar(var_G) * 255));
B := byte(round(ComputeaVar(var_B) * 255));
// si 'x := round(ComputeaVar(var_x)) * 255;' les couleurs sont justes mais aucun dégradé
// pareil avec trunc
// avec ou sans 'byte' c'est pareil.
end;
procedure CIELABtoRGB(const CIEL,CIEa,CIEb: float; out R,G,B: Byte); inline;
var
Xtmp,Ytmp,Ztmp: float;
begin
CIELABtoXYZ(CIEL,CIEa,CIEb, Xtmp,Ytmp,Ztmp);
XYZtoRGB(Xtmp,Ytmp,Ztmp, R,G,B);
end; |
Partager