SRL Archive - Research & Development Lounge

Color Debugger by Cazax


Cazax

2009-01-21 15:40:07

I made a color debugger for all your coloring needs :):
program Color_Debugger;
//By Cazax

Type
TRGB = Record
MinR, MinG, MinB : Integer;
MaxR, MaxG, MaxB : Integer;
MiddleColor : Integer;
End;

THSL = Record
MinH, MinS, MinL : Extended;
MaxH, MaxS, MaxL : Extended;
MiddleColor : Integer;
End;

TXYZ = Record
MinX, MinY, MinZ : Extended;
MaxX, MaxY, MaxZ : Extended;
MiddleColor : Integer;
End;

TColorSpace = (RGBcts, HSLcts, XYZcts);

Var
Colors : TIntegerArray;
RGB : TRGB;
HSL : THSL;
XYZ : TXYZ;


Procedure SetColors;
Begin

Colors := [{---------}]; // PUT COLORS HERE!

//Example: Colors := [14184135, 7516841, 94516525, 6843218];

End;

Function GetTolerance(Col1, Col2 : TColor; CTS : TColorSpace): Integer;
Var
V : Variant;
Begin
V := CTS;
ColorToleranceSpeed(V);
While Not SimilarColors(Col1, Col2, Result) Do
Inc(Result);
ColorToleranceSpeed(1);
End;

Procedure GetValues;
Var
I, H2, R, G, B : Integer;
H, S, L, X, Y, Z : Extended;
Begin
H2 := High(Colors);
For I := 0 To H2 Do
Begin
ColorToRGB(Colors[I], R, G, B);
ColorToHSL(Colors[I], H, S, L);
ColorToXYZ(Colors[I], X, Y, Z);
If I = 0 Then
Begin
RGB.MinR := R;
RGB.MinG := G;
RGB.MinB := B;
HSL.MinH := H;
HSL.MinS := S;
HSL.MinL := L;
XYZ.MinX := X;
XYZ.MinY := Y;
XYZ.MinZ := Z;
RGB.MaxR := R;
RGB.MaxG := G;
RGB.MaxB := B;
HSL.MaxH := H;
HSL.MaxS := S;
HSL.MaxL := L;
XYZ.MaxX := X;
XYZ.MaxY := Y;
XYZ.MaxZ := Z;
End;
RGB.MinR := Min(RGB.MinR, R);
RGB.MinG := Min(RGB.MinG, G);
RGB.MinB := Min(RGB.MinB, B);
HSL.MinH := MinE(HSL.MinH, H);
HSL.MinS := MinE(HSL.MinS, S);
HSL.MinL := MinE(HSL.MinL, L);
XYZ.MinX := MinE(XYZ.MinX, X);
XYZ.MinY := MinE(XYZ.MinY, Y);
XYZ.MinZ := MinE(XYZ.MinZ, Z);
RGB.MaxR := Max(RGB.MaxR, R);
RGB.MaxG := Max(RGB.MaxG, G);
RGB.MaxB := Max(RGB.MaxB, B);
HSL.MaxH := MaxE(HSL.MaxH, H);
HSL.MaxS := MaxE(HSL.MaxS, S);
HSL.MaxL := MaxE(HSL.MaxL, L);
XYZ.MaxX := MaxE(XYZ.MaxX, X);
XYZ.MaxY := MaxE(XYZ.MaxY, Y);
XYZ.MaxZ := MaxE(XYZ.MaxZ, Z);
End;
RGB.MiddleColor := RGBToColor((RGB.MinR + RGB.MaxR) Shr 1, (RGB.MinG + RGB.MaxG) Shr 1, (RGB.MinB + RGB.MaxB) Shr 1);
HSL.MiddleColor := HSLToColor((HSL.MinH + HSL.MaxH) / 2, (HSL.MinS + HSL.MaxS) / 2, (HSL.MinL + HSL.MaxL) / 2);
XYZ.MiddleColor := XYZToColor((XYZ.MinX + XYZ.MaxX) / 2, (XYZ.MinY + XYZ.MaxY) / 2, (XYZ.MinZ + XYZ.MaxZ) / 2);
End;

Procedure Debug;
Begin
Writeln('RGB Information:');
Writeln('Min Values: |R:' + IntToStr(RGB.MinR) + '|G:' + IntToStr(RGB.MinG) + '|B:' + IntToStr(RGB.MinB));
Writeln('Max Values: |R:' + IntToStr(RGB.MaxR) + '|G:' + IntToStr(RGB.MaxG) + '|B:' + IntToStr(RGB.MaxB));
Writeln('Mid Values: |R:' + IntToStr((RGB.MaxR + RGB.MinR) Shr 1) + '|G:' + IntToStr((RGB.MaxG + RGB.MinB) Shr 1) + '|B:' + IntToStr((RGB.MaxB + RGB.MinB) Shr 1));
Writeln('RGB Mid Color: ' + IntToStr(RGB.MiddleColor));
Writeln('RGB Tolerance: ' + IntToStr(GetTolerance(RGBToColor(RGB.MinR, RGB.MinG, RGB.MinB), RGBToColor(RGB.MaxR, RGB.MaxG, RGB.MaxB), RGBcts)));
Writeln('');
Writeln('HSL Information:');
Writeln('Min Values: |H:' + FloatToStr(HSL.MinH) + '|S:' + FloatToStr(HSL.MinS) + '|L:' + FloatToStr(HSL.MinL));
Writeln('Max Values: |H:' + FloatToStr(HSL.MaxH) + '|S:' + FloatToStr(HSL.MaxS) + '|L:' + FloatToStr(HSL.MaxL));
Writeln('Mid Values: |H:' + FloatToStr((HSL.MaxH + HSL.MinH) / 2) + '|S:' + FloatToStr((HSL.MaxS + HSL.MinS) / 2) + '|L:' + FloatToStr((HSL.MaxL + HSL.MinL) / 2));
Writeln('HSL Mid Color: ' + IntToStr(HSL.MiddleColor));
Writeln('Smod/HMod: ' + FloatToStr(Abs(HSL.MaxS - HSL.MinS) / Abs(HSL.MaxL - HSL.MinL)) + ' / ' + FloatToStr(Abs(HSL.MaxH - HSL.MinH) / Abs(HSL.MaxL - HSL.MinL)));

Writeln('HSL Tolerance: ' + IntToStr(GetTolerance(HSLToColor(HSL.MinH, HSL.MinS, HSL.MinL), HSLToColor(HSL.MaxH, HSL.MaxS, HSL.MaxL), HSLcts)));
Writeln('');
Writeln('XYZ Information:');
Writeln('Min Values: |X:' + FloatToStr(XYZ.MinX) + '|Y:' + FloatToStr(XYZ.MinY) + '|Z:' + FloatToStr(XYZ.MinZ));
Writeln('Max Values: |X:' + FloatToStr(XYZ.MaxX) + '|Y:' + FloatToStr(XYZ.MaxY) + '|Z:' + FloatToStr(XYZ.MaxZ));
Writeln('Mid Values: |X:' + FloatToStr((XYZ.MaxX + XYZ.MinX) / 2) + '|Y:' + FloatToStr((XYZ.MaxY + XYZ.MinY) / 2) + '|Z:' + FloatToStr((XYZ.MaxZ + XYZ.MinZ) / 2));
Writeln('XYZ Mid Color: ' + IntToStr(XYZ.MiddleColor));
Writeln('XYZ Tolerance: ' + IntToStr(GetTolerance(XYZToColor(XYZ.Minx, XYZ.MinY, XYZ.MinZ), XYZToColor(XYZ.MaxX, XYZ.MaxY, XYZ.MaxZ), XYZcts)));
Writeln('Sensitivity: ' + '?');
Writeln('');
End;

begin
SetColors;
GetValues;
Debug;
end.

Debugs RGB,HSL and XYZ min, max and middle values, tolerance, Sat mod and hue mod for CTS 2. I just need the formula for sensitivity to debug it :(

HarryJames

2009-01-21 23:00:26

wow, looks pretty cool :D

But what are each of these

HSL and XYZ min, max and middle values, tolerance, Sat mod and hue mod for CTS 2

Wizzup?

2009-01-22 06:43:19

Nice…
Although you remade something that's rather boring to make, and I am afraid Raymond already made it. :)

marpis

2009-01-22 10:53:50

From: 05hartor
wow, looks pretty cool :D

But what are each of these

HSL and XYZ min, max and middle values, tolerance, Sat mod and hue mod for CTS 2


http://www.villavu.com/forum/showthread.php?t=29072
i think there's pretty much everything

mastaraymond

2009-01-22 14:16:59

Hehe, made something like that a long time ago :-). It doesn't get the "scar" tolerances, but meh, you can calculate them yourself :p.

program New;
//By Mastaraymond
//0 = Min
//1 = Max
//2 = Middle
Const
RangePercent = 0.1;
Type
Test = Array[0..2] of Array[1..4] of Extended;
var
I,II : integer;
RGBColor : Array[1..3] of Integer;
// RGB : Array[0..2] of Array[1..3] of Integer;
RGB : Test;
XYZColor, HSLColor,HSVColor : Array[1..3] of Extended;
HSL,XYZ,HSV,CMYK : Test;
CMYKColor : Array[1..4] of Extended;
Colors : TIntegerArray;
Strings : Array of String;
Procedure Init;
begin;
// Colors := [5198934 ,5135441,6381669,4604231,6449246 ,4671810,5526097 ,5458771 ];//,2703449,1582132,1782329,1648439,2176330,2703192,2242380,1782329];
//Colors := [3684924 ,3621431 , 4867659 ,3090221 ,4935236 ,3157800 ,4012087 ,3944761 ];
Colors := [2840957 ,4087185 , 2309747 ,4154762 ,2377326 ,3231613 ,3164287 ];
//Colors := [2911630];
//Colors := [4086936,1128544,1066342 ,2312570 , 535132 ,2380147 ,602711 ,1456998 ,1389672 ];
//Colors := [4283764 , 3825769 ,4483447 ,3826793 , 3628128 , 3561053 , 4024685,4615546]; //Road
//Colors := [5141898 , 4618365 ,5275021 ,4684416 , 4485494 ,4485494,4882052 ]; //Wall
//{ RockColors Grey} Colors := [5854309,5198934 ,5135441,6381669 ,4604231,6449246,4671810,5526097,5458771,6908784];
// 4013622{ RockColors Grey Darker} Colors := [ 3684924 ,3621431,4867659,3090221,4935236,3157800,4012087, 3944761];
// 6310431{ RockColors Grey Darkest} Colors := [2106406,2042913,328914,1511703,3356718,1579282,2433569 ,2366243];
//Colors := [6908784,5394774,3816256,6974322,8220769,6908529,6584702,6776687,6189687];
//{Mime White}Colors := [8882328,9474209,13818088,11645377,11843270,13357537,11776964,11645377,11250363,10066345,12040393,12369614];
//{Mime Black} Colors := [2567223,3948878,4607327,4804706,3290944,5133671,4080984];
{Gas NEW rock} Colors := [8425623,10924982,7703440,8687247,9214623,8950938,10398384,9872296,10398384,7307916];
{Anvil} Colors := [6316392,5724254,3815998,5987426,4145220,5526619,6250599,4342343,5395032];
//{Bank} Colors := [3744043,6242636,6636881];
//{Door} Colors := [5802137,3428442];
//{Bank Brown} C olors := [2772828,2116184];
//{Bank grey} Colors := [4408136, 4079170,3881791,4737358];
//{Servan} Colors := [4216689,4084846,5073031, 8168915,5336719,7313091,5205132];
{Fishing spot colors } Colors := [16315112,15717309,14658440,14398100,11640193,14796717,11507072,14926246,15717294,14796723];
{Cage colors} Colors := [938360,804456,870764,736602,803683];
//{Trees} Colors := [399127,1780008,405550,531998];
//{Trees shadow} Colors := [198919,1027,264456,660498,329992]
{Trees Green} Colors := [1456698,1653044,1981744,1982001];
{Bank Booth EDGE} Colors := [3691619,3428189,3164502,3164502,2900815,2507859];
{Captcha stuff} Colors := [401410,3099946,5632,6580831];
{Test} Colors := [1250325];
end;

function XYZtoColor(X,Y,Z : extended) : TColor;
var
R, G, B : integer;
begin;
XYZtoRGB(x,y,z,R,G,B);
Result := RGBtoColor(R,G,B);
end;
Function RGBToColorFloat( R , G , B : Extended) : TColor;
begin;
Result := RGBtoColor(Round(R),Round(G),Round(B));
end;
Function HSLToColorFloat(H,S,L : Extended) : TColor;
begin;
Result := HSLToColor(H,S,L);
end;
Procedure RGBToCMYK(R,G,B : integer;var C,M,Y,K : Extended);
begin;
C := R / 255;
M := G / 255;
Y := B / 255;
C := 1 - C;
M := 1 - M;
Y := 1 - Y;
K := 1;
if ( C < 1 ) then K := C;
if ( M < K ) then K := M;
if ( Y < K ) then K := Y;
if K = 1 then
begin;
C := 0
M := 0
Y := 0
end else
begin;
C:= ( C - K ) / ( 1 - K ) * 100
M:= ( M - K ) / ( 1 - K ) * 100
Y:= ( Y - K ) / ( 1 - K ) * 100
K := K * 100
end;

end;

Procedure CMYKToRGB(C,M,Y,K : Extended;var r,g,b : integer);
begin;
R := Round(( 1 - ( C * ( 1 - K ) + K ) ) * 255);
G := Round(( 1 - ( M * ( 1 - K ) + K ) ) * 255);
B := Round(( 1 - ( Y * ( 1 - K ) + K ) ) * 255);
end;

Function CMYKToColor(C,M,Y,K : Extended) : TColor;
var
R, G, B : integer;
begin;
CMYKToRGB(C/100,M/100,Y/100,K/100,R,G,B);
Result := RGBtoColor(R,G,B);
end;

Procedure HSVToRGBRay(H,S,V : Extended;var R,G,B : integer);
var
Var_h,var_i,Var_1,Var_2,Var_3,var_r,var_g,var_b: Extended;
begin;
V := V / 100;
S := S / 100;
H := H / 100;
if S = 0 then
begin;
R := Round(V * 255);
G := Round(V * 255);
B := Round(V * 255);
end else
begin;
var_h := H * 6
if ( var_h = 6 ) then var_h := 0; //H must be < 1
var_i := floor( var_h ) //Or ... var_i = floor( var_h )
var_1 := V * ( 1 - S )
var_2 := V * ( 1 - S * ( var_h - var_i ) )
var_3 := V * ( 1 - S * ( 1 - ( var_h - var_i ) ) )
if ( var_i = 0 ) then begin; var_r := V ; var_g := var_3 ; var_b:= var_1 end
else if ( var_i = 1 ) then begin; var_r := var_2 ; var_g := V ; var_b := var_1 end
else if ( var_i = 2 ) then begin; var_r := var_1 ; var_g := V ; var_b := var_3 end
else if ( var_i = 3 ) then begin; var_r := var_1 ; var_g := var_2 ; var_b := V end
else if ( var_i = 4 ) then begin; var_r := var_3 ; var_g := var_1 ; var_b := V end
else begin; var_r := V ; var_g := var_1 ; var_b := var_2 end;
R := round(var_r * 255) //RGB results = 0 รท 255
G := round(var_g * 255)
B := Round(var_b * 255)
end;
end;
Function HSVToColor(H,S,V : Extended) : TColor;
var
R, G, B : integer;
begin;
HSVToRGBRay(H,S,V,R,G,B);
Result := RGBtoColor(R,G,B);
end;

Procedure RGBToHSVRay(RR,GG,BB : integer;var H,S,V : Extended);
var
R, G, B, D, Cmax, Cmin: Extended;

begin
R := RR / 255;
G := GG / 255;
B := BB / 255;
CMin := R;
if G < Cmin then Cmin := G;
if B < Cmin then Cmin := B;
CMax := R;
if G > Cmax then Cmax := G;
if B > Cmax then Cmax := B;
D := Cmax - Cmin;
V := CMax;
if Cmax = 0 then
S := 0
else
S := D / CMax;
if Cmax = CMin then
H := 0
else
begin;
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;
H := H * 100;
S := S * 100;
V := V * 100;
end;

Procedure WriteData(ColorProc : String; Data :Test; Name : String;PadAt : integer);
var
I,len : integer;
StrArr : Array of String;
V : TVariantArray;
S : Array of String;
begin;
Len := Length(Name) - 1;
SetLength(s,Len + 1);
For I := 1 to Len + 1 do
S[I - 1] := Name[I];
SetLength(StrArr,4);
SetLength(V,Len + 1);
StrArr[0] := 'Highest '+Name+' values = '+S[0]+': '+ Padr(FloatToStr(Data[1][1]),PadAt);
StrArr[1] := 'Lowest '+Name+' values = '+S[0]+': '+ Padr(FloatToStr(Data[0][1]),PadAt);
StrArr[2] := 'Differ '+Name+' values = '+S[0]+': '+ Padr(FloatToStr(Data[1][1] - Data[0][1]),PadAt);
StrArr[3] := 'Middle '+Name+' values = '+S[0]+': '+ Padr(FloatToStr(Data[2][1]),PadAt);
For I := 1 to Len do
begin;
StrArr[0] := StrArr[0] + ' | '+S[I]+': '+ Padr(FloatToStr(Data[1][I+ 1]),PadAt);
StrArr[1] := StrArr[1] + ' | '+S[I]+': '+ Padr(FloatToStr(Data[0][I+ 1]),PadAt);
StrArr[2] := StrArr[2] + ' | '+S[I]+': '+ Padr(FloatToStr(Data[1][I+ 1] - Data[0][I+ 1]) ,PadAt);
StrArr[3] := StrArr[3] + ' | '+S[I]+': '+ Padr(FloatToStr(Data[2][I+ 1]),PadAt);
end;
For I := 0 to 3 do
Writeln(StrArr[I]);
For I := 0 to Len do
V[I] := DATA[2][I + 1];

Writeln('Middle '+Name+' color = ' + FloatToStr( ThreadSafeCall(ColorProc,V)));
WritelN('');
end;
begin
Init;
For I:= 1 to 3 do
begin;
Writeln('');
RGB[0][I] := 255;
HSL[0][I] := 999; //Max is 240?
XYZ[0][I] := 999; //Max is ...?
HSV[0][I] := 999; //Donno x)
end;
For I:= 1 to 4 do
CMYK[0][I] := 999;
Strings := [' ','R: ','G: ','B: ','H: ','S: ','L: ','X: ','Y: ','Z: ','C: ','M: ','Y: ','K: ','H: ','S: ','V: '];
For I:= 0 to High(Colors) do
begin;
Strings[0] := Strings[0] + Padr('Color: '+FloatToStr(Colors[I]),16) +' | ';
ColortoRGB(Colors[I],RGBColor[1],RGBColor[2],RGBColor[3]);
ColortoHSL(Colors[I],HSLColor[1],HSLColor[2],HSLColor[3]);
RGBToCMYK(RGBColor[1],RGBColor[2],RGBColor[3], CMYKColor[1],CMYKColor[2],CMYKColor[3],CMYKColor[4]);
RGBtoXYZ(RGBColor[1],RGBColor[2],RGBColor[3],XYZColor[1],XYZColor[2],XYZColor[3]);
RGBToHSVRay(RGBColor[1],RGBColor[2],RGBColor[3],HSVColor[1],HSVColor[2],HSVColor[3]);
For II:= 1 to 3 do
begin;
RGB[0][II] := MinE(RGBColor[II],RGB[0][II]);
RGB[1][II] := MaxE(RGBColor[II],RGB[1][II]);
RGB[2][II] := (RGB[0][II] + RGB[1][II]) / 2.0;
HSL[0][II] := MinE(HSLColor[II],HSL[0][II]);
HSL[1][II] := MaxE(HSLColor[II],HSL[1][II]);
HSL[2][II] := (HSL[0][II] + HSL[1][II]) / 2.0;
XYZ[0][II] := MinE(XYZColor[II],XYZ[0][II]);
XYZ[1][II] := MaxE(XYZColor[II],XYZ[1][II]);
XYZ[2][II] := (XYZ[0][II] + XYZ[1][II]) / 2.0;
HSV[0][II] := MinE(HSVColor[II],HSV[0][II]);
HSV[1][II] := MaxE(HSVColor[II],HSV[1][II]);
HSV[2][II] := (HSV[0][II] + HSV[1][II]) / 2.0;
end;
For II := 1 to 4 do
begin;
CMYK[0][II] := MinE(CMYKColor[II],CMYK[0][II]);
CMYK[1][II] := MaxE(CMYKColor[II],CMYK[1][II]);
CMYK[2][II] := (CMYK[0][II] + CMYK[1][II]) / 2.0;
end;

For II := 1 to 3 do
Strings[II] := Strings[II] +Padr(FloatToStr (RGBColor[II]),16) +' | ';
For II := 4 to 6 do
Strings[II] := Strings[II] +Padr(FloatToStr(HSLColor[II-3]),16) +' | ';
For II := 7 to 9 do
Strings[II] := Strings[II] +Padr(FloatToStr(XYZColor[II-6]),16) +' | ';
For II := 10 to 13 do
Strings[II] := Strings[II] +Padr(FloatToStr(CMYKColor[II-9]),16) +' | ';
For II := 14 to 16 do
Strings[II] := Strings[II] +Padr(FloatToStr(HSVColor[II-13]),16) +' | ';
end;
For I:= 0 to 16 do
Delete(Strings[I],Length(Strings[I])-2,3);
For I:= 0 to 16 do
begin;
if (I = 1) or (I = 4)or (I = 7) or(I=10) or (I = 14) then Writeln('');
Writeln(Strings[I]);
end;
WritelN('');
WriteData('CMYKToColor',CMYK,'CMYK',17);
WriteData('HSVToColor' ,HSV ,'HSV',17);
WriteData('RGBToColorFloat' ,RGB ,'RGB',3);
WriteData('HSLToColorFloat' ,HSL ,'HSL',17);
WriteData('XYZToColor' ,XYZ ,'XYZ',17);
end.

Nose Smasher

2009-03-02 00:38:29

So for CTS(2) mods:

Smod = MidH / MidL? isn't that the Hmod though?

Think you made a typo :p
Writeln('Smod/HMod: ' + FloatToStr(((HSL.MaxH + HSL.MinH) / 2) / ((HSL.MaxL + HSL.MinL) / 2)) + ' / ' + FloatToStr(((HSL.MaxS + HSL.MinS) / 2) / ((HSL.MaxL + HSL.MinL) / 2)));

Put Smod and Hmod backwards ^.^

Cazax

2009-03-05 16:48:49

No, it's:
Writeln('Smod/HMod: ' + FloatToStr(Abs(HSL.MaxS - HSL.MinS) / Abs(HSL.MaxL - HSL.MinL)) + ' / ' + FloatToStr(Abs(HSL.MaxH - HSL.MinH) / Abs(HSL.MaxL - HSL.MinL)));
It's still a typo :p