PDA

View Full Version : Finding a good color from bitmaps



Boreas
04-17-2007, 04:35 AM
Moved from Dev section for your enjoyment :p


program New;
type BmpCom=record
bmp,inc,w,h,NumberOfColors:integer;
ColorArray:array of tpoint;
SkipArray:array of integer;
end;

var tmpres,tx,ty:integer;
var inccounter,iter,iter2,NumberOfCombos,NumberOfBmps, x,y,parray,tmpcolor,tmpal:integer;
Bmps:array of BmpCom;
Combos:array of array of integer;
AnswerArray,AnswerArray2:array of tpoint;

procedure DeclareBmps;
begin
NumberOfBmps:=3;
setarraylength(bmps,NumberofBmps);
bmps[0].bmp:=loadbitmap(apppath+'/bmpcom1.bmp');
bmps[1].bmp:=loadbitmap(apppath+'/bmpcom2.bmp');
bmps[2].bmp:=loadbitmap(apppath+'/bmpcom3.bmp');
end;






{************************************************* ******************************
function InIntArray(TheInt:integer;TheArray:array of integer):boolean;
By: Boreas
Description: Returns true if TheInt is a member of TheArray
************************************************** ****************************}
function InIntArray(TheInt:integer;TheArray:array of integer):boolean;
var i:integer;
begin
if getarraylength(thearray)<>0 then
repeat
if TheArray[i]=TheInt then
result:=true;
i:=i+1;
until ((i=getarraylength(TheArray)) or (result));
end;
function CountColorbmp(thebmp,color,x1,y1,x2,y2:integer):in teger;
var x,y,tmpres:integer;
begin
tmpres:=0;
for x:=x1 to x2 do
begin
for y:=y2 to y2 do
begin

if FastGetPixel(thebmp,x,y)=color then tmpres:=tmpres+1;
writeln(inttostr(x)+' '+inttostr(y)+' '+inttostr(FastGetPixel(thebmp,x,y))+' '+inttostr(tmpres));
end;
end;
result:=tmpres;
end;




function LowestTolSimColors(TheArray:array of integer):integer;
var parray:integer;
begin
for parray:=0 to getarraylength(TheArray)-2 do
begin
repeat
result:=result+1;
until SimilarColors(TheArray[parray],TheArray[parray+1],result);
end;
end;

function RearrangeTPA(thearray:array of tpoint; startpt, endpt:integer; dox,up:boolean):array of tpoint;
var
temp, pArray : integer;
done : boolean;
ttp:tpoint;
tmpTPA : array of tpoint;
begin
setarraylength(tmpTPA,getarraylength(thearray));
tmpTPA:=thearray;
setarraylength(result,endpt+1-startpt);

if not(up) then
begin

if dox then
begin
repeat
done := true;
for pArray := 0 to (getarraylength(thearray) - 2) do
begin
if(tmpTPA[pArray].x < tmpTPA[pArray + 1].x) then
begin
ttp := tmpTPA[pArray];
tmpTPA[pArray] := tmpTPA[pArray + 1];
tmpTPA[pArray + 1] := ttp;
done := false;
end;
end;
until(done);
end;

if not(dox) then
begin
repeat
done := true;
for pArray := 0 to (getarraylength(thearray) - 2) do
begin
if(tmpTPA[pArray].y < tmpTPA[pArray + 1].y) then
begin
ttp := thearray[pArray];
tmpTPA[pArray] := tmpTPA[pArray + 1];
tmpTPA[pArray + 1] := ttp;

done := false;
end;
end;
until(done);
end;

end;

if up then
begin

if dox then
begin
repeat
done := true;
for pArray := 0 to (getarraylength(thearray) - 2) do
begin
if(tmpTPA[pArray].x > tmpTPA[pArray + 1].x) then
begin
ttp := tmpTPA[pArray];
tmpTPA[pArray] := tmpTPA[pArray + 1];
tmpTPA[pArray + 1] := ttp;

done := false;
end;
end;
until(done);
end;

if not(dox) then
begin
repeat
done := true;
for pArray := 0 to (getarraylength(thearray) - 2) do
begin
if(tmpTPA[pArray].y > tmpTPA[pArray + 1].y) then
begin
ttp := tmpTPA[pArray];
tmpTPA[pArray] := tmpTPA[pArray + 1];
tmpTPA[pArray + 1] := ttp;


done := false;
end;
end;
until(done);
end;

end;

pArray:=startpt-1;
for temp:=0 to getarraylength(result)-1 do
begin
pArray:=pArray+1;
result[temp]:=tmpTPA[pArray];
end;

end;

function RemoveDupsFromTPASingle(var StartTPA: array of Tpoint; DoX:boolean): array of Tpoint;
var
ArrayLength, pFindDups, pBubbleUp: integer;
tpSwap:tpoint;
begin
ArrayLength:=getarraylength(StartTPA);
// result:=RearrangeTPA(StartTPA,0,ArrayLength-1,true,true);
if DoX then
begin
result:=RearrangeTPA(StartTPA,0,ArrayLength-1,true,true);
//for pFindDups := 0 to (ArrayLength - 2) do
// begin
pFindDups:=0; //
repeat //
if(result[pFindDups].x = result[pFindDups + 1].x) then
begin
for pBubbleUp := pFindDups to (ArrayLength-2) do
begin
tpSwap := result[pBubbleUp];
result[pBubbleUp] := result[pBubbleUp+1];
result[pBubbleUp+1] := tpSwap;
end;
ArrayLength := ArrayLength-1;
setarraylength(result, ArrayLength);
pFindDups:=pFindDups-1;
end;
pFindDups:=pFindDups+1; //
until pFindDups>(ArrayLength - 2);//
//end;
end;
if not DoX then
begin
result:=RearrangeTPA(StartTPA,0,ArrayLength-1,false,true);
for pFindDups := 0 to (ArrayLength - 2) do
begin
if(result[pFindDups].y = result[pFindDups + 1].y) then
begin
for pBubbleUp := pFindDups to (ArrayLength-2) do
begin
tpSwap := result[pBubbleUp];
result[pBubbleUp] := result[pBubbleUp+1];
result[pBubbleUp+1] := tpSwap;
end;
ArrayLength := ArrayLength-1;
setarraylength(result, ArrayLength);
end;
end;
end;
end;


begin {
bmp1:= BitmapFromString(32, 57, 'z78DAED99DB72EB2A0C865' +
'F090771BA1402DEFF9116415CC8439D8D9BFAB0672CCFFCED 3869' +
'FC490849A44A3DF6D8638F3DF6D863FF6DA42285D4952844C 57A8' +
'E610829D057FC89306AD6E49325907A0EFF375E9023C0906C D2B4' +
'B0F29DA3E336F2FFEE33A1807A9141F05AB3F29DA3C9FFCA0 B932' +
'06A6315646DBB171AF42B9F43BEC53FF3AC1492232B35630E 59B1' +
'FED5FA7EC3FFF989A9A44479A5949022658A1122C510DCD1E 433F' +
'CE3D36585E1DDDAB510452BF568F2BD5E041BB47369A11C51 2AFA' +
'9AFA2644678DEB9AEBCF741F7E266725248725A22F3660F4D A2AB' +
'4AE98CCEAB34D46CD54D10BE24F35A989969850317FD7C57B 0B98' +
'BCB1F5B58801AF9A073EF33BAA4BF08A1A8BCF4CDB994B78D 9C81' +
'A7C30CEDF8D9C150054BD9A86E2D02006BF9852B36AA975DF 41AD' +
'FD67E6FC0CB95526D40B0DD4CB9B57BD9ADA978906A5CA572 1830' +
'7772D7F8D682D902619572F0508684C9D0E0A7B24B593B7F7 33B9' +
'D4ABBCE8E44D21BEC3CFFA03F90DF8472F985C678D1A7BFC5 9D92' +
'FCE28A17DA2139EB25E558B98B353B54872FE8CE4929F7DBC 0F3F' +
'33FC10FF416FC7CFD166E5BD2CB3BD716EFE2DEF856BF9999 333A' +
'47931BF37A5EF67324BB69E3FAD2B8D3593EF4F45A0E949CC 1B79' +
'BE229FAE8DC7F18F99C019DB09DB84207300169D74EA2B722 9FF2' +
'AC21FBB2A33775AFEBDA9F3F5D40B33FCDDEB3FE2EF35442A 4F32' +
'0379EFAD1C6D31B3D50680EF09ED3DB37DAE3F2B2FDA4E89B E1ED' +
'87E3997F227ACA6AF0DE6919FD53B5B3B019FAD78DA9FE7EF 9D1D' +
'5C3629285BF6ACC5D83767C847FEAEC30ACE93B0EF7EB11AB CAB7' +
'B4BE729F2893C3987FF97FB94BBCF50037793CB5E7C706F5A 4569' +
'A386EF203F9D5F4E5F9BFCC3E9A99FA1467239F3C813D644F F3D9' +
'07F7E15FE87FCAB33EFA04793B38DF1DC9DF3929CA78813A7 FAAF' +
'AACDA0D79E6A7F58918DDC58A99891EE709EDA8CFFB843B9F 60E9' +
'39EBAD436F9376AFB5567A8D15C3465FDBD8DD43E9F785777 E999' +
'13C20EFE36B18FCCD278AAA425C0FBFBEFEBB365C5DFE6760 A01D' +
'DC2FAF93DEA66E6EAEC0F8BFCFFC856FC59D5638F3DF6D84E FB07' +
'C14271C3'); }

DeclareBmps;
for iter:=0 to NumberofBmps-1 do
begin
GetBitmapSize(bmps[iter].bmp,bmps[iter].w,bmps[iter].h);


for x:=0 to bmps[iter].w-1 do
begin
for y:=0 to bmps[iter].h-1 do
begin
tmpcolor:=fastgetpixel(bmps[iter].bmp,x,y);


if not( InIntArray(tmpcolor,bmps[iter].SkipArray)) and (tmpcolor<>0) then
begin
tmpAL:= GetArrayLength(bmps[iter].SkipArray);
SetArrayLength(bmps[iter].SkipArray,tmpAL+1);
SetArrayLength(bmps[iter].ColorArray,tmpAL+1);
bmps[iter].SkipArray[tmpAL]:=tmpcolor;
bmps[iter].ColorArray[tmpAL].x:=tmpcolor;
tmpres:=0;
for tx:=0 to bmps[iter].w-1 do
begin
for ty:=0 to bmps[iter].h-1 do
begin
if FastGetPixel(bmps[iter].bmp,tx,ty)=tmpcolor then tmpres:=tmpres+1;
end;
end;

bmps[iter].ColorArray[tmpAL].y:= tmpres;
//bmps[iter].ColorArray[tmpAL].y:=CountColorbmp(bmps[iter].bmp,tmpcolor,0,0,31,56);
//bmps[iter].ColorArray[tmpAL].y:= CountColor(tmpcolor,0,0,31,56);
end;
end;
end;
//writeln(inttostr(iter)+' bitmap');
//for parray:=0 to getarraylength(bmps[iter].colorArray)-1 do
//begin
//writeln(inttostr(bmps[iter].colorarray[parray].x)+' '+inttostr(bmps[iter].colorarray[parray].y));
//end;

RearrangeTPA(bmps[iter].colorarray,0,getarraylength(bmps[iter].colorarray)-1,false,false);
// for parray:=0 to getarraylength(bmps[iter].colorArray)-1 do
// begin
// writeln(inttostr(bmps[iter].colorarray[parray].x)+' '+inttostr(bmps[iter].colorarray[parray].y));
// end;
parray:=0;
repeat
if bmps[iter].colorarray[parray].y < (round(bmps[iter].w*bmps[iter].h/100)) then
break;
parray:=parray+1;
until parray=getarraylength(bmps[iter].colorarray);
setarraylength(bmps[iter].colorarray,parray);
// for parray:=0 to getarraylength(bmps[iter].colorArray)-1 do
// begin
/// writeln(inttostr(bmps[iter].colorarray[parray].x)+' '+inttostr(bmps[iter].colorarray[parray].y));
// end;
bmps[iter].NumberOfColors:=getarraylength(bmps[iter].colorarray);

freebitmap(bmps[iter].bmp);

end;


bmps[0].inc:=1;
inccounter:=1;
for iter:=1 to numberofbmps-1 do
begin
inccounter:=inccounter*bmps[iter-1].numberofcolors;
bmps[iter].inc:=inccounter;
end;

NumberOfCombos:=1;
for iter:=0 to numberofbmps-1 do
begin
NumberOfCombos:=NumberOfCombos*bmps[iter].Numberofcolors;
end;
//writeln(inttostr(NumberofCombos));
etarraylength(combos,NumberofCOmbos);
for iter:=0 to NumberofCOmbos-1 do
begin
setarraylength(combos[iter],numberofbmps);
for iter2:=0 to numberofbmps-1 do
begin
// writeln(inttostr(iter)+' '+inttostr(iter2)+inttostr(((iter/bmps[iter2].inc) mod bmps[iter2].numberofcolors)));
Combos[iter][iter2]:=bmps[iter2].colorarray[((iter/bmps[iter2].inc) mod bmps[iter2].numberofcolors)].x;

end;
end;
//writeln(inttostr(NumberofCOmbos))
//for iter:=0 to NumberofCOmbos-1 do
//writeln(inttostr(iter)+' '+inttostr(combos[iter][0])+' '+inttostr(combos[iter][1])+' '+inttostr(combos[iter][2]));
setarraylength(AnswerArray,NumberOfCombos);
for iter:=0 to NumberofCOmbos-1 do
begin
AnswerArray[iter].x:=Combos[iter][0];
AnswerArray[iter].y:=LowestTolSimColors(Combos[iter]);
end;
//RearrangeTPA(AnswerArray,0,getarraylength(AnswerAr ray)-1,true,false);

//AnswerArray2:=RemoveDupsFromTPASingle(AnswerArray, true);
AnswerArray2:=AnswerArray;
RearrangeTPA(AnswerArray2,0,getarraylength(AnswerA rray2)-1,false,false);
for iter:=0 to getarraylength(AnswerArray2)-1 do
begin
writeln(inttostr(AnswerArray2[iter].x)+' '+inttostr(AnswerArray2[iter].y));
end;
end.


For divi. Take some screenies of a MS 3d object, such as NPCs (I did it on fairy bankers), and in paint/etc color the background 0. Crop them as small as possible. Take them from different worlds, different positions etc. Save them in SCAR 3.06 folder and put their names in DeclareBmps, and set how many there are. Hit run and get a sandwich. It will output 2 lists of numbers, with the ones on the left being colors, and the ones on the right being tolerances to go with the colors. Using those combos, FindColorTolerance should return true for all the bitmaps. The last one will have the lowest tol. So add a little bit to that, and you should be able to find that color on that NPC in any world. :D

http://img297.imageshack.us/img297/6817/bmpcom1sh2.png

Freddy1990
04-17-2007, 07:02 PM
Looks very good, I'm gonna try this when I get home!

Boreas
04-17-2007, 07:18 PM
GetBitmapSize(bmps[iter].bmp,bmps[iter].w,bmps[iter].h); :D couldn't have done it without you!

Lorax
04-17-2007, 10:17 PM
I will perhaps test it once I will get the use of it ;)

Bebe
04-17-2007, 11:41 PM
Thanks :D

This is exactly what I needed. <3

Boreas
07-03-2007, 02:44 AM
You're welcome :)



I will perhaps test it once I will get the use of it ;)

It's for saving time on trying to find a color and tol that works for MS objects/NPCs.


Edit: Update!

I tried on doors, with 5 pictures, and the combos were over 2 million, it took a long time to get the combos, and even longer (more than I could wait, so I stopped it) to bubble sort it. So this version won't even bother adding combos that have over 100 tol to it (well it will add, but then it will take away, but the point is the bubble sort will be faster).

I just tried it with 3 duke horacio pictures, and it works great.

program New;
type BmpCom=record
bmp,inc,w,h,NumberOfColors:integer;
ColorArray:array of tpoint;
SkipArray:array of integer;
end;

var tmpres,tx,ty:integer;
var inccounter,iter,iter2,NumberOfCombos,NumberOfBmps, x,y,parray,tmpcolor,tmpal:integer;
Bmps:array of BmpCom;
Combos:array of array of integer;
AnswerArray,AnswerArray2:array of tpoint;

procedure DeclareBmps;
begin
NumberOfBmps:=4;
setarraylength(bmps,NumberofBmps);
bmps[0].bmp:=loadbitmap(apppath+'/duke4.bmp');
bmps[1].bmp:=loadbitmap(apppath+'/duke5.bmp');
bmps[2].bmp:=loadbitmap(apppath+'/duke6.bmp');
bmps[3].bmp:=loadbitmap(apppath+'/duke7.bmp');

end;






{************************************************* ******************************
function InIntArray(TheInt:integer;TheArray:array of integer):boolean;
By: Boreas
Description: Returns true if TheInt is a member of TheArray
************************************************** ****************************}
function InIntArray(TheInt:integer;TheArray:array of integer):boolean;
var i:integer;
begin
if getarraylength(thearray)<>0 then
repeat
if TheArray[i]=TheInt then
result:=true;
i:=i+1;
until ((i=getarraylength(TheArray)) or (result));
end;
function CountColorbmp(thebmp,color,x1,y1,x2,y2:integer):in teger;
var x,y,tmpres:integer;
begin
tmpres:=0;
for x:=x1 to x2 do
begin
for y:=y2 to y2 do
begin

if FastGetPixel(thebmp,x,y)=color then tmpres:=tmpres+1;
writeln(inttostr(x)+' '+inttostr(y)+' '+inttostr(FastGetPixel(thebmp,x,y))+' '+inttostr(tmpres));
end;
end;
result:=tmpres;
end;




function LowestTolSimColors(TheArray:array of integer):integer;
var parray:integer;
begin
for parray:=0 to getarraylength(TheArray)-2 do
begin
repeat
result:=result+1;
until SimilarColors(TheArray[parray],TheArray[parray+1],result);
end;
end;

function RearrangeTPA(thearray:array of tpoint; startpt, endpt:integer; dox,up:boolean):array of tpoint;
var
temp, pArray : integer;
done : boolean;
ttp:tpoint;
tmpTPA : array of tpoint;
begin
setarraylength(tmpTPA,getarraylength(thearray));
tmpTPA:=thearray;
setarraylength(result,endpt+1-startpt);

if not(up) then
begin

if dox then
begin
repeat
done := true;
for pArray := 0 to (getarraylength(thearray) - 2) do
begin
if(tmpTPA[pArray].x < tmpTPA[pArray + 1].x) then
begin
ttp := tmpTPA[pArray];
tmpTPA[pArray] := tmpTPA[pArray + 1];
tmpTPA[pArray + 1] := ttp;
done := false;
end;
end;
until(done);
end;

if not(dox) then
begin
repeat
done := true;
for pArray := 0 to (getarraylength(thearray) - 2) do
begin
if(tmpTPA[pArray].y < tmpTPA[pArray + 1].y) then
begin
ttp := thearray[pArray];
tmpTPA[pArray] := tmpTPA[pArray + 1];
tmpTPA[pArray + 1] := ttp;

done := false;
end;
end;
until(done);
end;

end;

if up then
begin

if dox then
begin
repeat
done := true;
for pArray := 0 to (getarraylength(thearray) - 2) do
begin
if(tmpTPA[pArray].x > tmpTPA[pArray + 1].x) then
begin
ttp := tmpTPA[pArray];
tmpTPA[pArray] := tmpTPA[pArray + 1];
tmpTPA[pArray + 1] := ttp;

done := false;
end;
end;
until(done);
end;

if not(dox) then
begin
repeat
done := true;
for pArray := 0 to (getarraylength(thearray) - 2) do
begin
if(tmpTPA[pArray].y > tmpTPA[pArray + 1].y) then
begin
ttp := tmpTPA[pArray];
tmpTPA[pArray] := tmpTPA[pArray + 1];
tmpTPA[pArray + 1] := ttp;


done := false;
end;
end;
until(done);
end;

end;

pArray:=startpt-1;
for temp:=0 to getarraylength(result)-1 do
begin
pArray:=pArray+1;
result[temp]:=tmpTPA[pArray];
end;

end;

function RemoveDupsFromTPASingle(var StartTPA: array of Tpoint; DoX:boolean): array of Tpoint;
var
ArrayLength, pFindDups, pBubbleUp: integer;
tpSwap:tpoint;
begin
ArrayLength:=getarraylength(StartTPA);
// result:=RearrangeTPA(StartTPA,0,ArrayLength-1,true,true);
if DoX then
begin
result:=RearrangeTPA(StartTPA,0,ArrayLength-1,true,true);
//for pFindDups := 0 to (ArrayLength - 2) do
// begin
pFindDups:=0; //
repeat //
if(result[pFindDups].x = result[pFindDups + 1].x) then
begin
for pBubbleUp := pFindDups to (ArrayLength-2) do
begin
tpSwap := result[pBubbleUp];
result[pBubbleUp] := result[pBubbleUp+1];
result[pBubbleUp+1] := tpSwap;
end;
ArrayLength := ArrayLength-1;
setarraylength(result, ArrayLength);
pFindDups:=pFindDups-1;
end;
pFindDups:=pFindDups+1; //
until pFindDups>(ArrayLength - 2);//
//end;
end;
if not DoX then
begin
result:=RearrangeTPA(StartTPA,0,ArrayLength-1,false,true);
for pFindDups := 0 to (ArrayLength - 2) do
begin
if(result[pFindDups].y = result[pFindDups + 1].y) then
begin
for pBubbleUp := pFindDups to (ArrayLength-2) do
begin
tpSwap := result[pBubbleUp];
result[pBubbleUp] := result[pBubbleUp+1];
result[pBubbleUp+1] := tpSwap;
end;
ArrayLength := ArrayLength-1;
setarraylength(result, ArrayLength);
end;
end;
end;
end;


begin {
bmp1:= BitmapFromString(32, 57, 'z78DAED99DB72EB2A0C865' +
'F090771BA1402DEFF9116415CC8439D8D9BFAB0672CCFFCED 3869' +
'FC490849A44A3DF6D8638F3DF6D863FF6DA42285D4952844C 57A8' +
'E610829D057FC89306AD6E49325907A0EFF375E9023C0906C D2B4' +
'B0F29DA3E336F2FFEE33A1807A9141F05AB3F29DA3C9FFCA0 B932' +
'06A6315646DBB171AF42B9F43BEC53FF3AC1492232B35630E 59B1' +
'FED5FA7EC3FFF989A9A44479A5949022658A1122C510DCD1E 433F' +
'CE3D36585E1DDDAB510452BF568F2BD5E041BB47369A11C51 2AFA' +
'9AFA2644678DEB9AEBCF741F7E266725248725A22F3660F4D A2AB' +
'4AE98CCEAB34D46CD54D10BE24F35A989969850317FD7C57B 0B98' +
'BCB1F5B58801AF9A073EF33BAA4BF08A1A8BCF4CDB994B78D 9C81' +
'A7C30CEDF8D9C150054BD9A86E2D02006BF9852B36AA975DF 41AD' +
'FD67E6FC0CB95526D40B0DD4CB9B57BD9ADA978906A5CA572 1830' +
'7772D7F8D682D902619572F0508684C9D0E0A7B24B593B7F7 33B9' +
'D4ABBCE8E44D21BEC3CFFA03F90DF8472F985C678D1A7BFC5 9D92' +
'FCE28A17DA2139EB25E558B98B353B54872FE8CE4929F7DBC 0F3F' +
'33FC10FF416FC7CFD166E5BD2CB3BD716EFE2DEF856BF9999 333A' +
'47931BF37A5EF67324BB69E3FAD2B8D3593EF4F45A0E949CC 1B79' +
'BE229FAE8DC7F18F99C019DB09DB84207300169D74EA2B722 9FF2' +
'AC21FBB2A33775AFEBDA9F3F5D40B33FCDDEB3FE2EF35442A 4F32' +
'0379EFAD1C6D31B3D50680EF09ED3DB37DAE3F2B2FDA4E89B E1ED' +
'87E3997F227ACA6AF0DE6919FD53B5B3B019FAD78DA9FE7EF 9D1D' +
'5C3629285BF6ACC5D83767C847FEAEC30ACE93B0EF7EB11AB CAB7' +
'B4BE729F2893C3987FF97FB94BBCF50037793CB5E7C706F5A 4569' +
'A386EF203F9D5F4E5F9BFCC3E9A99FA1467239F3C813D644F F3D9' +
'07F7E15FE87FCAB33EFA04793B38DF1DC9DF3929CA78813A7 FAAF' +
'AACDA0D79E6A7F58918DDC58A99891EE709EDA8CFFB843B9F 60E9' +
'39EBAD436F9376AFB5567A8D15C3465FDBD8DD43E9F785777 E999' +
'13C20EFE36B18FCCD278AAA425C0FBFBEFEBB365C5DFE6760 A01D' +
'DC2FAF93DEA66E6EAEC0F8BFCFFC856FC59D5638F3DF6D84E FB07' +
'C14271C3'); }

DeclareBmps;
for iter:=0 to NumberofBmps-1 do
begin
GetBitmapSize(bmps[iter].bmp,bmps[iter].w,bmps[iter].h);


for x:=0 to bmps[iter].w-1 do
begin
for y:=0 to bmps[iter].h-1 do
begin
tmpcolor:=fastgetpixel(bmps[iter].bmp,x,y);


if not( InIntArray(tmpcolor,bmps[iter].SkipArray)) and (tmpcolor<>0) then
begin
tmpAL:= GetArrayLength(bmps[iter].SkipArray);
SetArrayLength(bmps[iter].SkipArray,tmpAL+1);
SetArrayLength(bmps[iter].ColorArray,tmpAL+1);
bmps[iter].SkipArray[tmpAL]:=tmpcolor;
bmps[iter].ColorArray[tmpAL].x:=tmpcolor;
tmpres:=0;
for tx:=0 to bmps[iter].w-1 do
begin
for ty:=0 to bmps[iter].h-1 do
begin
if FastGetPixel(bmps[iter].bmp,tx,ty)=tmpcolor then tmpres:=tmpres+1;
end;
end;

bmps[iter].ColorArray[tmpAL].y:= tmpres;
//bmps[iter].ColorArray[tmpAL].y:=CountColorbmp(bmps[iter].bmp,tmpcolor,0,0,31,56);
//bmps[iter].ColorArray[tmpAL].y:= CountColor(tmpcolor,0,0,31,56);
end;
end;
end;
//writeln(inttostr(iter)+' bitmap');
//for parray:=0 to getarraylength(bmps[iter].colorArray)-1 do
//begin
//writeln(inttostr(bmps[iter].colorarray[parray].x)+' '+inttostr(bmps[iter].colorarray[parray].y));
//end;

RearrangeTPA(bmps[iter].colorarray,0,getarraylength(bmps[iter].colorarray)-1,false,false);
// for parray:=0 to getarraylength(bmps[iter].colorArray)-1 do
// begin
// writeln(inttostr(bmps[iter].colorarray[parray].x)+' '+inttostr(bmps[iter].colorarray[parray].y));
// end;
parray:=0;
repeat
if bmps[iter].colorarray[parray].y < (round(bmps[iter].w*bmps[iter].h/100)) then
break;
parray:=parray+1;
until parray=getarraylength(bmps[iter].colorarray);
setarraylength(bmps[iter].colorarray,parray);
// for parray:=0 to getarraylength(bmps[iter].colorArray)-1 do
// begin
/// writeln(inttostr(bmps[iter].colorarray[parray].x)+' '+inttostr(bmps[iter].colorarray[parray].y));
// end;
bmps[iter].NumberOfColors:=getarraylength(bmps[iter].colorarray);

freebitmap(bmps[iter].bmp);

end;


bmps[0].inc:=1;
inccounter:=1;
for iter:=1 to numberofbmps-1 do
begin
inccounter:=inccounter*bmps[iter-1].numberofcolors;
bmps[iter].inc:=inccounter;
end;

NumberOfCombos:=1;
for iter:=0 to numberofbmps-1 do
begin
writeln('bmp '+inttostr(iter)+' NUM COLS '+inttostr(bmps[iter].Numberofcolors));
NumberOfCombos:=NumberOfCombos*bmps[iter].Numberofcolors;
//writeln(
end;
writeln('numofcombos '+inttostr(NumberofCombos));
setarraylength(combos,NumberofCOmbos);
for iter:=0 to NumberofCOmbos-1 do
begin

// if ( iter mod 10000) = 0 then
// begin
// cleardebug;
// writeln(inttostr(iter)); end;
setarraylength(combos[iter],numberofbmps);
for iter2:=0 to numberofbmps-1 do
begin
// writeln(inttostr(iter)+' '+inttostr(iter2)+inttostr(((iter/bmps[iter2].inc) mod bmps[iter2].numberofcolors)));
Combos[iter][iter2]:=bmps[iter2].colorarray[((iter/bmps[iter2].inc) mod bmps[iter2].numberofcolors)].x;

end;
end;
//writeln(inttostr(NumberofCOmbos))
//for iter:=0 to NumberofCOmbos-1 do
//writeln(inttostr(iter)+' '+inttostr(combos[iter][0])+' '+inttostr(combos[iter][1])+' '+inttostr(combos[iter][2]));
setarraylength(AnswerArray,NumberOfCombos);
//for iter:=0 to NumberofCOmbos-1 do
//begin
iter:=0;
iter2:=0;
setarraylength(AnswerArray2,1);
AnswerArray2[0].x:=getarraylength(Combos);
repeat
// if ( iter mod 10000) = 0 then
// begin
// cleardebug;
// writeln(inttostr(iter)); end;

AnswerArray[iter].x:=Combos[iter2][0];
AnswerArray[iter].y:=LowestTolSimColors(Combos[iter2]);
if AnswerArray[iter].y > 100 then
begin
iter:=iter-1;
numberofcombos:=numberofcombos-1;
setarraylength(answerarray, numberofcombos);
end;
iter:=iter+1;
iter2:=iter2+1;
until ((iter>=(NumberOfCombos-2)) or (iter2 >= AnswerArray2[0].x-2)) ;
numberofcombos:=numberofcombos-2;
setarraylength(answerarray, numberofcombos);
//end;
//RearrangeTPA(AnswerArray,0,getarraylength(AnswerAr ray)-1,true,false);

//AnswerArray2:=RemoveDupsFromTPASingle(AnswerArray, true);
//AnswerArray2:=AnswerArray;
RearrangeTPA(AnswerArray,0,getarraylength(AnswerAr ray)-1,false,false);
for iter:=0 to getarraylength(AnswerArray)-1 do
begin
writeln(inttostr(AnswerArray[iter].x)+' '+inttostr(AnswerArray[iter].y));
end;
end.

Smartzkid
07-03-2007, 02:57 AM
Amazing!

Do you have to cut the npc out from it's background?

Harry
07-03-2007, 03:03 AM
04-17-2007, 12:35 AM

Boreas, you bumped it.. sigh.. lol

This is amazing though, you make nifty little procedures! :D

Boreas
07-03-2007, 03:13 AM
Amazing!

Do you have to cut the npc out from it's background?

Make anything you want ignored (such as background, or part of the npc that is too similar to other stuff) 0, which is black in paint, and it will be ignored. Also the smaller the better, so if you cut out a part of the npc, you won't need to color the background.


BTW, if anyone wants to use this to make something that takes some bitmaps of what you are looking for, plus bitmaps of things not to click (such as torches on the wall of lumby courtyard when trying to find mage instructor), so that it finds a color that works with these but not those, go right ahead :p

Wizzup?
07-03-2007, 11:37 AM
I like it.. :)

SKy Scripter
07-03-2007, 06:10 PM
Hmm ill bet it lags lolz...
looks nice this may be helpful one day ;)

Boreas
07-03-2007, 11:20 PM
Yea it does. That's why I said hit run and get and sandwich, and smaller is better :p On the bright side, a simple FindObj using the returned color/tol gets the fairy bankers first try hehe

3Garrett3
07-04-2007, 02:18 PM
Jeez, it doesnt take that long, like one minute on my crappy old computer :p. Ps, im not getting a list of colors..
bmp 0 NUM COLS 21
bmp 1 NUM COLS 21
bmp 2 NUM COLS 17
bmp 3 NUM COLS 7
that doesnt have colors on it. I did get
numofcombos 52479
6786230 82
below that though, 82, that cant be the right tolerance, thats really high?

EDIT: BTW, how do I figure out what color 6786230 is?

Boreas
07-04-2007, 07:10 PM
Hmm send me the bmps you are using.

3Garrett3
07-04-2007, 07:45 PM
Check your PMs :)

Boreas
07-05-2007, 01:35 AM
I got these on second version pretty quickly, first version is still running it may be better.

6786230 92
2905211 92
2641009 92
2773368 92
2971007 92

Just from looking at the bitmaps, it might work better if you pick a body part (torso, unless head has something unique) and take screenies of just that body part, but from different angles and on different worlds.

As I said, V1 may work better, I'll let you know when it finishes.
Edit: V1 took over 12 hours and still not done, so nvm on that lol. So yea like I said, try using the same body part from different angles and worlds.

3Garrett3
07-05-2007, 03:24 PM
ok, i will use the torso. second version it is :)



Successfully compiled
bmp 0 NUM COLS 18
bmp 1 NUM COLS 19
bmp 2 NUM COLS 18
bmp 3 NUM COLS 29
numofcombos 178524
6058378 93
5992327 90
5860741 87
6058378 87
6058378 84
5794691 84
5992327 84
5992327 81
5663105 80
5860741 80
5794691 78
5860741 77
5531262 76
5794691 75
5465467 75
4280419 75
3038087 75
5202294 75
4938865 75
5136243 75
2575216 75
4872814 75
4741228 75
4609385 75
2443373 75
2707059 75
5663105 74
2443373 74
5663105 71
5531262 70
2575216 70
5465467 69
4280419 69
3038087 69
5202294 69
4938865 69
5136243 69
2575216 69
4872814 69
4741228 69
4609385 69
2443373 69
2707059 69
2443373 69
6058378 68
2443373 68
5531262 67
5465467 66
4280419 66
3038087 66
5202294 66
4938865 66
5136243 66
2575216 66
4872814 66
4741228 66
4609385 66
2443373 66
2707059 66
5992327 66
2707059 66
2443373 65
2575216 65
2575216 64
5860741 62
6058378 62
2443373 61
2575216 61
5794691 60
2707059 60
5992327 60
2707059 60
2443373 59
4280419 58
2575216 57
2707059 57
5663105 57
4280419 57
5860741 56
2575216 55
2443373 55
6058378 55
6058378 54
5794691 54
2707059 53
5531262 53
5992327 53
5465467 52
4280419 52
3038087 52
5202294 52
4938865 52
5136243 52
2575216 52
4872814 52
4741228 52
4609385 52
2443373 52
2707059 52
5992327 52
2443373 52
3038087 52
2707059 51
2575216 51
5663105 51
4280419 50
4280419 50
5860741 50
5860741 49
2575216 49
4609385 49
6058378 48
5794691 48
3038087 48
5531262 48
5794691 48
4280419 47
5992327 47
2707059 47
5465467 47
4280419 47
3038087 47
5202294 47
4938865 47
5136243 47
2575216 47
4872814 47
4741228 47
4609385 47
2443373 47
2707059 47
4609385 47
5663105 46
3038087 45
5860741 45
4609385 45
5663105 45
4280419 45
2707059 45
4741228 45
5794691 44
2443373 44
3038087 43
3038087 43
4741228 43
5531262 43
5465467 43
5531262 43
4741228 43
4280419 42
5663105 42
4872814 42
3038087 42
5202294 42
4938865 42
5136243 42
2575216 42
4872814 42
4741228 42
4609385 42
2443373 42
2707059 42
3038087 42
4872814 42
5465467 42
4280419 42
3038087 42
5202294 42
4938865 42
5136243 42
2575216 42
4872814 42
4741228 42
4609385 42
2443373 42
2707059 42
5465467 41
5136243 41
4609385 41
5531262 40
5202294 40
4938865 40
3038087 40
3038087 40
4280419 39
3038087 39
2575216 39
2707059 39
4872814 39
4609385 38
4938865 38
4741228 36
4938865 36
4280419 35
5136243 34
4609385 33
4741228 33
4872814 33
4280419 32
6058378 31
5202294 31
5136243 31
4609385 30
4872814 30
4938865 29
4741228 28
6058378 28
5992327 28
5202294 28
4938865 26
4609385 26
4872814 25
4741228 25
5136243 25
5465467 25
6058378 24
5992327 24
5860741 24
4872814 22
4609385 22
5531262 22
4938865 21
6058378 21
5136243 21
5202294 21
5860741 21
4741228 21
5794691 21
5663105 21
5794691 21
5860741 21
6058378 21
5992327 21
5992327 20
5465467 20
4938865 18
5202294 18
5794691 18
4872814 18
5663105 18
4741228 18
5136243 17
5992327 17
5860741 17
5531262 17
6058378 16
5663105 16
5794691 16
5860741 16
6058378 16
5992327 16
5860741 14
5794691 14
5136243 14
5465467 14
5663105 14
4938865 14
4872814 14
5202294 13
6058378 13
5531262 13
5992327 12
5465467 12
5202294 12
4938865 12
5136243 12
5794691 11
5531262 11
5663105 10
5202294 10
5465467 10
5663105 10
5794691 10
5860741 10
5992327 10
5531262 10
5136243 10
5860741 9
5465467 9
5202294 9
5663105 7
5531262 7
5465467 6
5531262 6
5663105 6
5794691 6
5465467 5
5531262 4
Successfully executed


I use 5531262 with a tol of 4 then?

A G E N T
07-06-2007, 12:17 AM
This is pretty cool, seems quite useful... It is basically made to take the guesswork out of FindMSColorTol/FindObj, right?


EDIT: I got a sandwich and it was still going! Liar!!!1one!1factorial!

Boreas
07-07-2007, 12:03 AM
3garrett3- Yup. In fact anyone of those bottom few should do it. Maybe add a lil tol.

A G E N T 83- Yup. Of course it's still good to test and play around and have a back up method.