PDA

View Full Version : Out of Memory error even when bitmap is released?



mrpickle
03-22-2017, 01:03 PM
Heya,

I was using this function and got an out of memory error on this line after running it for awhile:
tmpBitmap := bitmapFromClient(x1,y1,x2,y2);

I thought I released it? But did I miss something?

Thanks in advance :)


Function GetBitmapText(x1,y1,x2,y2):String;
var tmpBitmap:Integer;
var tmpMufasa:TMufasaBitmap;
var tmpString:String;
begin

tmpBitmap := bitmapFromClient(x1,y1,x2,y2);
tmpMufasa := GetMufasaBitmap(tmpBitmap);
tmpMufasa := Resize(tmpMufasa);

ThresholdAdaptiveBitmap(tmpBitmap, 0, 255, false, TM_Mean, 18);

tmpString := Tess_GetText(tmpMufasa);
Freebitmap(tmpBitmap);
Result := tmpString;

end;

Citrus
03-22-2017, 01:09 PM
You probably need to free the TMufasaBitmap as well. Try something like this

tmpMufasa := getMufasaBitmap(bitmapFromClient(x1, y1, x2, y2));
...
tmpMufasa.free();

mrpickle
03-22-2017, 01:25 PM
Worked great! Though this is not in the documentation.


You probably need to free the TMufasaBitmap as well. Try something like this

tmpMufasa := getMufasaBitmap(bitmapFromClient(x1, y1, x2, y2));
...
tmpMufasa.free();

mrpickle
03-22-2017, 04:27 PM
wait. It didn't work great.

Freebitmap(tmpBitmap);
tmpMufasa.free();
Causes access violation.


tmpMufasa.free();
Freebitmap(tmpBitmap);
tmpBitmap already doesn't exist.



tmpMufasa.free();
Still causes memory leaks

tls
03-22-2017, 05:38 PM
Does Resize create a copy of the TMufasaBitmap? If it does you are losing a reference when you overwrite the tmpMufasa variable.

Citrus
03-23-2017, 02:56 AM
Yeah, I'm not getting any leaks when I test it myself. It must be your resize function. Did you try TMufasaBitmap.ResizeEx() (https://github.com/MerlijnWajer/Simba/blob/73deaec2f0060333cccddba59678b975395ffd3f/Units/MMLCore/bitmaps.pas#L2101) ?

slacky
03-23-2017, 04:49 AM
function GetBitmapText(x1,y1,x2,y2):String;
var tmpBitmap:Integer;
var tmpMufasa:TMufasaBitmap;
var tmpString:String;
begin

tmpBitmap := bitmapFromClient(x1,y1,x2,y2); //creates 1 bitmap
tmpMufasa := GetMufasaBitmap(tmpBitmap); //get the actual underlying bitmap (it's the same as tmpBitmap atm)
tmpMufasa := Resize(tmpMufasa); //Idk of any such method, but as you assign some result.. then you are likely copying..

ThresholdAdaptiveBitmap(tmpBitmap, 0, 255, false, TM_Mean, 18); //runs threshold on the OLD bitmap.. not the new resized one

tmpString := Tess_GetText(tmpMufasa); //Gets text from the new resize one, which is not thresholded...
Freebitmap(tmpBitmap); //free the first bitmap (the thresholded one) -> not the resized one
Result := tmpString;

end;


This is pretty much how it should be:

function RecognizeTextAt(x1,y1,x2,y2: Int32; Scale:Double; ThresholdMod:Int32):String;
var
clientBmp:TMufasaBitmap;
begin
clientBmp := GetMufasaBitmap(BitmapFromClient(x1,y1,x2,y2)); //get client image and get the actual mufasa bitmap directly
clientBmp.ResizeEx(RM_Bilinear, Round((x2-x1+1)*Scale), Round((y2-y1+1)*Scale)); //resize that bitmap without copying
clientBmp.ThresholdAdaptive(0, 255, False, TM_Mean, ThresholdMod); //threshold it, again without copying

//assuming it takes a mufasabitmap (I don't use SRL-6 at all)
Result := Tess_GetText(clientBmp); //recognize the text
//Result := Tess_GetText(clientBmp.GetIndex()); //if not
clientBmp.Free(); //free
end;

var text:String;
begin
text := RecognizeTextAt(someBounds..., 3.5, 18);
end.

mrpickle
03-23-2017, 11:52 PM
Does Resize create a copy of the TMufasaBitmap? If it does you are losing a reference when you overwrite the tmpMufasa variable.
It did! Fixed it


Yeah, I'm not getting any leaks when I test it myself. It must be your resize function. Did you try TMufasaBitmap.ResizeEx() (https://github.com/MerlijnWajer/Simba/blob/73deaec2f0060333cccddba59678b975395ffd3f/Units/MMLCore/bitmaps.pas#L2101) ?
I didn't think to open that... that would've been a useful function to use!


...
This is pretty much how it should be:

function RecognizeTextAt(x1,y1,x2,y2: Int32; Scale:Double; ThresholdMod:Int32):String;
var
clientBmp:TMufasaBitmap;
begin
clientBmp := GetMufasaBitmap(BitmapFromClient(x1,y1,x2,y2)); //get client image and get the actual mufasa bitmap directly
clientBmp.ResizeEx(RM_Bilinear, Round((x2-x1+1)*Scale), Round((y2-y1+1)*Scale)); //resize that bitmap without copying
clientBmp.ThresholdAdaptive(0, 255, False, TM_Mean, ThresholdMod); //threshold it, again without copying

//assuming it takes a mufasabitmap (I don't use SRL-6 at all)
Result := Tess_GetText(clientBmp); //recognize the text
//Result := Tess_GetText(clientBmp.GetIndex()); //if not
clientBmp.Free(); //free
end;

var text:String;
begin
text := RecognizeTextAt(someBounds..., 3.5, 18);
end.

That looks more proper in everyway xD.

mrpickle
03-26-2017, 09:39 PM
@Slacky

I think your function should go into SRL, what do you think?