CGDipSnapShot - GDI replacement for PixelGetColor

Post your working scripts, libraries and tools
+MeleaB+
Posts: 11
Joined: 26 Oct 2017, 18:46

Re: CGDipSnapShot - GDI replacement for PixelGetColor

30 Oct 2017, 11:44

It appears as if CGDipSnapShot is gradually increasing the amount of memory it uses, the longer the program is running. The main loop of my program calls the following functions. It's memory usage increases from an initial ~7MB until it eventually lags so badly that it has to be restarted.

The program [initially] runs so much quicker than with the original pixelgetcolor code, but unfortunately I won't be able to use it if I can't get this issue fixed. I would be very grateful if you could offer any advice.

(Also, during the checkseatstatus function, I had to give the two uses of the CGDipSnapShot different names (originally they both used the variable "snap", now they have been changed to "snap1" and "snap2") even though they are used one after the other, because originally the second use was returning a result of zero each time the red colour component was read. NB: Parts of the code have been revised since I made those name changes- in case that may be relevant.)

Thank you!

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus

User avatar
evilC
Posts: 3593
Joined: 27 Feb 2014, 12:30

Re: CGDipSnapShot - GDI replacement for PixelGetColor

30 Oct 2017, 15:47

Hmm, it is entirely possible that I messed up and when the snap variable goes out of scope, the memory is not freed up. (Probably due to a self-reference).

In order to work around this, you could do try to re-use the same snapshot object, just re-take the snapshot
At the moment, you create a new snapshot each time the function is called.
You could maybe do something like

Code: [Select all] [Download] GeSHi © Codebox Plus

snap := new CGdipSnapshot(x,y,w,h)
AveCol(x,y,w,h, snap)
{
blue := 0
green := 0
red := 0
snap.TakeSnapShot()


This would also make your code quicker, as you do not need to new up the snapshot each time.

Btw, your sample code uses snap.TakeSnapShot when it should use snap.TakeSnapShot()

I will try and get around to looking into whether snapshot objects get properly garbage collected, thanks for the heads up.
+MeleaB+
Posts: 11
Joined: 26 Oct 2017, 18:46

Re: CGDipSnapShot - GDI replacement for PixelGetColor

30 Oct 2017, 18:29

Thanks very much for the prompt response! I'll make the change you suggested and see how it goes.

(I hadn't noticed the missing "()" as it still worked despite that. However I now just tested using an infinite loop and undefined, and then off-screen, variabless, and whereas it continued to work fine with the correct syntax, with the parenthesis omitted it caused the program to crash.)
+MeleaB+
Posts: 11
Joined: 26 Oct 2017, 18:46

Re: CGDipSnapShot - GDI replacement for PixelGetColor

30 Oct 2017, 21:03

OK, so I've spent a little time trying to understand everything better but I'm still having a problem: Forgive me if I've missed something, but I don't understand how I can re-use the same snapshot object. Each time the AveCol function is called, different co-ordinates and dimensions of the area to snapshot are used, so wouldn't I need to create a new snapshot each time?

As I was unable to successfully make the change you mentioned, I reverted to the code as it stood, other than now using the correct syntax of snap.TakeSnapShot(), and even added in a further check to verify coordinates are valid, but I'm still seeing a steady increase in memory usage until the program slows to such a pace that it needs to be restarted.

Help! :)

EDIT: I was looking through the other AHK program I wrote last summer, which also included CGdipSnapShot, as I recalled an issue I had back then. I found this code and comment:

Code: [Select all] [Download] GeSHi © Codebox Plus

;Take a peek else next snap won't update
DummyPeek := snap.PixelSnap[5, 5].r

IIRC, often the initial attempt to read a colour component resulted in a value of zero (similar to the comment I made in my last post) and so I initiated a "dummy" read to get around this. I don't know if this is in any way related to my current issue, but I thought I'd mention it in case it may be.
User avatar
evilC
Posts: 3593
Joined: 27 Feb 2014, 12:30

Re: CGDipSnapShot - GDI replacement for PixelGetColor

31 Oct 2017, 07:22

Are there a fixed number of different regions that you want to examine using AveCol?

What I meant is, that if you want to examine x5 y5 w100 h100 multiple times, then it is wasteful creating a new instance each time. Every time you want to take a snapshot of the same region, you should use the same instance and re-snapshot.

I had a quick look at the code re: the bloating issue, and all my classes seem to free their memory.
However, I did find some issue where GDI+ did not like me creating a new token each time you newed up a CGDipSnapshot class.

So I altered the code so that all CGDipSnapshot classes share the same GDI+ token.
This should also increase performance.

Regarding the "snap not updating" issue, do you mean if you re-snapshot or something? Could you maybe clarify a little?
+MeleaB+
Posts: 11
Joined: 26 Oct 2017, 18:46

Re: CGDipSnapShot - GDI replacement for PixelGetColor

01 Nov 2017, 12:25

No, there aren't really any fixed regions, but it's good to know that I don't have to create a new snap if I do happen to have a fixed region that I need to examine at some future point.

Thanks very much for making the change to the code. I'll try it out and report back.

--------------------------------------------

I can only be vague with the issue where the snap was returning a zero value each time. It was from over a year ago, and I just recall that the first pixelsnap read returned a zero result each time, and that the next read produced the actually result, so I had to add a "dummy peek" to get around the problem. I don't remember the precise conditions though. I just wondered if it was similar to the problem I mentioned a few posts back: "Also, during the checkseatstatus function, I had to give the two uses of the CGDipSnapShot different names (originally they both used the variable "snap", now they have been changed to "snap1" and "snap2") even though they are used one after the other, because originally the second use was returning a result of zero each time the red colour component was read..." I'll let you know if I experience it again.
+MeleaB+
Posts: 11
Joined: 26 Oct 2017, 18:46

Re: CGDipSnapShot - GDI replacement for PixelGetColor

05 Nov 2017, 06:36

Hi.

Just reporting back that since you made the alterations, everything seems to be working perfectly! Thanks very much for quickly fixing it.
+MeleaB+
Posts: 11
Joined: 26 Oct 2017, 18:46

Re: CGDipSnapShot - GDI replacement for PixelGetColor

18 Nov 2017, 23:24

Hi again, evilC

Is it possible for SnapShot to work with an image file, rather than just from the screen?

For example, if one had previously saved an image with SnapShot and wished to re-examine it, or- in my case- with an image captured from a window that is hidden.

Thanks.
+MeleaB+
Posts: 11
Joined: 26 Oct 2017, 18:46

Re: CGDipSnapShot - GDI replacement for PixelGetColor

23 Nov 2017, 02:35

I think there are still memory leakage issues caused from Snapshot.

When I tried using code such as that shown below, it appears that Snapshot was causing a conflict as I was having to create a new token each time I wanted to create and save a bitmap. So, I couldn't use the code as shown, and instead had to use pToken := gdip_startup() and Gdip_Shutdown(pToken) EACH TIME I wanted to perform the task. That wasn't a long-term solution of course and so I proceeded to replace all of my routines that used SnapShot with those from the GDI+ library and it now works as required. I'm learning as I go with AHK so there's plenty I still don't fully grasp. If I'm missing something then I'd be grateful if you could explain how else I could have resolved the memory leak.

Code: [Select all] [Download] GeSHi © Codebox Plus

pToken := gdip_startup()
.
.
file=%a_scriptdir%\PMData\thumbnail%thumbnail_tableno%.png
thumbnail_id := tableid[thumbnail_tableno]
pBitmap := Gdip_BitmapFromHWND(thumbnail_id)
Gdip_SaveBitmapToFile(pBitmap,file)
Gdip_DisposeImage(pBitmap)
.
.
Gdip_Shutdown(pToken)

Return to “Scripts and Functions”

Who is online

Users browsing this forum: No registered users and 13 guests