Page 1 sur 1
[R] Capture ecran et mémoire perdue.
Posté : lun. 18 mai 2009 20:36
par raoullevert
Bonjour a tous,
Déjà un grand bravo au forum. Je découvre auto-it avec joie aux travers des scripts d'exemples et des astuces présentées. Je suis en train de faire un petit programme simple pour l'instant : un "loggeur" pour Entropia Universe. En gros je prends une capture d'écran toutes les secondes, a partir de la je cherche a analyser le Tchat du jeux pour extraire les données texte. C'est plus pour le fun qu'autre chose, car ce genre de logiciel existe apparement.
Bref. Quand je lance mon script, la mémoire augmente au fur et a mesure du temps. Il s'agit d'un simple problème de Release de donnée. Le problème est que quand j'essaye de faire un 'Release' sur l'image de capture, le script s'arrete.
► Afficher le texte
Code : Tout sélectionner
#include <GuiConstantsEx.au3>
#include <GDIPlus.au3>
#include <ScreenCapture.au3>
#include <Timers.au3>
Global const $Titre = "EU Logger";
Global Const $Ver = "0.01a";
Global Const $Largeur = 400;
Global Const $Hauteur = 400;
Global const $TitreEU = "Entropia Universe";
Global $EntropiaHandle = 0;
Global $EntropiaPosX = 0;
Global $EntropiaPosY = 0;
Global $EntropiaTailleX = 0;
Global $EntropiaTailleY = 0;
global $hGraphic;
$MainWindow = GUICreate($Titre & $Ver, $Largeur, $Hauteur);
$Console = GUICtrlCreateEdit( $Titre & "V. " & $Ver, 0, 190, 400, 200);
GUISetState()
_GDIPlus_Startup ()
Console( "Demarrage .....");
Console( "Recherche de la fenetre : ");
RechercheFenetreEntropia()
_Timer_SetTimer($MainWindow,100,"ImageCapture")
while 1
$nMSG = GUIGetMsg()
Switch $nMSG
Case $GUI_EVENT_CLOSE
Fin()
EndSwitch
WEnd
Func ImageCapture($a, $b, $c , $d)
$hGraphic = _GDIPlus_GraphicsCreateFromHWND ($Mainwindow)
$hBMP = _ScreenCapture_Capture ("", $EntropiaPosX, $EntropiaPosY, $EntropiaTailleX, $EntropiaTailleY)
$hBitmap = _GDIPlus_BitmapCreateFromHBITMAP ($hBmp)
_GDIPlus_GraphicsDrawImageRect($hGraphic, $hBitmap, 0, 0, 400, 200)
_GDIPlus_ImageDispose($hBitmap)
_GDIPlus_GraphicsDispose($hGraphic)
_WinAPI_DeleteObject ($hBMP)
EndFunc
Func RechercheFenetreEntropia()
$EntropiaSize = WinGetPos ($TitreEU)
if @error = 1 Then
Console ("Pas de fenetre trouvée")
Fin()
EndIf
Console ( "Fenetre Trouvée ..." )
$EntropiaPosX = $EntropiaSize[0]
$EntropiaPosY = $EntropiaSize[1]
$EntropiaTailleX = $EntropiaSize[2]
$EntropiaTailleY = $EntropiaSize[3]
Console (" Taille : " & $EntropiaTailleX & "/" & $EntropiaTailleY )
Console (" Pos : " & $EntropiaPosX & ":" & $EntropiaPosY)
EndFunc
Func Console($a_ecrire)
GUICtrlSetData($Console, @CRLF & $a_ecrire, 1);
EndFunc
Func Fin()
; Procedure de fin de programme
_GDIPlus_Shutdown()
Exit
EndFunc
Désolé pour les maladresses de code, c'est mon premier script.
Re: [..] Capture ecran et mémoire perdue.
Posté : lun. 18 mai 2009 21:03
par Tlem
Bonsoir. J'ai survolé extrêmement rapidement votre code et j'ai déjà remarqué deux grosses erreur dans votre code.
Toutes les lignes de commentaire doivent être précédées du symbole '
;' (Elle doivent impérativement apparaitre en vert dans Scite).
Ensuite et surement un des problèmes du 'débordement mémoire', c'est que vous utilisez des fonctions
_GDIPlus_xxxxx sans les fonctions :
-
_GDIPlus_Startup ()
- _GDIPlus_ShutDown ()
Rajoutez les, et sans doute les choses fonctionneront mieux.

Re: [..] Capture ecran et mémoire perdue.
Posté : mar. 19 mai 2009 14:04
par raoullevert
Merci pour la réponse rapide !
Pour les commentaires, je les ai rajouté a partir du forum, mais c'est toujours bon de le souligner.
Pour les fonction _GDIPlus_Startup et _GDIPlus_ShutDown, je ne les connaissaient simplement pas !
Je rajoute ça de suite.
EDIT :
En fait ca ne résouds pas le problème. J'ai ajoute les balises Startup et Shutdown autour de mes fonctions GDIPLus, pour la capture, et ca génère le même débordement. Il y a t il un moyen plus simple d'afficher une capture dans un Widget, sans passer par GDIPlus ?
Re: [..] Capture ecran et mémoire perdue.
Posté : mar. 19 mai 2009 17:01
par Tlem
Vous avez ré-édité votre code, ce qui est une bonne chose, mais sur les 20 secondes pendent lesquelles j'ai regardé le code modifié, je note que les commentaire ne sont toujours pas modifiés ainsi l'absence de la fonction
_GDIPlus_ShutDown.
Je ne sais pas si ça fonctionnera mieux, mais je vous conseille de placer la ligne :
au début de la fonction
ImageCapture() et de rajouter
_GDIPlus_ShutDown à la fin de celle-ci.
Re: [..] Capture ecran et mémoire perdue.
Posté : mar. 19 mai 2009 21:28
par raoullevert
En fait j'ai placé
en début de fonction, et _GDIPlus_ShutDown en fin.
Le résultat est assez surprenant :
Avant le processus qui 'enflait' étais le gestionnaire de fenetres, ce qui est logique : je créais un widget sans le detruire.
Maintenant, l'utilisation de la RAM augmente, mais sans qu'aucune utilisation 'RAM' d'aucun processus n'augmente.
En gros le total augmente sans qu'aucun processus ne 'gonfle' ....
► Afficher le texte
Code : Tout sélectionner
#include <GuiConstantsEx.au3>
#include <GDIPlus.au3>
#include <ScreenCapture.au3>
#include <Timers.au3>
Global const $Titre = "EU Logger";
Global Const $Ver = "0.01a";
Global Const $Largeur = 400;
Global Const $Hauteur = 400;
Global const $TitreEU = "Entropia Universe";
Global $EntropiaHandle = 0;
Global $EntropiaPosX = 0;
Global $EntropiaPosY = 0;
Global $EntropiaTailleX = 0;
Global $EntropiaTailleY = 0;
global $hGraphic;
$MainWindow = GUICreate($Titre & $Ver, $Largeur, $Hauteur);
$Console = GUICtrlCreateEdit( $Titre & "V. " & $Ver, 0, 190, 400, 200);
GUISetState()
_GDIPlus_Startup ()
Console( "Demarrage .....");
Console( "Recherche de la fenetre : ");
RechercheFenetreEntropia()
_Timer_SetTimer($MainWindow,100,"ImageCapture")
while 1
$nMSG = GUIGetMsg()
Switch $nMSG
Case $GUI_EVENT_CLOSE
Fin()
EndSwitch
WEnd
Func ImageCapture($a, $b, $c , $d)
_GDIPlus_Startup ()
$hGraphic = _GDIPlus_GraphicsCreateFromHWND ($Mainwindow)
$hBMP = _ScreenCapture_Capture ("", $EntropiaPosX, $EntropiaPosY, $EntropiaTailleX, $EntropiaTailleY)
$hBitmap = _GDIPlus_BitmapCreateFromHBITMAP ($hBMP)
_GDIPlus_GraphicsDrawImageRect($hGraphic, $hBitmap, 0, 0, 400, 200)
_GDIPlus_ImageDispose($hBitmap)
_GDIPlus_GraphicsDispose($hGraphic)
_GDIPlus_Shutdown()
EndFunc
Func RechercheFenetreEntropia()
$EntropiaSize = WinGetPos ($TitreEU)
if @error = 1 Then
Console ("Pas de fenetre trouvée")
Fin()
EndIf
Console ( "Fenetre Trouvée ..." )
$EntropiaPosX = $EntropiaSize[0]
$EntropiaPosY = $EntropiaSize[1]
$EntropiaTailleX = $EntropiaSize[2]
$EntropiaTailleY = $EntropiaSize[3]
Console (" Taille : " & $EntropiaTailleX & "/" & $EntropiaTailleY )
Console (" Pos : " & $EntropiaPosX & ":" & $EntropiaPosY)
EndFunc
Func Console($a_ecrire)
GUICtrlSetData($Console, @CRLF & $a_ecrire, 1);
EndFunc
Func Fin()
; Procedure de fin de programme
Exit
EndFunc
Le problème viendrait de $hBMP. Quand je fais un _GDIPlus_BitmapDispose($hBMP), le script plante. De plus, quand je ne fais pas la conversion Bitmap -> hBitmap, il n'y a pas de fuite mémoire...
Re: [..] Capture ecran et mémoire perdue.
Posté : mar. 19 mai 2009 21:55
par Tlem
Juste pour info :
La coloration syntaxique du code est réservée aux forums :
Re: [..] Capture ecran et mémoire perdue.
Posté : mar. 19 mai 2009 22:05
par raoullevert
désolé, je le ferais plus

Re: [R] Capture ecran et mémoire perdue.
Posté : mer. 20 mai 2009 01:24
par raoullevert
Au final j'ai résolu le problème :
_GDIPlus_Shutdown() a été mis dans la procédure fin().
_GDIPlus_Startup () à été mis au tout début du script.
L'erreur ne venait pas de la, mais de la "non-desalocation" de la variable $hBMP.
Pour dire a Windows de libérer la mémoire, il ne fallait pas faire un _GDIPlus_ImageDispose, mais un _WinAPI_DeleteObject ($hBMP).
Tout bêtement.
En tout cas merci du temps passé !