Effet Torche ?!

Programmation avancée de jeux en PureBasic
Mytic
Messages : 466
Inscription : mer. 25/juil./2007 0:13

Message par Mytic »

Ollivier a écrit :Par contre, ce qu'il est intéressant de voir, vu que je n'ai pas encore téléchargé les images de case, c'est de savoir lequel des codes bouffe en ressources CPU (le mien est assez gourmand).

Ollivier
Chez moi il bouffe 71% du CPU en plein mouvement.
Et celui de Case utilise 40% mais avec un delay(2)
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Message par Ollivier »

@case

Mes hommages du jour et chapeau bas : félicitations !

:D
beauregard
Messages : 1307
Inscription : dim. 08/juil./2007 18:32
Localisation : Toulouse

Message par beauregard »

c'est fortiche tout çà :), surtout l'utilisation du PokeL, ça me rappele de vieux souvenirs sur atari800XL...
Mwoua
Messages : 44
Inscription : lun. 24/oct./2005 10:28

Message par Mwoua »

'lut à tous !

J'arrive toujours pas à décortiquer clairement les différents codes... alors je fais appel à vous :lol: :

j'ai 2 images en mémoires, et je souhaite en créer une troisième (ou modifier l'une des 2, peut importe) avec comme résultat :

- tous les pixels identiques sur les 2 images deviennent blanc, ou noir, au choix 8)

- et pour les pixels qui diffèrent, on ne garde que ceux de la 2ème image.

J'ai essayé en faisant un test sur tous les pixels, avec des PokeC et PeekC, mais c'est assez lent.
Vous auriez d'autres idées ? :idea:
Anonyme

Message par Anonyme »

Mwoua a écrit :'lut à tous !

J'arrive toujours pas à décortiquer clairement les différents codes... alors je fais appel à vous :lol: :

j'ai 2 images en mémoires, et je souhaite en créer une troisième (ou modifier l'une des 2, peut importe) avec comme résultat :

- tous les pixels identiques sur les 2 images deviennent blanc, ou noir, au choix 8)

- et pour les pixels qui diffèrent, on ne garde que ceux de la 2ème image.

J'ai essayé en faisant un test sur tous les pixels, avec des PokeC et PeekC, mais c'est assez lent.
Vous auriez d'autres idées ? :idea:

Essaye ca :

Code : Tout sélectionner


Declare CompareData(*Data_A.l,*Data_B.l,Lenght.l,Replace)
Declare GetData(ImageID)

UsePNGImageDecoder()
UsePNGImageEncoder()


LoadImage(0,"A.bmp")
LoadImage(1,"B.bmp")

Debug CreateImage(2,256,256)

ResizeImage(0,256,256,#PB_Image_Smooth)
ResizeImage(1,256,256,#PB_Image_Smooth)

TimerA = ElapsedMilliseconds()

*PixMapA = GetData(0)
*PixMapB = GetData(1)
*PixMapC = CompareData(*PixMapA,*PixMapB,64*64,RGB(255,255,255))

StartDrawing(ImageOutput(2))

For y = 0 To ImageHeight(2)-1
  For x = 0 To ImageWidth(2)-1
   Color = PeekL(*PixMapC+(x*4)+ImageWidth(2)*(y*4))
   Plot(x,y,Color)
  Next 
Next 


StopDrawing()



TimerB = ElapsedMilliseconds()

SaveImage(2,"C.png",#PB_ImagePlugin_PNG )
MessageRequester("Temps = ",Str(B-A)+"ms")




Procedure.l GetData(ImageID)

Protected *Dta.l

*Dta = AllocateMemory(4*ImageHeight(ImageID)*ImageWidth(ImageID))


StartDrawing(ImageOutput(ImageID))

For y = 0 To ImageHeight(ImageID)-1
  For x = 0 To ImageWidth(ImageID)-1
   PokeL(*Dta+(x*4)+ImageWidth(ImageID)*(y*4),Point(x,y))
  Next 
Next 


StopDrawing()

ProcedureReturn *Dta
EndProcedure



Procedure.l CompareData(*Data_A.l,*Data_B.l,Lenght.l,Replace)

Protected A.l,B.l,Ra.l,Ga.l,Ba.l,Rb.l,Gb.l,Bb.l

*Data_C = AllocateMemory(4*Lenght)


For i = 0 To Lenght

  A = PeekL(*Data_A+(i*4))
  B = PeekL(*Data_B+(i*4))

  Ra = Red(A)
  Ga = Green(A)
  Ba = Blue(A)

  Rb = Red(B)
  Gb = Green(B)
  Bb = Blue(B)


  If A<>B
   PokeL(*Data_C+(i*4),B)
  ElseIf A=B
   PokeL(*Data_C+(i*4),Replace)
  EndIf 

Next 

ProcedureReturn *Data_C
EndProcedure
Mwoua
Messages : 44
Inscription : lun. 24/oct./2005 10:28

Message par Mwoua »

Merci Cpl.Bator pour ta réponse si rapide ! :D

Mais ça reste lent (le code, hein, pas toi :lol: ) :cry:

quelques erreurs dans ton code, qui donne un temps de calcul de 0ms 8) et aussi une erreur de dimensions au niveau de l'image 3 :

Code : Tout sélectionner

Declare CompareData(*Data_A.l,*Data_B.l,Lenght.l,Replace) 
Declare GetData(ImageID) 

UsePNGImageDecoder() 
UsePNGImageEncoder() 


LoadImage(0,"c:\A.bmp") 
LoadImage(1,"c:\B.bmp") 

Debug CreateImage(2,256,256) 

ResizeImage(0,256,256,#PB_Image_Smooth) 
ResizeImage(1,256,256,#PB_Image_Smooth) 

TimerA = ElapsedMilliseconds() 

*PixMapA = GetData(0) 
*PixMapB = GetData(1) 
*PixMapC = CompareData(*PixMapA,*PixMapB,256*256,RGB(255,255,255)) 

StartDrawing(ImageOutput(2)) 

For y = 0 To ImageHeight(2)-1 
  For x = 0 To ImageWidth(2)-1 
   Color = PeekL(*PixMapC+(x*4)+ImageWidth(2)*(y*4)) 
   Plot(x,y,Color) 
  Next 
Next 


StopDrawing() 



TimerB = ElapsedMilliseconds() 

SaveImage(2,"c:\C.bmp" ) 
MessageRequester("Temps = ",Str(TimerB-TimerA)+"ms") 




Procedure.l GetData(ImageID) 

Protected *Dta.l 

*Dta = AllocateMemory(4*ImageHeight(ImageID)*ImageWidth(ImageID)) 


StartDrawing(ImageOutput(ImageID)) 

For y = 0 To ImageHeight(ImageID)-1 
  For x = 0 To ImageWidth(ImageID)-1 
   PokeL(*Dta+(x*4)+ImageWidth(ImageID)*(y*4),Point(x,y)) 
  Next 
Next 


StopDrawing() 

ProcedureReturn *Dta 
EndProcedure 



Procedure.l CompareData(*Data_A.l,*Data_B.l,Lenght.l,Replace) 

Protected A.l,B.l,Ra.l,Ga.l,Ba.l,Rb.l,Gb.l,Bb.l 

*Data_C = AllocateMemory(4*Lenght) 


For i = 0 To Lenght 

  A = PeekL(*Data_A+(i*4)) 
  B = PeekL(*Data_B+(i*4)) 

  Ra = Red(A) 
  Ga = Green(A) 
  Ba = Blue(A) 

  Rb = Red(B) 
  Gb = Green(B) 
  Bb = Blue(B) 


  If A<>B 
   PokeL(*Data_C+(i*4),B) 
  ElseIf A=B 
   PokeL(*Data_C+(i*4),Replace) 
  EndIf 

Next 

ProcedureReturn *Data_C 
EndProcedure
Pour une image de 256*256, comme le fait ce code, ça me donne près de 300ms. En 1280*960, il faut plus de 5sec...

En fait j'imaginais une soluc' en utilisant les APIs : on peut, avec BitBlt_(), utiliser un "raster-operation" qui effectue une "combinaison" entre 2 images, mais je n'arrive pas à avoir ce que je cherche. L'avantage de BitBlt() est sa rapidité.

un exemple (mais qui ne fait pas tout à fait ce que je cherche) :

Code : Tout sélectionner

Global LargEcran=240
Global HautEcran=240

OpenWindow (0,0,0,80,80, "--",#PB_Window_SystemMenu)
StickyWindow(0,1)

CreateImage(1,LargEcran,HautEcran)
DC1 = StartDrawing(ImageOutput(1))
BitBlt_(DC1,0,0,LargEcran,HautEcran,GetDC_(GetDesktopWindow_()),0,0,#SRCCOPY )
StopDrawing()

OpenWindow (1,100,100,80,80, "--",#PB_Window_SystemMenu)
StickyWindow(1,1)

CreateImage(2,LargEcran,HautEcran)
DC2 = StartDrawing(ImageOutput(2))
BitBlt_(DC2,0,0,LargEcran,HautEcran,GetDC_(GetDesktopWindow_()),0,0,#SRCCOPY )
StopDrawing()

CopyImage(1,3)
DC3 = StartDrawing(ImageOutput(3))
If BitBlt_(DC3,0,0,LargEcran,HautEcran,GetDC_(GetDesktopWindow_()),0,0,#MERGEPAINT)=0 ;<======== #MERGEPAINT est le "raster-operation"
  End
EndIf
StopDrawing()

x=1
ResizeImage(1, LargEcran*x, HautEcran*x ,#PB_Image_Raw )
ResizeImage(2, LargEcran*x, HautEcran*x ,#PB_Image_Raw )
ResizeImage(3, LargEcran*x, HautEcran*x ,#PB_Image_Raw )

OpenWindow (2,0,0,3*(ImageWidth(1)+10)+10,ImageHeight(1)+20 , "FastImageOutput Test",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
StartDrawing (WindowOutput(2))
DrawImage (ImageID(1), 10, 10)
DrawImage (ImageID(2), 20+ImageWidth(1), 10)
DrawImage (ImageID(3), 30+2*ImageWidth(1), 10)
StopDrawing()

Repeat
  event=WaitWindowEvent()
Until event=#PB_Event_CloseWindow
Deux "inconvéniants" :

- les pixels qui diffèrent sont transformés en une combinaisons de ceux des 2 images, au lieu de garder ceux de la 2ème

- je n'arrive pas à faire ce "calcul" sur 2 images existantes. Uniquement sur une existante + une capture d'écran...

À vot' bon coeur, programmeurs fous que vous z'êtes ! :lol:

PS : Peut-être que l'aide Win32.hlp peux servir : http://91.146.56.62/math/win32.hlp
Avatar de l’utilisateur
case
Messages : 1545
Inscription : lun. 10/sept./2007 11:13

Message par case »

le probleme dans les operations booléennes c'est que c'est du bit a bit d'ou le melange entre les deux images avec bitblt qui sans doute fais un bete xor . a moins de comparer chaque pixel tu ne pourra pas faire mieux au niveau du rendu avec cette methode.

le plus rapide serais d'avoir les images en memoire et de comparer avec des peekl et de modifier avec pokel puisque dans le fond on s'en fiche de connaitre les couleurs ...
ImageImage
Avatar de l’utilisateur
case
Messages : 1545
Inscription : lun. 10/sept./2007 11:13

Message par case »

pas vraiment ce que je voulais faire (surtout au nveau de la reecriture j'utilise plot) mais c'est deja un bon debut il me semble

Code : Tout sélectionner

InitSprite()
main=OpenWindow(0,0,0,800,608,"diffpicture")
screen=OpenWindowedScreen(WindowID(0),0,0,800,608,0,0,0)
Declare getmem(ID)

LoadImage(0,"1.bmp")
LoadImage(1,"2.bmp") 

mem1=getmem(0)
mem2=getmem(1)

CreateImage(3,800,600)

a=ElapsedMilliseconds()
StartDrawing(ImageOutput(3))
	For y=0 To ImageHeight(0)-1
		For x=0 To ImageWidth(0)-1
		c=PeekL(mem1+aa)
		d=PeekL(mem2+aa)
		If c<>d
			r=d >> 16& $ff
			g=d >> 8 & $ff
			b=d & $ff
			Plot(x,(ImageHeight(0)-1)-y,RGB(r,g,b))
		EndIf
		aa=aa+4
	Next
Next
StopDrawing()
FreeMemory(mem1)
FreeMemory(mem2)
Debug ElapsedMilliseconds()-a
StartDrawing(ScreenOutput())
DrawImage(ImageID(3),0,0)
StopDrawing()
Repeat
Repeat
	Event = WindowEvent()
	spr=0
    Select Event 
    Case #PB_Event_Gadget
          If EventGadget() = 0
            End
          EndIf       
        Case #PB_Event_CloseWindow
          End 
      EndSelect
   Until Event = 0 
   Delay(1)
   FlipBuffers(1)

ForEver
Procedure getmem(ID)
	ImageID=  ImageID(id)
	Hdc = CreateCompatibleDC_ ( GetDC_ ( ImageID ))
	If HDC
		bmi.BITMAPINFO
		bm.BITMAP
		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
		bmi\bmiheader\biCompression = #BI_RGB
		HList = AllocateMemory (bm\bmWidth*bm\bmHeight*4)
		GetDIBits_ (hDC, ImageID ,0,bm\bmHeight,HList,bmi, #DIB_RGB_COLORS ) 	
		ProcedureReturn HList
	EndIf
	ProcedureReturn -1 ; erreur
	
EndProcedure
ImageImage
Avatar de l’utilisateur
Ar-S
Messages : 9539
Inscription : dim. 09/oct./2005 16:51
Contact :

Message par Ar-S »

Peux tu fournir tes images 1 et 2 pour voir ce que ça donne ?
Merci
Avatar de l’utilisateur
case
Messages : 1545
Inscription : lun. 10/sept./2007 11:13

Message par case »

ben deux images en bmp ca doit etre simple a trouver :p ou a fabriquer

enfin pour les flemmards voila :)


http://zorgrage.dyndns.org/pictures/1.bmp
http://zorgrage.dyndns.org/pictures/2.bmp


clic droit enregistrer sous :)
ImageImage
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

j'avais parlé de l'effet torche /éclairage il y a longtemps déjà
http://www.purebasic.fr/french/viewtopi ... sc&start=0

Et voici le code que j'avais réussi a pondre.
File:1->Light_Test.zip
Image
Répondre