SRL Archive - Research & Development Lounge

Finding a good color from bitmaps


Boreas

2007-04-17 00:35:59

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):integer;
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' +
'F090771BA1402DEFF9116415CC8439D8D9BFAB0672CCFFCED3869' +
'FC490849A44A3DF6D8638F3DF6D863FF6DA42285D4952844C57A8' +
'E610829D057FC89306AD6E49325907A0EFF375E9023C0906CD2B4' +
'B0F29DA3E336F2FFEE33A1807A9141F05AB3F29DA3C9FFCA0B932' +
'06A6315646DBB171AF42B9F43BEC53FF3AC1492232B35630E59B1' +
'FED5FA7EC3FFF989A9A44479A5949022658A1122C510DCD1E433F' +
'CE3D36585E1DDDAB510452BF568F2BD5E041BB47369A11C512AFA' +
'9AFA2644678DEB9AEBCF741F7E266725248725A22F3660F4DA2AB' +
'4AE98CCEAB34D46CD54D10BE24F35A989969850317FD7C57B0B98' +
'BCB1F5B58801AF9A073EF33BAA4BF08A1A8BCF4CDB994B78D9C81' +
'A7C30CEDF8D9C150054BD9A86E2D02006BF9852B36AA975DF41AD' +
'FD67E6FC0CB95526D40B0DD4CB9B57BD9ADA978906A5CA5721830' +
'7772D7F8D682D902619572F0508684C9D0E0A7B24B593B7F733B9' +
'D4ABBCE8E44D21BEC3CFFA03F90DF8472F985C678D1A7BFC59D92' +
'FCE28A17DA2139EB25E558B98B353B54872FE8CE4929F7DBC0F3F' +
'33FC10FF416FC7CFD166E5BD2CB3BD716EFE2DEF856BF9999333A' +
'47931BF37A5EF67324BB69E3FAD2B8D3593EF4F45A0E949CC1B79' +
'BE229FAE8DC7F18F99C019DB09DB84207300169D74EA2B7229FF2' +
'AC21FBB2A33775AFEBDA9F3F5D40B33FCDDEB3FE2EF35442A4F32' +
'0379EFAD1C6D31B3D50680EF09ED3DB37DAE3F2B2FDA4E89BE1ED' +
'87E3997F227ACA6AF0DE6919FD53B5B3B019FAD78DA9FE7EF9D1D' +
'5C3629285BF6ACC5D83767C847FEAEC30ACE93B0EF7EB11ABCAB7' +
'B4BE729F2893C3987FF97FB94BBCF50037793CB5E7C706F5A4569' +
'A386EF203F9D5F4E5F9BFCC3E9A99FA1467239F3C813D644FF3D9' +
'07F7E15FE87FCAB33EFA04793B38DF1DC9DF3929CA78813A7FAAF' +
'AACDA0D79E6A7F58918DDC58A99891EE709EDA8CFFB843B9F60E9' +
'39EBAD436F9376AFB5567A8D15C3465FDBD8DD43E9F785777E999' +
'13C20EFE36B18FCCD278AAA425C0FBFBEFEBB365C5DFE6760A01D' +
'DC2FAF93DEA66E6EAEC0F8BFCFFC856FC59D5638F3DF6D84EFB07' +
'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(AnswerArray)-1,true,false);

//AnswerArray2:=RemoveDupsFromTPASingle(AnswerArray,true);
AnswerArray2:=AnswerArray;
RearrangeTPA(AnswerArray2,0,getarraylength(AnswerArray2)-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

2007-04-17 15:02:52

Looks very good, I'm gonna try this when I get home!

Boreas

2007-04-17 15:18:39

GetBitmapSize(bmps[iter].bmp,bmps[iter].w,bmps[iter].h); :D couldn't have done it without you!

Lorax

2007-04-17 18:17:13

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

Bebe

2007-04-17 19:41:51

Thanks :D

This is exactly what I needed. <3

Boreas

2007-07-02 22:44:59

You're welcome :)


From: Lorax
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):integer;
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' +
'F090771BA1402DEFF9116415CC8439D8D9BFAB0672CCFFCED3869' +
'FC490849A44A3DF6D8638F3DF6D863FF6DA42285D4952844C57A8' +
'E610829D057FC89306AD6E49325907A0EFF375E9023C0906CD2B4' +
'B0F29DA3E336F2FFEE33A1807A9141F05AB3F29DA3C9FFCA0B932' +
'06A6315646DBB171AF42B9F43BEC53FF3AC1492232B35630E59B1' +
'FED5FA7EC3FFF989A9A44479A5949022658A1122C510DCD1E433F' +
'CE3D36585E1DDDAB510452BF568F2BD5E041BB47369A11C512AFA' +
'9AFA2644678DEB9AEBCF741F7E266725248725A22F3660F4DA2AB' +
'4AE98CCEAB34D46CD54D10BE24F35A989969850317FD7C57B0B98' +
'BCB1F5B58801AF9A073EF33BAA4BF08A1A8BCF4CDB994B78D9C81' +
'A7C30CEDF8D9C150054BD9A86E2D02006BF9852B36AA975DF41AD' +
'FD67E6FC0CB95526D40B0DD4CB9B57BD9ADA978906A5CA5721830' +
'7772D7F8D682D902619572F0508684C9D0E0A7B24B593B7F733B9' +
'D4ABBCE8E44D21BEC3CFFA03F90DF8472F985C678D1A7BFC59D92' +
'FCE28A17DA2139EB25E558B98B353B54872FE8CE4929F7DBC0F3F' +
'33FC10FF416FC7CFD166E5BD2CB3BD716EFE2DEF856BF9999333A' +
'47931BF37A5EF67324BB69E3FAD2B8D3593EF4F45A0E949CC1B79' +
'BE229FAE8DC7F18F99C019DB09DB84207300169D74EA2B7229FF2' +
'AC21FBB2A33775AFEBDA9F3F5D40B33FCDDEB3FE2EF35442A4F32' +
'0379EFAD1C6D31B3D50680EF09ED3DB37DAE3F2B2FDA4E89BE1ED' +
'87E3997F227ACA6AF0DE6919FD53B5B3B019FAD78DA9FE7EF9D1D' +
'5C3629285BF6ACC5D83767C847FEAEC30ACE93B0EF7EB11ABCAB7' +
'B4BE729F2893C3987FF97FB94BBCF50037793CB5E7C706F5A4569' +
'A386EF203F9D5F4E5F9BFCC3E9A99FA1467239F3C813D644FF3D9' +
'07F7E15FE87FCAB33EFA04793B38DF1DC9DF3929CA78813A7FAAF' +
'AACDA0D79E6A7F58918DDC58A99891EE709EDA8CFFB843B9F60E9' +
'39EBAD436F9376AFB5567A8D15C3465FDBD8DD43E9F785777E999' +
'13C20EFE36B18FCCD278AAA425C0FBFBEFEBB365C5DFE6760A01D' +
'DC2FAF93DEA66E6EAEC0F8BFCFFC856FC59D5638F3DF6D84EFB07' +
'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(AnswerArray)-1,true,false);

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




Smartzkid

2007-07-02 22:57:45

Amazing!

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

Harry

2007-07-02 23:03:46

04-17-2007, 12:35 AM

Boreas, you bumped it.. sigh.. lol

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

Boreas

2007-07-02 23:13:35

From: Smartzkid
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?

2007-07-03 07:37:30

I like it.. :)

SKy Scripter

2007-07-03 14:10:32

Hmm ill bet it lags lolz…
looks nice this may be helpful one day ;)

Boreas

2007-07-03 19:20:58

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

2007-07-04 10:18:28

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

2007-07-04 15:10:17

Hmm send me the bmps you are using.

3Garrett3

2007-07-04 15:45:41

Check your PMs :)

Boreas

2007-07-04 21:35:10

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

2007-07-05 11:24:51

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

2007-07-05 20:17:57

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

2007-07-06 20:03:55

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.