Librairie Effect

Vous avez développé un logiciel en PureBasic et vous souhaitez le faire connaitre ?
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message par Flype »

je ne suis pas sûr mais je crois qu'il y a des fuites mémoire...
j'ai un petit soft qui montre ma ram dispo et en faisant tourner
les sources ci dessus je me suis apercu que ma ram descendait
a raison d' 1 Mo par 10 secondes...

voilà de quoi tester aussitot - est ce normal ?

Code : Tout sélectionner


ImageNormale = CreateImage(#PB_Any, 80, 100) 
StartDrawing(ImageOutput()) 
  Box(0, 0, 80, 100, $6F6F6F) 
  Box(5, 5, 35, 45, $FF) 
  Box(40, 5, 35, 45, $FF00) 
  Box(5, 50, 35, 45, $FF0000) 
  Box(40, 50, 35, 45, $FFFFFF) 
StopDrawing() 

; Création de la fenêtre et de la GadgetList 
If OpenWindow(0, 0, 0, 350, 400, #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget, "Effect - Rotation d'image") = 0 Or CreateGadgetList(WindowID()) = 0 
  End 
EndIf 

Angle = 30 
Mode = 0 
CouleurFondFenetre = GetSysColor_(#COLOR_3DFACE) - $101010 ; Couleur de fond des fenêtres de Windows mais légèrement foncé (le - $101010) 
ImageRotation = RotateImageEx3(UseImage(ImageNormale), Angle, CouleurFondFenetre, Mode) 

TextGadget(#PB_Any, 10, 10, 100, 15, "Image normale") 
ImageGadget(#PB_Any, 10, 25, 0, 0, UseImage(ImageNormale)) 

RotationTexte = TextGadget(#PB_Any, 10, 150, 220, 18, "Rotation de 30°",#pb_text_border) 
Rotation = ImageGadget(#PB_Any, 10, 215, 0, 0, UseImage(ImageRotation)) 

TextGadget(#PB_Any, 180, 200, 100, 15, "Mode :") 
OptionGadget(0, 180, 215, 170, 15, "normal") 
OptionGadget(1, 180, 230, 170, 15, "sans redimensionnement") 
OptionGadget(2, 180, 245, 170, 15, "avec redimensionnement fixe") 
SetGadgetState(0, 1) 

SetTimer_(WindowID(), 0, 25, 0) 

Global RamInfo.MEMORYSTATUS

Repeat 
  Event = WaitWindowEvent() 
  
  If Event = #WM_TIMER 
    Angle + 1 
    If Angle = 360 
      Angle = 0 
    EndIf 
    FreeImage(ImageRotation) 
    ImageRotation = RotateImageEx3(UseImage(ImageNormale), Angle, CouleurFondFenetre, Mode) 
    SetGadgetState(Rotation, UseImage(ImageRotation)) 
    GlobalMemoryStatus_(@RamInfo)
    SetGadgetText(RotationTexte, "Rotation de " + StrF(Angle, 1) + "° - "+Str(RamInfo\dwAvailPhys)+" octets.")
    
  ElseIf Event = #PB_EventGadget 
    Select EventGadgetID() 
      Case 0 
        Mode = 0 
      Case 1 
        Mode = 1 
      Case 2 
        Mode = 2 
    EndSelect 
  EndIf 
  
Until Event = #PB_EventCloseWindow 

KillTimer_(WindowID(), 0) 

End
Image
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message par Flype »

faut il liberer hObject = GetObject_(ImageID, SizeOf(BITMAP), @bm.BITMAP)

par DeleteObject_(hObject) ?
Image
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Message par djes »

Dès lors que l'on fait appel à des fonctions systèmes (non natives à pure), il faut s'occuper de tout. Donc à priori, je dirais oui.
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

Flype a écrit :je ne suis pas sûr mais je crois qu'il y a des fuites mémoire...
j'ai un petit soft qui montre ma ram dispo et en faisant tourner
les sources ci dessus je me suis apercu que ma ram descendait
a raison d' 1 Mo par 10 secondes...

Salut Flype,

je suis intérressé par le soft que tu utilises pour la ram.
Tu peux nous donner les reférences ?
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message par Flype »

@denis
en fait le prog que j'utilise est une barre multifonctions plutot pratique.
j'aime bien. ca fait bien un an maintenant que je l'utilise...

va voir ici :
Image
http://www.winbar.nl/download.php
je conseille pour l'instant la version 1.2.95.
mais c'est pas un outil de debuggage tres précis franchement.
juste de quoi garder un oeil sur l'utilisation du cpu, de la memoire, de l'IP... :wink:
Image
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

Bonne remarque Flype, merci :D

J'ai cherché et j'ai trouvé, il faut remplacer tous les ReleaseDC par des DeleteDC.

Je met à jour la lib sur mon site de suite

Denis > Regarde l'API dans le code

Edition : Lib mise à jour sur mon site
Dernière modification par Le Soldat Inconnu le mar. 22/févr./2005 22:33, modifié 1 fois.
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message par Flype »

regis>
j'aime pas les fuites :twisted:
et je confirme ca marche bcp mieux avec DeleteDC_(hdc).
mais ta MAJ integre t elle aussi le DeleteObject_(hObject) à la derniere ligne de la procedure RotateImageEx ?

denis>
comme dit regis, regarde l'API, je te mets l'exemple...
utile n'est ce pas pour debugger :wink:

Code : Tout sélectionner

RamInfo.MEMORYSTATUS

GlobalMemoryStatus_(@RamInfo)

RAM_Load  = RamInfo\dwMemoryLoad
RAM_Free  = RamInfo\dwAvailPhys / 1024 / 1024
RAM_Total = RamInfo\dwTotalPhys / 1024 / 1024 

Debug Str(RAM_Load)+" %"
Debug Str(RAM_Free)+" Mo"
Debug Str(RAM_Total)+" Mo"
Image
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

Pour DeleteObject_(hObject), j'ai regardé sur la doc MS, et dans mon cas, c'est inutile car je récupère simplement la taille d'une image existante.
En fait, je ne crée pas d'objet, je récupère des infos dessus.

Mais pour ReleasedDc_( je croyais que ça le détruisait, en fait ça ferme simplement le DC mais il existe toujours.
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

En fait, le code de retour de l'API GetObject n'est pas un handle mais normalement une information sur le nombre d'octets copié dans le tampon.
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message par Flype »

exact :wink:
Image
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

Merci Flype,

je pense que la barre fera l'affaire dans la majorité des cas.
Je que je cherche depuis un moment (sans beaucoup me fatiguer :roll: ) c'est un utilitaire que je lance par exemple avant l'application PB qui me donne la mémoire dispo puis lorsque je ferme le prog PB, il me donne la taille de la mémoire.
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

voir ici :

http://www.purearea.net/pb/english/index.htm

vous trouverez une aide au format hlp dans le zip
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Re: Librairie Effect

Message par Le Soldat Inconnu »

Je suis en train de travailler sur une mise à jour pour PB4.40 avec le support de la couche alpha sur la rotation des images, symétrie, etc...

Et il me reste la rotation qui risque d'être assez complexe.
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Librairie Effect

Message par djes »

Il y a luis sur le forum anglais qui vient d'en faire une... Je lui ai déjà parlé de toi.
http://www.purebasic.fr/english/viewtop ... 12&t=38975
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Re: Librairie Effect

Message par Le Soldat Inconnu »

voila la fonction avec lissage pour image avec couche alpha, ça fonctionne nickel

j'ai du viré tout l'asm pour retrouvé mes petits

ça donne ça pour le moment

Code : Tout sélectionner

ProcedureDLL.l RotateImageEx2(ImageID, Angle.f, Mode.l) ; Rotation d'une image d'un angle en °
	Protected bmi.BITMAPINFO, bmi2.BITMAPINFO, hdc.l, NewImageID, Mem, n, nn, bm.BITMAP
	
	Angle = Angle * #PI / 180 ; On convertit en radian
	
	Cos.f = Cos(Angle)
	Sin.f = Sin(Angle)
	
	CouleurFond = 0
	
	GetObject_(ImageID, SizeOf(BITMAP), @bm.BITMAP)
	
	bmi\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
	bmi\bmiHeader\biWidth = bm\bmWidth
	bmi\bmiHeader\biHeight = bm\bmHeight
	bmi\bmiHeader\biPlanes = 1
	bmi\bmiHeader\biBitCount = 32
	
	bmi2\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
	Select Mode
		Case 1
			bmi2\bmiHeader\biWidth = bm\bmWidth
			bmi2\bmiHeader\biHeight = bm\bmHeight
		Case 2
			bmi2\bmiHeader\biWidth = Round(Sqr(bm\bmWidth * bm\bmWidth + bm\bmHeight * bm\bmHeight), 1)
			bmi2\bmiHeader\biHeight = bmi2\bmiHeader\biWidth
		Default
			bmi2\bmiHeader\biWidth = Round(bm\bmWidth * Abs(Cos) + bm\bmHeight * Abs(Sin), 1)
			bmi2\bmiHeader\biHeight = Round(bm\bmHeight * Abs(Cos) + bm\bmWidth * Abs(Sin), 1)
	EndSelect
	bmi2\bmiHeader\biPlanes = 1
	bmi2\bmiHeader\biBitCount = 32
	
	Mem = AllocateMemory(bm\bmWidth * bm\bmHeight * 4)
	If Mem
		Mem2 = AllocateMemory(bmi2\bmiHeader\biWidth * bmi2\bmiHeader\biHeight * 4)
		If Mem2
			
			hdc = CreateCompatibleDC_(GetDC_(ImageID))
			If hdc
				GetDIBits_(hdc, ImageID, 0, bm\bmHeight, Mem, @bmi, #DIB_RGB_COLORS) ; on envoie la liste dans l'image
				DeleteDC_(hdc)
			EndIf
			
			CX1 = bm\bmWidth - 1
			CY1 = bm\bmHeight - 1
			CX2 = bmi2\bmiHeader\biWidth - 1
			CY2 = bmi2\bmiHeader\biHeight - 1
			
			Mem01 = Mem + bm\bmWidth * 4
			Mem10 = Mem + 4
			Mem11 = Mem01 + 4
			
			Mem2Temp = Mem2
			
			For nn = 0 To CY2
				y1b.l = nn * 2 - CY2
				Temp1.f = CX1 - y1b * Sin
				Temp2.f = CY1 + y1b * Cos
				For n = 0 To CX2
					x1b.l = n * 2 - CX2
					
					x1.f = (Temp1 + x1b * Cos) / 2
					y1.f = (Temp2 + x1b * Sin) / 2
					
					x2.l = x1
					y2.l = y1
					
					If x1 < x2
						DEC x2
					EndIf
					If y1 < y2
						DEC y2
					EndIf
					
					x2b = x2 + 1
					y2b = y2 + 1
					
					If x2b >= 0 And x2 <= CX1 And y2b >= 0 And y2 <= CY1 ; On filtre si on est completement en dehors de l'image
						
						fx.f = x1 - x2
						fy.f = y1 - y2
						f00.f = (1 - fx) * (1 - fy)
						f01.f = (1 - fx) * fy
						f10.f = fx * (1 - fy)
						f11.f = fx * fy
						
						MemTemp = (x2 + y2 * bm\bmWidth) * 4
						
						If x2 >= 0 And x2 <= CX1
							If y2 >= 0 And y2 <= CY1
								c00 = PeekL(Mem + MemTemp)
							Else
								c00 = 0
							EndIf
							If y2b >= 0 And y2b <= CY1
								c01 = PeekL(Mem01 + MemTemp)
							Else
								c01 = 0
							EndIf
						Else
							c00 = 0
							c01 = 0
						EndIf
						If x2b >= 0 And x2b <= CX1
							If y2 >= 0 And y2 <= CY1
								c10 = PeekL(Mem10 + MemTemp)
							Else
								c10 = 0
							EndIf
							If y2b >= 0 And y2b <= CY1
								c11 = PeekL(Mem11 + MemTemp)
							Else
								c11 = 0
							EndIf
						Else
							c10 = 0
							c11 = 0
						EndIf
						
						Channel00 = c00 >> 24 & $FF
						Channel01 = c01 >> 24 & $FF
						Channel10 = c10 >> 24 & $FF
						Channel11 = c11 >> 24 & $FF
						Alpha = Channel00 * f00 + Channel01 * f01 + Channel10 * f10 + Channel11 * f11
						Channel00 = c00 >> 16 & $FF
						Channel01 = c01 >> 16 & $FF
						Channel10 = c10 >> 16 & $FF
						Channel11 = c11 >> 16 & $FF
						Rouge = Channel00 * f00 + Channel01 * f01 + Channel10 * f10 + Channel11 * f11
						Channel00 = c00 >> 8 & $FF
						Channel01 = c01 >> 8 & $FF
						Channel10 = c10 >> 8 & $FF
						Channel11 = c11 >> 8 & $FF
						Vert = Channel00 * f00 + Channel01 * f01 + Channel10 * f10 + Channel11 * f11
						Channel00 = c00 & $FF
						Channel01 = c01 & $FF
						Channel10 = c10 & $FF
						Channel11 = c11 & $FF
						Bleu = Channel00 * f00 + Channel01 * f01 + Channel10 * f10 + Channel11 * f11
						
						PokeL(Mem2Temp, Rouge | Vert << 8 | Bleu << 16 | Alpha << 24)
						
					Else
						PokeL(Mem2Temp, 0)
					EndIf
					
					Mem2Temp + 4
					
				Next
			Next
			
			; On crée la nouvelle image
			NewImageID = CreateImage(#PB_Any, bmi2\bmiHeader\biWidth, bmi2\bmiHeader\biHeight, 32)
			hdc = CreateCompatibleDC_(GetDC_(ImageID(NewImageID)))
			If hdc
				SetDIBits_(hdc, ImageID(NewImageID), 0, bmi2\bmiHeader\biHeight, Mem2, @bmi2, #DIB_RGB_COLORS) ; on envoie la liste dans l'image
				DeleteDC_(hdc)
			EndIf
			
			FreeMemory(Mem2)
		EndIf
		FreeMemory(Mem)
	EndIf
	
	ProcedureReturn NewImageID
EndProcedure


;- ----------------------------------------
;- Test  d'affichage d'image avec rotation
; On dessine une image

ImageNormale = CreateImage(#PB_Any, 80, 100, 32)
StartDrawing(ImageOutput(ImageNormale))
	DrawingMode(#PB_2DDrawing_AlphaChannel)
	Box(0, 0, 80, 100, $00000000)
	DrawingMode(#PB_2DDrawing_Gradient | #PB_2DDrawing_AlphaBlend)
	LinearGradient(0, 0, 80, 100)
	GradientColor(0.0, $00000000)
	GradientColor(1.0, $FF000000)
	Box(0, 0, 80, 100)
	DrawingMode(#PB_2DDrawing_AlphaBlend)
	Box(5, 5, 35, 45, $B00000FF)
	Box(40, 5, 35, 45, $FF00FF00)
	Box(5, 50, 35, 45, $FFFF0000)
	Box(40, 50, 35, 45, $80FFFFFF)
StopDrawing()

; Création de la fenêtre et de la GadgetList
If OpenWindow(0, 0, 0, 350, 400, "Effect - Rotation d'image", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget) = 0
	End
EndIf

Angle.f = 30
Mode = 0
ImageRotation = RotateImageEx2(ImageID(ImageNormale), Angle, Mode)

TextGadget(#PB_Any, 10, 10, 100, 15, "Image normale")
ImageGadget(#PB_Any, 10, 25, 0, 0, ImageID(ImageNormale))

RotationTexte = TextGadget(#PB_Any, 10, 200, 100, 15, "Rotation de 30°")
Rotation = ImageGadget(#PB_Any, 10, 215, 0, 0, ImageID(ImageRotation))
RotationTemps = TextGadget(#PB_Any, 180, 270, 170, 15, "")

TextGadget(#PB_Any, 180, 200, 100, 15, "Mode :")
OptionGadget(0, 180, 215, 170, 15, "normal")
OptionGadget(1, 180, 230, 170, 15, "sans redimensionnement")
OptionGadget(2, 180, 245, 170, 15, "avec redimensionnement fixe")
SetGadgetState(0, 1)

AddWindowTimer(0, 1, 200)

Repeat
	Event = WaitWindowEvent()
	
	If Event = #PB_Event_Timer
		If EventTimer() = 1
			Angle + 1
			If Angle = 360
				Angle = 0
			EndIf
			Temps1 = ElapsedMilliseconds()
			For n = 1 To 100
				FreeImage(ImageRotation)
				ImageRotation = RotateImageEx2(ImageID(ImageNormale), Angle, Mode)
			Next
			Temps2 = ElapsedMilliseconds()
			SetGadgetState(Rotation, ImageID(ImageRotation))
			SetGadgetText(RotationTexte, "Rotation de " + Str(Angle) + "°")
			SetGadgetText(RotationTemps, StrF((Temps2 - Temps1) / 100, 2) + "ms")
			
		EndIf
	ElseIf Event = #PB_Event_Gadget
		Select EventGadget()
			Case 0
				Mode = 0
			Case 1
				Mode = 1
			Case 2
				Mode = 2
		EndSelect
	EndIf
	
Until Event = #PB_Event_CloseWindow

End
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Répondre