Log in

View Full Version : FindDeformedBitmap Not Working for me..



Brandon
06-30-2012, 02:29 AM
So I've been trying to develop some new item finding system for some time now. I thought well since I have enough knowledge now, I can succeed but now I'm failing AGAIN!

It keeps saying nothing found but if I debug the bitmap they look the EXACT SAME! I don't know what's wrong or why.. I went through all of the code line by line with a ton of debugging.

If anyone has any idea why it doesn't work let me know plox. Don't tell me it's because it's GIF's.. I looked into Simba's code and it can load it just fine as it only iterates through RGB and ignores Alpha values (Sets to Black).


program ImageProc;
{$DEFINE SMART}
{$I SRL/SRL.Simba}
{$I SRL/SRL/Misc/PaintSmart.Simba}



type ItemClass = Record
ItemName: String;
ItemID: Integer;
end;

type ItemArray = Array of ItemClass;

var
Runes: TIntegerArray;
AllItems: ItemArray;

Procedure GetItem(ItemID: Integer; LocationToSaveTo: String; ItemName: String; Extension: String);
var
Image, Path: string;
FP: Integer;
begin
Image:= GetPage('http://services.runescape.com/m=itemdb_rs/3773_obj_sprite.gif?id=' + ToStr(ItemID));
Path:= Trim(LocationToSaveTo + '.' + ToStr(Extension));
FP:= CreateFile(Path);
WriteFileString(FP, Image);
CloseFile(FP);
end;

Function GetItemByID(ItemID: Integer; ItemName: String): Integer;
var
Path: String;
Item: Integer;
begin
Path:= ScriptPath + 'GeItems\' + ItemName;

If (Not FileExists(Path + '.GIF')) then
begin
if (Not DirectoryExists(ScriptPath + 'GeItems')) then
CreateDirectory(ScriptPath + 'GeItems');
GetItem(ItemId, Path, ItemName, 'GIF'); //Downloads the Image in any format!
end;

Item:= LoadBitmap(Path + '.GIF');
Result:= CopyBitmap(Item);
FreeBitmap(Item);
end;

Procedure GetAllItems;
var
I: Integer;
begin
SetLength(Runes, 6);
SetLength(AllItems, 6);
AllItems[0].ItemID := 7936;
AllItems[1].ItemID := 554;
AllItems[2].ItemID := 561;
AllItems[3].ItemID := 556;
AllItems[4].ItemID := 555;
AllItems[5].ItemID := 557;

AllItems[0].ItemName := 'PureEssence';
AllItems[1].ItemName := 'FireRune';
AllItems[2].ItemName := 'NatureRune';
AllItems[3].ItemName := 'AirRune';
AllItems[4].ItemName := 'WaterRune';
AllItems[5].ItemName := 'EarthRune';

For I:= 0 To 5 Do
Runes[I] := GetItemByID(AllItems[I].ItemID, AllItems[I].ItemName);

AddOnTerminate('FreeAllItems');
end;

Procedure FreeAllItems;
var
I, L: Integer;
begin
L:= High(Runes);
For I:= 0 To L Do
FreeBitmap(Runes[I]);
end;


Function FindAllItems(ItemsToFind: TIntegerArray; TPA: TPointArray): TBooleanArray;
var
I, L, X, Y: Integer;
Accuracy: Extended;
begin
SetLength(Result, Length(ItemsToFind));
SetLength(TPA, Length(ItemsToFind));
L:= High(ItemsToFind);
For I:= 0 To L Do
begin
Result[I]:= FindDeformedBitmapToleranceIn(ItemsToFind[I], X, Y, MIX1, MIY1, MIX2, MIY2, 10, 0, False, Accuracy);
//SMART_DRAWBITMAP(True, ItemsToFind[I], Point(250, 250));
TPA[I].X := X;
TPA[I].Y := Y;
end;
end;

var
I: Integer;
TPA: TPointArray;
ItemsFound: TBooleanArray;

Begin
Smart_Server:= 72;
Smart_Members:= True;
Smart_Signed:= True;
Smart_SuperDetail:= False;

SetupSRL;
GetAllItems;

ItemsFound := FindAllItems(Runes, TPA);

Writeln(ItemsFound);

For I:= 0 To High(TPA) Do
If (ItemsFound[I]) Then
begin
MMouse(TPA[I].X, TPA[I].Y, 0, 0);
Wait(1500);
end;
end.

Runaway
06-30-2012, 03:16 AM
Oh my lanta... /fail

Is FindAllItems returning true in any instances?

Brandon
06-30-2012, 03:22 AM
Oh my lanta... /fail

Is FindAllItems returning true in any instances?

Not a single return value was true. All values it returns are false :S

Runaway
06-30-2012, 03:45 AM
Could it be the fact that FindDeformedBitmapToleranceIn() is looking to use a TMufasaBitmap? Try loading the .GIF with LoadFromRawImage() (http://wizzup.org/simbafpcdoc/bitmaps/tmufasabitmap.loadfromrawimage.html) or LoadFromTBitmap() (http://wizzup.org/simbafpcdoc/bitmaps/tmufasabitmap.loadfromtbitmap.html) and see if that changes anything.

EDIT: A few sources say that it uses a normal Bitmap (int) but this is from finder.pas:


function FindDeformedBitmapToleranceIn(bitmap: TMufasaBitmap; out x, y: Integer; xs, ys, xe, ye: Integer; tolerance: Integer; Range: Integer; AllowPartialAccuracy: Boolean; out accuracy: Extended): Boolean;

Brandon
06-30-2012, 05:15 AM
Could it be the fact that FindDeformedBitmapToleranceIn() is looking to use a TMufasaBitmap? Try loading the .GIF with LoadFromRawImage() (http://wizzup.org/simbafpcdoc/bitmaps/tmufasabitmap.loadfromrawimage.html) or LoadFromTBitmap() (http://wizzup.org/simbafpcdoc/bitmaps/tmufasabitmap.loadfromtbitmap.html) and see if that changes anything.

EDIT: A few sources say that it uses a normal Bitmap (int) but this is from finder.pas:


function FindDeformedBitmapToleranceIn(bitmap: TMufasaBitmap; out x, y: Integer; xs, ys, xe, ye: Integer; tolerance: Integer; Range: Integer; AllowPartialAccuracy: Boolean; out accuracy: Extended): Boolean;


I got it working. FindDeformedBitmapToleranceIn counts the numbers too! So if you're looking for an entire bitmap, it will never find it!! You have to clip the bitmap so that only part of it exists.

Example for nature runes it has a number on it so it shows like iunno 1034 natures (Stacked Item). Without a tolerance of over 300, it'll never find it no matter how good the bitmap is. So I have to crop the numbers part and since Jagex deforms stuff by cutting off the left side, I also had to do the same.

My final code is:


program ImageProc;
{$DEFINE SMART}
{$I SRL/SRL.Simba}
{$I SRL/SRL/Misc/Debug.Simba}


type ItemClass = Record
ItemName: String;
ItemID: Integer;
end;

type ItemArray = Array of ItemClass;

var
Runes: TIntegerArray;
AllItems: ItemArray;


Procedure ClipImage(Image: Integer);
var
Top, Side: TPointArray;
TopColors, SideColors: TIntegerArray;
begin
Top:= TPAFromBox(IntToBox(0, 0, 31, 11));
Side:= TPAFromBox(IntToBox(0, 0, 8, 31));
SetLength(TopColors, Length(Top));
SetLength(SideColors, Length(Side));
FastReplaceColor(Image, 2171169, 0);
FastReplaceColor(Image, 526344, 0);
FastSetPixels(Image, Top, TopColors);
FastSetPixels(Image, Side, SideColors);
end;

Procedure ClipImagePath(Path: String);
var
Image: Integer;
begin
Image:= LoadBitmap(Path);
ClipImage(Image);
DeleteFile(Path);
Path:= ReplaceWrap(Path, 'GIF', 'bmp', [rfIgnoreCase]);
SaveBitmap(Image, Path);
FreeBitmap(Image);
end;

Procedure ConvertToBitmap(Path: String);
var
Image: Integer;
begin
Image:= LoadBitmap(Path);
DeleteFile(Path);
Path:= ReplaceWrap(Path, 'GIF', 'bmp', [rfIgnoreCase]);
SaveBitmap(Image, Path);
FreeBitmap(Image);
end;

Procedure GetItem(ItemID: Integer; LocationToSaveTo: String; ItemName: String; Extension: String);
var
Image, Path: string;
FP: Integer;
begin
Image:= GetPage('http://services.runescape.com/m=itemdb_rs/3773_obj_sprite.gif?id=' + ToStr(ItemID));
Path:= Trim(LocationToSaveTo + '.' + ToStr(Extension));
FP:= CreateFile(Path);
WriteFileString(FP, Image);
CloseFile(FP);
ConvertToBitmap(Path);
end;

Function GetItemByID(ItemID: Integer; ItemName: String; Clip: Boolean): Integer;
var
Path: String;
Item: Integer;
begin
Path:= ScriptPath + 'GeItems\' + ItemName;

If (Not FileExists(Path + '.GIF')) then
begin
if (Not DirectoryExists(ScriptPath + 'GeItems')) then
CreateDirectory(ScriptPath + 'GeItems');
GetItem(ItemId, Path, ItemName, 'GIF'); //Downloads the Image in any format!
end;

Item:= LoadBitmap(Path + '.bmp');
If Clip then ClipImage(Item);
Result:= CopyBitmap(Item);
FreeBitmap(Item);
end;

Procedure GetAllItems(Clip: Boolean);
var
I: Integer;
begin
SetLength(Runes, 6);
SetLength(AllItems, 6);
AllItems[0].ItemID := 7936;
AllItems[1].ItemID := 554;
AllItems[2].ItemID := 561;
AllItems[3].ItemID := 556;
AllItems[4].ItemID := 555;
AllItems[5].ItemID := 557;

AllItems[0].ItemName := 'PureEssence';
AllItems[1].ItemName := 'FireRune';
AllItems[2].ItemName := 'NatureRune';
AllItems[3].ItemName := 'AirRune';
AllItems[4].ItemName := 'WaterRune';
AllItems[5].ItemName := 'EarthRune';

For I:= 0 To 5 Do
Runes[I] := GetItemByID(AllItems[I].ItemID, AllItems[I].ItemName, Clip);

AddOnTerminate('FreeAllItems');
end;

Procedure FreeAllItems;
var
I, L: Integer;
begin
L:= High(Runes);
For I:= 0 To L Do
FreeBitmap(Runes[I]);
end;


Function FindAllItems(ItemsToFind: TIntegerArray; var TPA: TPointArray, Tolerance: Integer): TBooleanArray;
var
I, L: Integer;
Accuracy: Extended;
begin
SetLength(Result, Length(ItemsToFind));
SetLength(TPA, Length(ItemsToFind));
L:= High(ItemsToFind);
For I:= 0 To L Do
Result[I]:= FindDeformedBitmapToleranceIn(ItemsToFind[I], TPA[I].X, TPA[I].Y, MIX1, MIY1, MIX2, MIY2, Tolerance, 0, False, Accuracy);
end;

var
I, L: Integer;
TPA: TPointArray;
ItemsFound: TBooleanArray;

Begin
Smart_Server:= 72;
Smart_Members:= True;
Smart_Signed:= True;
Smart_SuperDetail:= False;

SetupSRL;
GetAllItems(True);

ItemsFound := FindAllItems(Runes, TPA, 35);

Writeln(ItemsFound);

L:= High(ItemsFound);
For I:= 0 To L Do
begin
If (ItemsFound[I]) Then
MMouse(TPA[I].X, TPA[I].Y, 0, 0);
end;
end.



Finds items directly from GE given an ID.

Runaway
06-30-2012, 04:13 PM
Awesome :) So from what I gather there is a difference between a Bitmap and a TMufasaBitmap; and in fact what I was reading said that you need to convert a Bitmap up to a TM in order to use it with TM functions. So why exactly are you able to use a normal Bitmap with a TM function?

Also, great idea! Using their own database against them... genius :p