SRL Archive - Help and Support

help me fix my rgb to hsl converter


Bramble

2007-01-24 20:33:15

this version of hsl splitter, will also return rgb values if you wish,
note:: to do this just edit the writeln(blahblahblah) in the main loop
edit:: this version will now find maxs and mins of hsl values and rgb values

program rgb2hsl;
type rgbcolor =record
red,green,blue:integer;
end;
var var_min,Var_max,var_r,var_b,var_g,L,H,S,sixty,threesixty,onetwenty,twoforty,zero:extended;
a,b,c,I,maxofarray,rgbrange,hslrange:integer;color:Array[0..24] of integer;color2:rgbcolor;
rangeofvalues,maxofoutput,minofoutput:array[0..5] of integer;

procedure setup;
begin
Color[0]:=2972255;
Color[1]:=3694710;
Color[2]:=2906462;
Color[3]:=3498354;
Color[4]:=2905438;
Color[5]:=3697526;
Color[6]:=3169639;
Color[7]:=3565682;
Color[8]:=3233130;
Color[9]:=3500657;
Color[10]:=3564660;
Color[11]:=3237484;
Color[12]:=2576726;
Color[13]:=2639191;
Color[14]:=2510675;
Color[15]:=2840411;
Color[16]:=2770778;
Color[17]:=3233130;
Color[18]:=3104870;
Color[19]:=3036516;
Color[20]:=3167079;
Color[21]:=3562610;
Color[22]:=3103332;
Color[23]:=3231336;
Color[24]:=2772058;
maxofarray:=24;
end;

function color2rgb(color:integer):rgbcolor;
begin
result.red:=(color mod 256);
result.green:=((color/256) mod 256);
result.blue:=((color/256) / 256);
end;

function rgb2color(rgb:rgbcolor):integer;
begin
result:=(((rgb.blue*256)+rgb.green)*256)+rgb.red
end;

Procedure minmax;
var test1,test2:integer;
begin
Var_r:=color2.Red/255;
Var_g:=color2.Green/255;
Var_b:=color2.Blue/255;
test1:=min(color2.red,color2.green);
test2:=min(color2.green,color2.blue);
var_min:= min(test1,test2)/255;
test1:=max(color2.red,color2.green);
test2:=max(color2.green,color2.blue);
var_max:=max(test1,test2)/255;
zero:=0.0;
threesixty:=1.0;
sixty:=0.16666666666666666666666666666667;
onetwenty:=0.33333333333333333333333333333333;
twoforty:=0.66666666666666666666666666666667;
end;

Procedure Converter;
begin
L:= (Var_max+Var_min)/2
if (L<0.5) or (L=0.5) then
S:=(Var_max-Var_min)/(2*L)
else if L=0 then
S:=0
else
s:=(var_max-var_min)/(2-(var_max+var_min));

if (var_max = Var_r) and (var_b=Var_min) then
H:=(sixty*((var_g-Var_b)/(var_max-Var_min)))+zero;
if (var_max=Var_r) and (var_g<Var_b) then
h:=(sixty*((var_g-Var_b)/(var_max-Var_min))+threesixty);
if (var_max=Var_g) then
H:=sixty*((var_b-Var_r)/(var_max-Var_min))+onetwenty;
if (var_max = var_b) then
h:=sixty*((var_r-Var_g)/(var_max-Var_min))+ twoforty;
if (var_Max=Var_min) then
H:=0;
end;

procedure getmaxmin;
begin
if I=0 then
begin
maxofoutput[0]:=A;
maxofoutput[1]:=B;
maxofoutput[2]:=C;
maxofoutput[3]:=color2.red;
maxofoutput[4]:=color2.green;
maxofoutput[5]:=color2.blue;
minofoutput[0]:=A;
minofoutput[1]:=B;
minofoutput[2]:=C;
minofoutput[3]:=color2.red;
minofoutput[4]:=color2.green;
minofoutput[5]:=color2.blue;
end
else
begin
maxofoutput[0]:=max(maxofoutput[0],A);
maxofoutput[1]:=max(maxofoutput[1],b);
maxofoutput[2]:=max(maxofoutput[2],C);
maxofoutput[3]:=max(maxofoutput[3],color2.red);
maxofoutput[4]:=max(maxofoutput[4],color2.green);
maxofoutput[5]:=max(maxofoutput[5],color2.blue);
minofoutput[0]:=Min(minofoutput[0],A);
minofoutput[1]:=Min(minofoutput[1],B);
minofoutput[2]:=Min(minofoutput[2],C);
minofoutput[3]:=Min(minofoutput[3],color2.red);
minofoutput[4]:=Min(minofoutput[4],color2.green);
minofoutput[5]:=Min(minofoutput[5],color2.blue);
end;
end;
procedure rangeofvalue;
begin
rangeofvalues[0]:=maxofoutput[0]-minofoutput[0];
rangeofvalues[1]:=maxofoutput[1]-minofoutput[1];
rangeofvalues[2]:=maxofoutput[2]-minofoutput[2];
rangeofvalues[3]:=maxofoutput[3]-minofoutput[3];
rangeofvalues[4]:=maxofoutput[4]-minofoutput[4];
rangeofvalues[5]:=maxofoutput[5]-minofoutput[5];
rgbrange:=rangeofvalues[3]*rangeofvalues[4]*rangeofvalues[5];
hslrange:=rangeofvalues[0]*rangeofvalues[1]*rangeofvalues[2];
end;

begin
setup;
repeat
color2:=color2rgb(color[i]);
minmax;
converter;
a:=trunc(H*240);
b:=trunc(s*240);
c:=trunc(L*240);
getmaxmin;
//notes: A is Hue, B is Saturation, L is lightness or luminosity
// color2.red/color2.green/color2.blue is the rgb values
// color[i] is the current color
writeln (inttostr(a)+' = H '+inttostr(b)+' = s '+inttostr(c)+' = L');
if (I=maxofarray) then
begin
rangeofvalue;
//notes: for maxofoutput and minofoutput arrays, 0 is hue, 1 is saturation,
// 2 is luminosity, 3 is red, 4 is green, 5 is blue.
//this if statement will find max or min of hsl/rgb vars, u select which to output
writeLn(inttostr(maxofoutput[0])+' = max of Hue | '+inttostr(minofoutput[0])+ ' = min of Hue');
writeLn(inttostr(maxofoutput[1])+' = max of Saturation | '+inttostr(minofoutput[1])+ ' = min of Saturation');
writeLn(inttostr(maxofoutput[2])+' = max of Luminosity | '+inttostr(minofoutput[2])+ ' = min of Luminosity');
//note: rangeofvalues is like max/minofoutput with array,
// but it displays the range of the values
writeLn(inttostr(rangeofvalues[0])+' = H range | '+inttostr(rangeofvalues[1])+' = S range | '+inttostr(rangeofvalues[2])+' = L range');
// note: hslrange = total amount of colors in hsl range, same with rgbrange except
// it does rgb range
writeLn(inttostr(hslrange)+' = total colors possible between ranges');


end;
i:=i+1;
until (i=(maxofarray+1))
end.

Boreas

2007-01-24 20:44:33

heres what i got, it 'works' but its not giving me the numbers that paint edit custom colors does

program New;
{.include SRL/SRL.scar}
type rgbcolor =record
red,green,blue:integer;
end;

type hslcolor =record
h,s,l:integer;
end;

var testhsl:hslcolor;
testrgb:rgbcolor;

function maxex(first,second:extended):extended;
begin
if first>second then result:=first;
if first<second then result:=second;
if first=second then result:=first;
end;
function minex(first,second:extended):extended;
begin
if first>second then result:=second;
if first<second then result:=first;
if first=second then result:=first;
end;



function rgbtohsl(rgb:rgbcolor):hslcolor;
var r,g,b,delr,delg,delb,h,s,l,maxcolor,mincolor,deltacolor:extended;

begin
r:=rgb.red/255.0;
g:=rgb.green/255.0;
b:=rgb.blue/255.0;



maxcolor:=maxex(r,maxex(g,b));
mincolor:=minex(r,minex(g,b));
deltacolor:=maxcolor-mincolor;

l:=(maxcolor+mincolor)/2;

if (deltacolor=0) then
begin
h:=0;
s:=0;
// l:=r;
end;
if not(deltacolor=0)then
begin
if (l<0.5) then
s:=deltacolor/(maxcolor+mincolor)
else s:=deltacolor/(2-maxcolor-mincolor);
{
if (r=maxcolor) then
h:=(g-b)/(maxcolor-mincolor)
else if (g=maxcolor) then
h:= 2.0 + (b-r)/(maxcolor-mincolor)
else h:=4.0 + (r-g)/(maxcolor-mincolor);
}

delr:=(((maxcolor-r)/6)+(deltacolor/2))/deltacolor;
delg:=(((maxcolor-g)/6)+(deltacolor/2))/deltacolor;
delb:=(((maxcolor-b)/6)+(deltacolor/2))/deltacolor;

if (r=maxcolor) then h:=delb-delg;
if (g=maxcolor) then h:=(1/3)+delr-delb;
if (b=maxcolor) then h:=(2/3)+delg-delr;

if (h<0) then h:=h+1;
if (h>1) then h:=h-1;


{h:=h/6;
if (h<0) then h:=h+1;
}
result.h:=round(h*255.0);
result.s:=round(s*255.0);
result.l:=round(l*255.0);


end;
end;

begin
SetupSRL;
testrgb.red:=64;
testrgb.green:=206;
testrgb.blue:=199;


testhsl:=rgbtohsl(testrgb);

writeln(inttostr(testhsl.h));
writeln(inttostr(testhsl.s));
writeln(inttostr(testhsl.l));


end.

ill look at it again later


edit: this works except scale for hue
program New;
{.include SRL/SRL.scar}
type rgbcolor =record
red,green,blue:integer;
end;

type hslcolor =record
h,s,l:integer;
end;

var testhsl:hslcolor;
testrgb:rgbcolor;

function maxex(first,second:extended):extended;
begin
if first>second then result:=first;
if first<second then result:=second;
if first=second then result:=first;
end;
function minex(first,second:extended):extended;
begin
if first>second then result:=second;
if first<second then result:=first;
if first=second then result:=first;
end;



function rgbtohsl(rgb:rgbcolor):hslcolor;
var r,g,b,delr,delg,delb,h,s,l,maxcolor,mincolor,deltacolor:extended;

begin
r:=rgb.red/255.0;
g:=rgb.green/255.0;
b:=rgb.blue/255.0;

writeln('r='+floattostr(r));
writeln('g='+floattostr(g));
writeln('b='+floattostr(b));


maxcolor:=maxex(r,maxex(g,b));
mincolor:=minex(r,minex(g,b));
deltacolor:=maxcolor-mincolor;

l:=(maxcolor+mincolor)/2;

if (deltacolor=0) then
begin
h:=0;
s:=0;
// l:=r;
end;
if not(deltacolor=0)then
begin
if (l<0.5) then
s:=deltacolor/(maxcolor+mincolor)
else s:=deltacolor/(2-maxcolor-mincolor);
{
if (r=maxcolor) then
h:=(g-b)/(maxcolor-mincolor)
else if (g=maxcolor) then
h:= 2.0 + (b-r)/(maxcolor-mincolor)
else h:=4.0 + (r-g)/(maxcolor-mincolor);
}

delr:=(((maxcolor-r)/6)+(deltacolor/2))/deltacolor;
delg:=(((maxcolor-g)/6)+(deltacolor/2))/deltacolor;
delb:=(((maxcolor-b)/6)+(deltacolor/2))/deltacolor;
writeln('max='+floattostr(maxcolor));

if (r=maxcolor) then h:=delb-delg;
if (g=maxcolor) then h:=(1/3)+delr-delb;
if (b=maxcolor) then h:=(2/3)+delg-delr;
writeln('h='+floattostr(h));

if (h<0) then h:=h+1;
if (h>1) then h:=h-1;


{h:=h/6;
if (h<0) then h:=h+1;
}
result.h:=round(h*240.0);
result.s:=round(s*240.0);
result.l:=round(l*240.0);


end;
end;

begin
SetupSRL;
testrgb.red:=64;
testrgb.green:=206;
testrgb.blue:=199;


testhsl:=rgbtohsl(testrgb);

writeln(inttostr(testhsl.h));
writeln(inttostr(testhsl.s));
writeln(inttostr(testhsl.l));


end.

Bramble

2007-01-25 00:02:57

here is an autotyper so you dont have to type in all the array information for your colors

instructions:
copy and paste your colors under procedure setup
ex:
procedure setup:
begin
color
color
color
color
maxofarray:=blahblah blah
next step is to make sure your cursor is on the line with BEGIN
now target ur scar window and click start on the autotyper

program New;
{.include srl/srl.scar}
var amountofcolors,parentnum,secondnum,rotation,tries:integer;


// when you use this, make sure the cursor is 1 line above ur first color
procedure Setup;
begin
Parentnum:=48;
secondnum:=47;
amountofcolors:=24;//note: put ur amount of colors to modify 4 scar here
end;

procedure whichnumber;
begin
rotation:=rotation+1;
if rotation= 11 then
rotation:=1;
if rotation =1 then
if tries>10 then
parentnum:=parentnum+1;
secondnum:=secondnum+1;
if secondnum=58 then
secondnum:=48;
end;


begin
activateclient;
wait(5000);
setup;
repeat
tries:=Tries+1;
keydown(40);
keyup(40);
keydown(36);
keyup(36);
keydown(67);
keyup(67);
keydown(79);
keyup(79);
keydown(76);
keyup(76);
keydown(79);
keyup(79);
keydown(82);
keyup(82);
keydown(219);
keyup(219);

whichnumber;
if tries>10 then
begin
keydown(parentnum);
keyup(parentnum);
end;
keydown(secondnum);
keyup(secondnum);
keydown(221);
keyup(221);
keydown(16);
keydown(186);
keyup(186);
keyup(16);
keydown(187);
keyup(187);
keydown(35);
keyup(35);
keydown(186);
keyup(186);
until (tries=amountofcolors+1)
end.

Boreas

2007-01-25 13:11:56

nice, this makes it so much easier lol

Bramble

2007-01-26 13:11:16

i created a converter for hsl back to scar colors, but it seems that my hsl to rgb formula is off, or my round() functions arent doing their job,

program HslToScar;
var color:integer;
Function makergb(H,S,L:extended):integer;
var var_1,Var_2,onesixth,onethird,twothird:extended;
Var_3,Color:array[0..2] of extended;
red,green,blue,color2,i:integer;
begin
H:=H/240;
S:=S/240;
L:=L/240;
onesixth:=0.16666666666666666666666666666667;
onethird:=0.33333333333333333333333333333333;
twothird:=0.66666666666666666666666666666667;
If (s=0) then
begin
Red:=Trunc(L*255);
Green:=Trunc(L*255);
Blue:=Trunc(L*255);
end
else
begin
if (L<0.5) then
var_2:=L*(1+s)
else
var_2:=(L+S)-(S*L);
var_1:=(2*L)-Var_2;
var_3[0]:=h+(onethird);
var_3[1]:=h;
var_3[2]:=h-(onethird);
repeat
if var_3[i]<0 then
var_3[i]:=var_3[i]+1.0
else if var_3[i]>1 then
var_3[i]:=var_3[i]-1.0;

if var_3[i]<(onesixth) then
color[i]:=var_1+((((var_2-Var_1)*6.0)*var_3[i]))
else if (onesixth<var_3[i]) and (var_3[i]<0.5) then
Color[i]:=var_2
else if (var_3[i]=Onesixth) then
Color[i]:=var_2
else if (0.5<var_3[i]) and (var_3[i]<twothird)then
color[i]:=var_1+((var_2-var_1)*(twothird-var_3[i])*6.0)
else if (var_3[i]=0.5) then
color[i]:=var_1+((var_2-var_1)*(twothird-var_3[i])*6.0)
else
color[i]:=var_1;
i:=i+1;
until(i=3);
red:=round(color[0]*255);
green:=round(Color[1]*255);
Blue:=round(Color[2]*255);
end;
result:=(((blue*256)+green)*256)+red
end;


begin
color:=makergb(85,133,108);
writeln(inttostr(color));
end.


and here is a roadcolor finder using the rgb to scar formula, it works fast, but im afraid it might hit a color one time that returns differnt cause of the error in the script somewhere, im trying to fix that as we speak

program New;
{.include srl/srl.scar}
var Color,color2,time1,time2:integer;
Const
x1=0;x2=240;
y1=6;y2=11;
z1=85;z2=115;

Function makergb(H,S,L:extended):integer;
var var_1,Var_2,onesixth,onethird,twothird:extended;
Var_3,Color:array[0..2] of extended;
red,green,blue,i:integer;
begin
H:=H/240;
S:=S/240;
L:=L/240;
onesixth:=0.16666666666666666666666666666667;
onethird:=0.33333333333333333333333333333333;
twothird:=0.66666666666666666666666666666667;
If (s=0) then
begin
Red:=Trunc(L*255);
Green:=Trunc(L*255);
Blue:=Trunc(L*255);
end
else
begin
if (L<0.5) then
var_2:=L*(1+s)
else
var_2:=(L+S)-(S*L);
var_1:=(2*L)-Var_2;
var_3[0]:=h+(onethird);
var_3[1]:=h;
var_3[2]:=h-(onethird);
repeat
if var_3[i]<0 then
var_3[i]:=var_3[i]+1.0
else if var_3[i]>1 then
var_3[i]:=var_3[i]-1.0;
I:=I+1;
until (i=3)
I:=0;
repeat

if var_3[i]<(onesixth) then
color[i]:=var_1+((((var_2-Var_1)*6.0)*var_3[i]))
else if (onesixth<var_3[i]) and (var_3[i]<0.5) then
Color[i]:=var_2
else if (var_3[i]=Onesixth) then
Color[i]:=var_2
else if (0.5<var_3[i]) and (var_3[i]<twothird)then
color[i]:=var_1+((var_2-var_1)*(twothird-var_3[i])*6.0)
else if (var_3[i]=0.5) then
color[i]:=var_1+((var_2-var_1)*(twothird-var_3[i])*6.0)
else
color[i]:=var_1;
i:=i+1;
until(i=3);
red:=round(color[0]*255);
green:=round(Color[1]*255);
Blue:=round(Color[2]*255);
end;
result:=(((blue*256)+green)*256)+red
end;

Function GetRoadColor(color:integer):Boolean;
var z:integer;
begin
X:=x1-1;
Y:=Y1-1;
Z:=Z1-1;
repeat
X:=X+1;
Y:=y1;
if x=21 then
x:=230;
repeat
Y:=Y+1;
Z:=Z1;
repeat
Z:=Z+1;
color:=makergb(x,y,z);
until (z=z2) or (findcolor(a,b,Color,mmx1,mmy1,mmx2,mmy2));
until (y=y2) or (findcolor(a,b,Color,mmx1,mmy1,mmx2,mmy2));
until (x=x2) or (findcolor(a,b,Color,mmx1,mmy1,mmx2,mmy2));
if findcolorspiral(x,y,color,mmx1,mmy1,mmx2,mmy2) then
begin
mmouse(x,y,0,0);
writeLn(IntToStr(Color));
end
else
writeln('couldnt find');
end;
begin
time1:=Getsystemtime;
Setupsrl;
GetroadColor(color2)
time2:=Getsystemtime;
writeln(inttostr(time2-time1));
end.

Bramble

2007-01-29 14:31:56

i created a new, hsl to rgb converter that is actually accurate!!! lol
i had a repeat in it but boreas said it seemd to slow down the script

program New;
var color:integer;

function HSLScarness(hh,ss,ll:integer):integer;
var rgbs:array[0..2] of extended;vh,one,h,s,l,two:extended;i:integer;
onethird,twothird:extended;
begin
onethird:=0.33333333333333333333333333333333;
twothird:=0.66666666666666666666666666666667;
H:=hh/239.0;
s:=ss/240.0;
l:=ll/240.0;
if not(s>0.0) then
begin
rgbs[0]:=round(L*255.0);
rgbs[1]:=round(L*255.0);
rgbs[2]:=round(L*255.0);
end
else
begin
if (L<0.5) then
two:=L*(1.0+s)
else two:=(L+S)-(S*L);
one:=2.0*L-two;
I:=0
vh:=h+onethird;
if (vh<0.0) then
vh:=vh+1.0;
if (h>1.0) then
vh:=vh-1.0;
if ((6.0*vh)<1.0) then
rgbs[i]:=255.0*(one+(((two-one)*6.0)*vh))
else if ((2.0*vh)<1.0) then
rgbs[i]:=255.0*(two)
else if ((3.0*vh)<2.0) then
rgbs[i]:=255.0*(one+(((two-one)*(twothird-vh))*6.0))
else
rgbs[i]:=255.0*one;
i:=i+1;
vh:=h;
if (vh<0.0) then
vh:=vh+1.0;
if (h>1.0) then
vh:=vh-1.0;
if ((6.0*vh)<1.0) then
rgbs[i]:=255.0*(one+(((two-one)*6.0)*vh))
else if ((2.0*vh)<1.0) then
rgbs[i]:=255.0*(two)
else if ((3.0*vh)<2.0) then
rgbs[i]:=255.0*(one+(((two-one)*(twothird-vh))*6.0))
else
rgbs[i]:=255.0*one;
i:=i+1;
vh:=h-onethird;
if (vh<0.0) then
vh:=vh+1.0;
if (h>1.0) then
vh:=vh-1.0;
if ((6.0*vh)<1.0) then
rgbs[i]:=255.0*(one+(((two-one)*6.0)*vh))
else if ((2.0*vh)<1.0) then
rgbs[i]:=255.0*(two)
else if ((3.0*vh)<2.0) then
rgbs[i]:=255.0*(one+(((two-one)*(twothird-vh))*6.0))
else
rgbs[i]:=255.0*one;
end;
result:=(((round(rgbs[2])*256)+round(rgbs[1]))*256)+round(rgbs[0]);
end;

begin
Color:=HSLScarness(27,68,90);
writeln(inttostr(color));
end.

Boreas

2007-01-29 16:10:29

I played around with the differences between our versions a lot, and it turns out

the repeat makes it slower, prolly because of jumping from line to line
the array makes it slower, idk maybe loading arrays takes more time
the onethird twothird variables make it about 40ms slower per 10k conversions, maybe more variables=slower
the
Red:=255.0*red;
Green:=255.0*green;
Blue:=255.0*blue;
I had at the end makes it slower too, prolly because how you have the 255 on each line it means less lines to process, idk

Anyway this has the faster version of each option, a good 200ms per 10k faster than using the slower versions


program New;
var color:integer; var time,i:integer;

function HSLScarness(hh,ss,ll:integer):integer;
var Red,Green,Blue,vh,one,h,s,l,two:extended;
begin
H:=hh/239.0;
s:=ss/240.0;
l:=ll/240.0;
if not(s>0.0) then
begin
red:=round(L*255.0);
green:=round(L*255.0);
blue:=round(L*255.0);
end
else
begin
if (L<0.5) then
two:=L*(1.0+s)
else two:=(L+S)-(S*L);
one:=2.0*L-two;

vh:=h+(1.0/3.0);
if (vh<0.0) then
vh:=vh+1.0;
if (h>1.0) then
vh:=vh-1.0;
if ((6.0*vh)<1.0) then
red:=255.0*(one+(((two-one)*6.0)*vh))
else if ((2.0*vh)<1.0) then
red:=255.0*(two)
else if ((3.0*vh)<2.0) then
red:=255.0*(one+(((two-one)*((2.0/3.0)-vh))*6.0))
else
red:=255.0*one;

vh:=h;
if (vh<0.0) then
vh:=vh+1.0;
if (h>1.0) then
vh:=vh-1.0;
if ((6.0*vh)<1.0) then
green:=255.0*(one+(((two-one)*6.0)*vh))
else if ((2.0*vh)<1.0) then
green:=255.0*(two)
else if ((3.0*vh)<2.0) then
green:=255.0*(one+(((two-one)*((2.0/3.0)-vh))*6.0))
else
green:=255.0*one;

vh:=h-(1.0/3.0);
if (vh<0.0) then
vh:=vh+1.0;
if (h>1.0) then
vh:=vh-1.0;
if ((6.0*vh)<1.0) then
blue:=255.0*(one+(((two-one)*6.0)*vh))
else if ((2.0*vh)<1.0) then
blue:=255.0*(two)
else if ((3.0*vh)<2.0) then
blue:=255.0*(one+(((two-one)*((2.0/3.0)-vh))*6.0))
else
blue:=255.0*one;
end;
result:=(((round(blue)*256)+round(green))*256)+round(red);
end;
begin
time:=getsystemtime;

for i:=0 to 10000 do
Color:=HSLScarness(27,68,90);
writeln(inttostr(getsystemtime-time));
end.

Let me know if making it a plugin makes its even faster.

Also probably tonite I'll make the brute forcer start from the middle of the range and work outwards.