PureBasic

Forums PureBasic
Nous sommes le Dim 26/Mai/2013 3:36

Heures au format UTC + 1 heure




Poster un nouveau sujet Répondre au sujet  [ 111 messages ]  Aller à la page Précédente  1, 2, 3, 4, 5, 6 ... 8  Suivante
Auteur Message
 Sujet du message:
MessagePosté: Sam 12/Fév/2005 20:44 
Hors ligne
Avatar de l’utilisateur

Inscription: Sam 27/Mar/2004 16:44
Messages: 467
Citation:
Du coup, je demande si il ne serai pas interressant d'optimiser avec de l'assembleur ma lib.
Est-ce que des pros de l'assembleur seraient partant ?

Oui, je veux bien le faire :D

_________________
fanghua bu ru yuan er


Haut
 Profil  
 
 Sujet du message:
MessagePosté: Sam 12/Fév/2005 21:07 
Hors ligne
Avatar de l’utilisateur

Inscription: Mer 28/Jan/2004 20:58
Messages: 4311
Localisation: Clermont ferrand OU Olsztyn
ok ;)

voici un exemple qui permet de tester la rapidité de la rotation et son bon fonctionnement.
La procedure qui permet la rotation est au début. y'a plus qu'à l'optimiser et voir le résultat :wink:

Code:
ProcedureDLL.l RotateImage2(ImageID, Angle.l) ; Rotation d'une image d'un angle multiple de 90°
  Protected bmi.BITMAPINFO, Hdc.l, NewImageID, Mem, n, nn, bm.BITMAP, Temp1, Temp2
 
  NewImageID = 0
 
  If Angle <= 0
    Angle = 360 + Angle
  EndIf
 
  ; On récupère la taille de l'image
  GetObject_(ImageID, SizeOf(BITMAP), @bm.BITMAP)
 
  If Angle = 90 Or Angle = 180 Or Angle = 270

    ; on prépare les infos pour récupérer l'image sous forme d'adresse mémoire
    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
   
    ; On alloue 2 espace mémoire pour recevoir l'image d'origine et l'image pivotée
    Mem = AllocateMemory(bm\bmWidth * bm\bmHeight * 4)
    If Mem
      Mem2 = AllocateMemory(bm\bmWidth * bm\bmHeight * 4)
      If Mem2
       
        ; On récupère l'image dans un espace mémoire
        Hdc = CreateCompatibleDC_(GetDC_(ImageID))
        If Hdc
          GetDIBits_(Hdc, ImageID, 0, bm\bmHeight, Mem, @bmi, #DIB_RGB_COLORS) ; on envoie la liste dans l'image
          ReleaseDC_(0, Hdc)
        EndIf
       
        ; On fait la rotation de l'image de 90, 180 ou 270°
        Select Angle
          Case 90 ; rotation de 90°
            Temp1 = bm\bmWidth - 1
            ; Pour chaque point de l'image
            For n = 0 To bm\bmHeight - 1
              For nn = 0 To Temp1
                PokeL(Mem2 + (n + (Temp1 - nn) * bm\bmHeight) * 4, PeekL(Mem + (nn + n * bm\bmWidth) * 4)) ; On fait une rotation de 90°
                ; Le * 4 vient du fait qu'on manipule des long
              Next
            Next
            ; On inverse la largeur et la hauteur de l'image
            Temp1 = bm\bmHeight : bm\bmHeight = bm\bmWidth : bm\bmWidth = Temp1
            bmi\bmiHeader\biWidth = bm\bmWidth
            bmi\bmiHeader\biHeight = bm\bmHeight
            ; On crée la nouvelle image vierge
            NewImageID = CreateImage(#PB_Any, bm\bmWidth, bm\bmHeight)
           
          Case 180
            Temp1 = Mem2 + bm\bmWidth * bm\bmHeight * 4 - 4
            For n = 0 To bm\bmHeight - 1
              For nn = 0 To bm\bmWidth - 1
                Temp2 = (nn + n * bm\bmWidth) * 4
                PokeL(Temp1 - Temp2, PeekL(Mem + Temp2))
              Next
            Next
            NewImageID = CreateImage(#PB_Any, bm\bmWidth, bm\bmHeight)
           
          Case 270
            Temp1 = bm\bmHeight - 1
            For n = 0 To Temp1
              For nn = 0 To bm\bmWidth - 1
                PokeL(Mem2 + (Temp1 - n + nn * bm\bmHeight) * 4, PeekL(Mem + (nn + n * bm\bmWidth) * 4))
              Next
            Next
            Temp1 = bm\bmHeight : bm\bmHeight = bm\bmWidth : bm\bmWidth = Temp1
            bmi\bmiHeader\biWidth = bm\bmWidth
            bmi\bmiHeader\biHeight = bm\bmHeight
            NewImageID = CreateImage(#PB_Any, bm\bmWidth, bm\bmHeight)
           
        EndSelect
       
        ; On copie l'espace mémoire qui contient l'image pivotée dans la nouvelle image créée
        Hdc = CreateCompatibleDC_(GetDC_(ImageID()))
        If Hdc
          SetDIBits_(Hdc, ImageID(), 0, bm\bmHeight, Mem2, @bmi, #DIB_RGB_COLORS) ; on envoie la liste dans l'image
          ReleaseDC_(0, Hdc)
        EndIf
       
        ; On libère la mémoire
        FreeMemory(Mem2)
      EndIf
      FreeMemory(Mem)
    EndIf
   
  ElseIf Angle = 360
    NewImageID = CreateImage(#PB_Any, bm\bmWidth, bm\bmHeight)
    StartDrawing(ImageOutput())
      DrawImage(ImageID, 0, 0)
    StopDrawing()
  EndIf
 
  ProcedureReturn NewImageID
EndProcedure



;-----------------------------------------
;- Test de rapidité

ImageOrigine = CreateImage(0, 1000, 1000)
StartDrawing(ImageOutput())
  For n = 0 To 999
    For nn = 0 To 999
      Plot(n, nn, Random($FFFFFF))
    Next
  Next
StopDrawing()
Dim Liste(ImageWidth() - 1, ImageHeight() - 1)

#NbTest = 5

Temps1 = ElapsedMilliseconds()

For n = 1 To #NbTest
  ;- Test de rapidité sur la rotation et la symétrie d'image
  ; ImageModifiee = ImageSymmetryH(ImageOrigine)
  ; ImageModifiee = ImageSymmetryV(ImageOrigine)
  ; ImageModifiee = RotateImage(ImageOrigine, 180)
  ImageModifiee = RotateImage2(ImageOrigine, 90)
  ; ImageModifiee = RotateImage(ImageOrigine, 270)
  ; ImageModifiee = RotateImageEx(ImageOrigine, 30)
  ;- Test de rapidité sur le transfert d'image
  ; GetImageBits(UseImage(0), @Liste())
  ; SetImageBits(UseImage(0), @Liste())
Next

Temps2 = ElapsedMilliseconds()

Vitesse = (Temps2 - Temps1) / #NbTest
NbPixel = ImageHeight() * ImageWidth()

MessageRequester("Temps", Str(Vitesse) + " ms" + Chr(10) + "Image de " + Str(ImageWidth()) + " * " + Str(ImageHeight()) + " pixels" + Chr(10) + "Nb pixels traités = " + Str(NbPixel), 0)


;-----------------------------------------
;- Test  d'affichage d'image avec rotation
; On dessine une image
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()

; On fait différente rotation de cette image
ImageRotation90 = RotateImage2(UseImage(ImageNormale), 90) ; ou -270°
ImageRotation180 = RotateImage2(UseImage(ImageNormale), 180) ; ou -180°
ImageRotation270 = RotateImage2(UseImage(ImageNormale), 270) ; ou -90°
; RotateImage(ImageID.l, Angle.l)
; ImageID : Handle de l'image
; Angle : Angle de rotation en dégré, les valeurs suivantes sont acceptées : -270, -180, -90, 0, 90, 180, 270, 360
; La fonction retourne l'identifiant PB de la nouvelle image, pas le handle de la nouvelle image, le but étant de pouvoir manipuler cette nouvelle image comme une image PB

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

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

TextGadget(#PB_Any, 120, 10, 100, 15, "Rotation de 90°")
ImageGadget(#PB_Any, 120, 25, 0, 0, UseImage(ImageRotation90))

TextGadget(#PB_Any, 10, 135, 100, 15, "Rotation de 180°")
ImageGadget(#PB_Any, 10, 150, 0, 0, UseImage(ImageRotation180))

TextGadget(#PB_Any, 120, 135, 100, 15, "Rotation de 270°")
ImageGadget(#PB_Any, 120, 150, 0, 0, UseImage(ImageRotation270))

Repeat
  Event = WaitWindowEvent()
 
Until Event = #PB_EventCloseWindow

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)]


Haut
 Profil  
 
 Sujet du message:
MessagePosté: Dim 13/Fév/2005 9:54 
Hors ligne
Avatar de l’utilisateur

Inscription: Sam 27/Mar/2004 16:44
Messages: 467
Voilà c'est fait :D
le traitement graphique est beaucoup plus rapide, mais le problème c'est la lenteur des fonctions API (GetDIBits_,SetDIBits_,...) que je ne peux pas optimiser. Pour avoir un résultat flagrant, il faudrait un traitement graphique "plus lourd"...
Code:
ProcedureDLL.l RotateImage2(ImageID, Angle.l) ; Rotation d'une image d'un angle multiple de 90°
          Protected bmi.BITMAPINFO, Hdc.l, NewImageID, n, nn, bm.BITMAP, Temp1, Temp2
          Global Mem,Mem2,pMem,Largeur,Largeur4,Longueur,Longueur4
          NewImageID = 0
         
          If Angle <= 0
                    Angle = 360 + Angle
          EndIf
         
          ; On récupère la taille de l'image
          GetObject_(ImageID, SizeOf(BITMAP), @bm.BITMAP)
         
          If Angle = 90 Or Angle = 180 Or Angle = 270
                   
                    ; on prépare les infos pour récupérer l'image sous forme d'adresse mémoire
                    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
                   
                    ; On alloue 2 espace mémoire pour recevoir l'image d'origine et l'image pivotée
                    Mem = AllocateMemory(bm\bmWidth * bm\bmHeight * 4)
                    If Mem
                              Mem2 = AllocateMemory(bm\bmWidth * bm\bmHeight * 4)
                              If Mem2
                                       
                                        ; On récupère l'image dans un espace mémoire
                                        Hdc = CreateCompatibleDC_(GetDC_(ImageID))
                                        If Hdc
                                                  GetDIBits_(Hdc, ImageID, 0, bm\bmHeight, Mem, @bmi, #DIB_RGB_COLORS) ; on envoie la liste dans l'image
                                                  ReleaseDC_(0, Hdc)
                                        EndIf
                                       
                                        ; On fait la rotation de l'image de 90, 180 ou 270°
                                        Select Angle
                                                  Case 90 ; rotation de 90°
                                                            ;/
                                                            Longueur = bm\bmWidth
                                                            Largeur = bm\bmHeight
                                                            Largeur4 = bm\bmHeight * 4
                                                            pMem = Mem2 - Largeur4 + ( bm\bmWidth * bm\bmHeight ) * 4
                                                            ; Pour chaque point de l'image
                                                            !MOV   ebx,dword [v_Mem]
                                                            !MOV   eax,dword [v_pMem]
                                                            !MOV   ecx,dword [v_Largeur]
                                                            !Encore90Y:
                                                                      !PUSH    ecx
                                                                      !PUSH    eax
                                                                      !MOV     ecx,dword [v_Longueur]
                                                                      !Encore90X:
                                                                                !MOV    edx,dword[ebx]
                                                                                !MOV    dword[eax],edx
                                                                                !ADD     ebx,4
                                                                                !SUB     eax,dword [v_Largeur4]
                                                                                !DEC     ecx
                                                                      !JNZ Encore90X
                                                                      !POP eax
                                                                      !ADD eax,4
                                                                      !POP ecx
                                                                      !DEC ecx
                                                            !JNZ Encore90Y
                                                            ;/
                                                           
                                                            ; On inverse la largeur et la hauteur de l'image
                                                            Temp1 = bm\bmHeight : bm\bmHeight = bm\bmWidth : bm\bmWidth = Temp1
                                                            bmi\bmiHeader\biWidth = bm\bmWidth
                                                            bmi\bmiHeader\biHeight = bm\bmHeight
                                                            ; On crée la nouvelle image vierge
                                                            NewImageID = CreateImage(#PB_Any, bm\bmWidth, bm\bmHeight)
                                                           
                                                  Case 180
                                                            ;/
                                                            Longueur = bm\bmWidth
                                                            Largeur = bm\bmHeight
                                                            Longueur4 = bm\bmWidth * 4
                                                            pMem = Mem2 + ( bm\bmWidth * bm\bmHeight ) * 4 - 4
                                                            ; Pour chaque point de l'image
                                                            !MOV   ebx,dword [v_Mem]
                                                            !MOV   eax,dword [v_pMem]
                                                            !MOV   ecx,dword [v_Largeur]
                                                            !Encore180Y:
                                                                      !PUSH    ecx
                                                                      !PUSH    eax
                                                                      !MOV     ecx,dword [v_Longueur]
                                                                      !Encore180X:
                                                                                !MOV    edx,dword[ebx]
                                                                                !MOV    dword[eax],edx
                                                                                !ADD     ebx,4
                                                                                !SUB     eax,4
                                                                                !DEC     ecx
                                                                      !JNZ Encore180X
                                                                      !POP eax
                                                                      !SUB eax,dword [v_Longueur4]
                                                                      !POP ecx
                                                                      !DEC ecx
                                                            !JNZ Encore180Y
                                                            ;/
                                                            NewImageID = CreateImage(#PB_Any, bm\bmWidth, bm\bmHeight)
                                                           
                                                  Case 270
                                                            ;/
                                                            Longueur = bm\bmWidth
                                                            Largeur = bm\bmHeight
                                                            Largeur4 = bm\bmHeight * 4
                                                            pMem = Mem2 + Largeur4 - 4
                                                            ; Pour chaque point de l'image
                                                            !MOV   ebx,dword [v_Mem]
                                                            !MOV   eax,dword [v_pMem]
                                                            !MOV   ecx,dword [v_Largeur]
                                                            !Encore270Y:
                                                                      !PUSH    ecx
                                                                      !PUSH    eax
                                                                      !MOV     ecx,dword [v_Longueur]
                                                                      !Encore270X:
                                                                                !MOV    edx,dword[ebx]
                                                                                !MOV    dword[eax],edx
                                                                                !ADD     ebx,4
                                                                                !ADD     eax,dword [v_Largeur4]
                                                                                !DEC     ecx
                                                                      !JNZ Encore270X
                                                                      !POP eax
                                                                      !SUB eax,4
                                                                      !POP ecx
                                                                      !DEC ecx
                                                            !JNZ Encore270Y
                                                            ;/
                                                            Temp1 = bm\bmHeight : bm\bmHeight = bm\bmWidth : bm\bmWidth = Temp1
                                                            bmi\bmiHeader\biWidth = bm\bmWidth
                                                            bmi\bmiHeader\biHeight = bm\bmHeight
                                                            NewImageID = CreateImage(#PB_Any, bm\bmWidth, bm\bmHeight)
                                                           
                                        EndSelect
                                       
                                        ; On copie l'espace mémoire qui contient l'image pivotée dans la nouvelle image créée
                                        Hdc = CreateCompatibleDC_(GetDC_(ImageID()))
                                        If Hdc
                                                  SetDIBits_(Hdc, ImageID(), 0, bm\bmHeight, Mem2, @bmi, #DIB_RGB_COLORS) ; on envoie la liste dans l'image
                                                  ReleaseDC_(0, Hdc)
                                        EndIf
                                       
                                        ; On libère la mémoire
                                        FreeMemory(Mem2)
                              EndIf
                              FreeMemory(Mem)
                    EndIf
                   
          ElseIf Angle = 360
                    NewImageID = CreateImage(#PB_Any, bm\bmWidth, bm\bmHeight)
                    StartDrawing(ImageOutput())
                    DrawImage(ImageID, 0, 0)
                    StopDrawing()
          EndIf
         
          ProcedureReturn NewImageID
EndProcedure



;-----------------------------------------
;- Test de rapidité

ImageOrigine = CreateImage(0, 1000, 1000)
StartDrawing(ImageOutput())
For n = 0 To 999
          For nn = 0 To 999
                    Plot(n, nn, Random($FFFFFF))
          Next
Next
StopDrawing()
Dim Liste(ImageWidth() - 1, ImageHeight() - 1)

#NbTest = 5

Temps1 = ElapsedMilliseconds()

For n = 1 To #NbTest
          ;- Test de rapidité sur la rotation et la symétrie d'image
          ; ImageModifiee = ImageSymmetryH(ImageOrigine)
          ; ImageModifiee = ImageSymmetryV(ImageOrigine)
          ; ImageModifiee = RotateImage(ImageOrigine, 180)
          ImageModifiee = RotateImage2(ImageOrigine, 90)
          ; ImageModifiee = RotateImage(ImageOrigine, 270)
          ; ImageModifiee = RotateImageEx(ImageOrigine, 30)
          ;- Test de rapidité sur le transfert d'image
          ; GetImageBits(UseImage(0), @Liste())
          ; SetImageBits(UseImage(0), @Liste())
Next

Temps2 = ElapsedMilliseconds()

Vitesse = (Temps2 - Temps1) / #NbTest
NbPixel = ImageHeight() * ImageWidth()

MessageRequester("Temps", Str(Vitesse) + " ms" + Chr(10) + "Image de " + Str(ImageWidth()) + " * " + Str(ImageHeight()) + " pixels" + Chr(10) + "Nb pixels traités = " + Str(NbPixel), 0)


;-----------------------------------------
;- Test  d'affichage d'image avec rotation
; On dessine une image
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()

; On fait différente rotation de cette image
ImageRotation90 = RotateImage2(UseImage(ImageNormale), 90) ; ou -270°
ImageRotation180 = RotateImage2(UseImage(ImageNormale), 180) ; ou -180°
ImageRotation270 = RotateImage2(UseImage(ImageNormale), 270) ; ou -90°
; RotateImage(ImageID.l, Angle.l)
; ImageID : Handle de l'image
; Angle : Angle de rotation en dégré, les valeurs suivantes sont acceptées : -270, -180, -90, 0, 90, 180, 270, 360
; La fonction retourne l'identifiant PB de la nouvelle image, pas le handle de la nouvelle image, le but étant de pouvoir manipuler cette nouvelle image comme une image PB

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

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

TextGadget(#PB_Any, 120, 10, 100, 15, "Rotation de 90°")
ImageGadget(#PB_Any, 120, 25, 0, 0, UseImage(ImageRotation90))

TextGadget(#PB_Any, 10, 135, 100, 15, "Rotation de 180°")
ImageGadget(#PB_Any, 10, 150, 0, 0, UseImage(ImageRotation180))

TextGadget(#PB_Any, 120, 135, 100, 15, "Rotation de 270°")
ImageGadget(#PB_Any, 120, 150, 0, 0, UseImage(ImageRotation270))

Repeat
          Event = WaitWindowEvent()
         
Until Event = #PB_EventCloseWindow

End

_________________
fanghua bu ru yuan er


Haut
 Profil  
 
 Sujet du message:
MessagePosté: Dim 13/Fév/2005 11:14 
Hors ligne
Avatar de l’utilisateur

Inscription: Mer 28/Jan/2004 20:58
Messages: 4311
Localisation: Clermont ferrand OU Olsztyn
sur mon 900 mhz, j'ai pratiquement aucune différence de vitesse.
240 contre 250.

c'est pas flaggrant :( Sur des calcul simple, j'ai pas l'impression que l'ASM apporte beaucoup.

les fonctions de l'API prennent 186 ms donc les 3/4 du temps de calcul.

comme tu le dits, faut arriver à faire sauter l'API GetDIBits :)
Mais pour s'en passer, il faut trouver le moyen d'accéder à l'image en mémoire à partir de son handle. car passer par un startdrawing est nettement plus lent.
Quelqu'un à une idée ?


Par contre, sur un traitement avec plein de math, on doit avoir une grosse différence avec de l'ASM.

je vais te préparer un exemple pour la rotation d'une image avec un angle quelconque, la j'ai 4.3 secondes de calcul, on dervrait être bien plus gagnant

_________________
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)]


Haut
 Profil  
 
 Sujet du message:
MessagePosté: Dim 13/Fév/2005 12:32 
Hors ligne
Avatar de l’utilisateur

Inscription: Ven 13/Fév/2004 0:57
Messages: 3069
et en utilisant aucune fonction de Pure, que des API ?


Haut
 Profil  
 
 Sujet du message:
MessagePosté: Dim 13/Fév/2005 12:44 
Hors ligne
Avatar de l’utilisateur

Inscription: Sam 27/Mar/2004 16:44
Messages: 467
J'ai isolé les boucles des traitements graphiques pour voir les temps :
Code:
#NbTest = 5
Global Mem,Mem2,pMem,Largeur,Largeur4,Longueur
Longueur = 1000
Largeur = 1000

Mem = AllocateMemory(Longueur * Largeur * 4)
If Mem
          Mem2 = AllocateMemory(Longueur * Largeur * 4)
          If Mem2
                    ;/ rotation de 90°
                    Temps1 = ElapsedMilliseconds()
                    For t = 1 To #NbTest
                              ;/
                              Largeur4 = Largeur * 4
                              pMem = Mem2 - Largeur4 + ( Longueur * Largeur ) * 4
                              ; Pour chaque point de l'image
                              !MOV   ebx,dword [v_Mem]
                              !MOV   eax,dword [v_pMem]
                              !MOV   ecx,dword [v_Largeur]
                              !Encore90Y:
                                        !PUSH    ecx
                                        !PUSH    eax
                                        !MOV     ecx,dword [v_Longueur]
                                        !Encore90X:
                                                  !MOV    edx,dword[ebx]
                                                  !MOV    dword[eax],edx
                                                  !ADD     ebx,4
                                                  !SUB     eax,dword [v_Largeur4]
                                                  !DEC     ecx
                                        !JNZ Encore90X
                                        !POP eax
                                        !ADD eax,4
                                        !POP ecx
                                        !DEC ecx
                              !JNZ Encore90Y
                              ;/
                    Next
                    Temps2 = ElapsedMilliseconds()
                    For t = 1 To #NbTest
                              ;/
                              Temp1 = Longueur - 1
                              ; Pour chaque point de l'image
                              For n = 0 To Largeur - 1
                                        For nn = 0 To Temp1
                                                  PokeL(Mem2 + (n + (Temp1 - nn) * Largeur) * 4, PeekL(Mem + (nn + n * Longueur) * 4)) ; On fait une rotation de 90°
                                                  ; Le * 4 vient du fait qu'on manipule des long
                                        Next
                              Next
                              ;/
                    Next
                    Temps3 = ElapsedMilliseconds()
          EndIf
EndIf
MessageRequester("Vitesse", "Temps ASM : " + StrF((Temps2 - Temps1)/#NbTest) + " ms" + Chr(10) + "Temps PureBasic  : " + StrF((Temps3 - Temps2)/#NbTest) + " ms",#PB_MessageRequester_Ok)

bien qu'il y ait un petit avantage pour l'ASM, c'est vrai qu'il passe inaperçus à côté des fonctions GetDIBits SetDIBits. Mais je ne pense pas qu'on puisse accéder directement à la mémoire, Windows la protège, seules les APIs le peuvent, c'est pour cela qu'elles sont aussi lente, c'est parce qu'elles doivent montrer leurs papiers à la douane :mrgreen:

_________________
fanghua bu ru yuan er


Haut
 Profil  
 
 Sujet du message:
MessagePosté: Dim 13/Fév/2005 12:54 
Hors ligne
Avatar de l’utilisateur

Inscription: Jeu 22/Jan/2004 14:31
Messages: 3311
Je ne suis pas sur que l'on puisse optimiser beaucoup si on manipule des nombres flottants (tu dois surement les utiliser dans tes calculs d'angles), car les calculs avec les nombres flottants consomment beaucoup de temps.

Je crois que l'optimisation devrait d'abord passer par une recherche d'un meilleur algorithme si c'est possible.

Si on peut utiliser des tables avec des valeurs précalculées, il faut le faire, ça accelère souvent le résultat (limitation des calculs).

Lors de la compilation, sélectionne l'option ALL CPU, PB va intégrer un test sur le type de CPU et ajouter des routines optimisées (mais là je ne sais pas sur quelles fonctions portent les optimisations)

_________________
Documentation GDI + 1.0 PB 4.30 beta 4 et supérieur
PureIconManager


Haut
 Profil  
 
 Sujet du message:
MessagePosté: Dim 13/Fév/2005 13:16 
Hors ligne
Avatar de l’utilisateur

Inscription: Jeu 22/Jan/2004 14:31
Messages: 3311
J'ai une erreur à la ligne 110 avec le debuggeur
Plot is outside the drawing area

J'ai PB 3.92 beta2 et toutes les mises à jour des libs du site PureBasic beta

_________________
Documentation GDI + 1.0 PB 4.30 beta 4 et supérieur
PureIconManager


Haut
 Profil  
 
 Sujet du message:
MessagePosté: Dim 13/Fév/2005 15:27 
Hors ligne
Avatar de l’utilisateur

Inscription: Mer 28/Jan/2004 20:58
Messages: 4311
Localisation: Clermont ferrand OU Olsztyn
pas normal :? ça marche très bien chez moi

Code:
ImageOrigine = CreateImage(0, 1000, 1000)
StartDrawing(ImageOutput())
  For n = 0 To 999
    For nn = 0 To 999
      Plot(n, nn, Random($FFFFFF))
    Next
  Next
StopDrawing()

regarde, c'est pas possible d'avoir un plot en dehors de l'image
l'image fait 1000*1000 et je vais de 0 à 999 avec un For
Il y a un blème avec les Beta

_________________
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)]


Haut
 Profil  
 
 Sujet du message:
MessagePosté: Dim 13/Fév/2005 15:45 
Hors ligne
Avatar de l’utilisateur

Inscription: Mer 28/Jan/2004 20:58
Messages: 4311
Localisation: Clermont ferrand OU Olsztyn
je viens de penser à un truc :

on a la fonction PlgBlt_( qui visiblement permet de faire des rotations mais compatible uniquement sur 2000 et XP

mais rien n'empêche de faire un condition pour choisir cette fonction si l'OS est > à win 2000, et d'utiliser mon code sinon.

C'est compatible tout OS et ça ira peut-être plus vite sur XP et 2000 :)

la description de l'API en question est la :
http://msdn.microsoft.com/library/defau ... s_0qk3.asp




Sinon, pour la rotation avec un angle quelconque + lissage, la, il n'y a pas d'API, ou alors je suis bigleux :lol:

Voici mon code :
4.3 s sur mon 900mhz pour faire une rotation d'une image de 1000*1000

Il n'y a rien d'optimiser, il est brut de fonderie

Code:
ProcedureDLL.l RotateImageEx2(ImageID, Angle.f) ; Rotation d'une image d'un angle en °
  Protected bmi.BITMAPINFO, bmi2.BITMAPINFO, Hdc.l, NewImageID, Mem, n, nn, bm.BITMAP, Temp1, Temp2
 
  Angle = Angle * #Pi / 180 ; On convertit en radian
 
  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
 
  bmi2\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
  bmi2\bmiHeader\biWidth = Int(bm\bmWidth * Abs(Cos(Angle)) + bm\bmHeight * Abs(Sin(Angle)) + 0.5)
  bmi2\bmiHeader\biHeight = Int(bm\bmHeight * Abs(Cos(Angle)) + bm\bmWidth * Abs(Sin(Angle)) + 0.5)
  bmi2\bmiHeader\biPlanes = 1
  bmi2\bmiHeader\biBitCount = 32
  bmi2\bmiHeader\biCompression = #BI_RGB
 
  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
        ReleaseDC_(0, Hdc)
      EndIf
     
      CX1 = (bm\bmWidth - 1) * 100 / 2
      CY1 = (bm\bmHeight - 1) * 100 / 2
      CX2 = (bmi2\bmiHeader\biWidth - 1) * 100 / 2
      CY2 = (bmi2\bmiHeader\biHeight - 1) * 100 / 2
      For n = 0 To bmi2\bmiHeader\biWidth - 1
        For nn = 0 To bmi2\bmiHeader\biHeight - 1
          x2 = n * 100 - CX2
          y2 = nn * 100 - CY2
          x1.f = Int(CX1 + x2 * Cos(Angle) - y2 * Sin(Angle)) / 100
          y1.f = Int(CY1 + x2 * Sin(Angle) + y2 * Cos(Angle)) / 100
         
          If x1 < 0 : PasX = -1 : Else : PasX = 1 : EndIf
          If y1 < 0 : PasY = -1 : Else : PasY = 1 : EndIf
         
          If Int(x1) < 0 Or Int(x1) > bm\bmWidth - 1 Or Int(y1) < 0 Or Int(y1) > bm\bmHeight - 1
            c00 = 0
          Else
            c00 = PeekL(Mem + (Int(x1) + Int(y1) * bm\bmWidth) * 4)
          EndIf
          If Int(x1 + PasX) < 0 Or Int(x1 + PasX) > bm\bmWidth - 1 Or Int(y1) < 0 Or Int(y1) > bm\bmHeight - 1
            c10 = 0
          Else
            c10 = PeekL(Mem + (Int(x1 + PasX) + Int(y1) * bm\bmWidth) * 4)
          EndIf
          If Int(x1) < 0 Or Int(x1) > bm\bmWidth - 1 Or Int(y1 + PasY) < 0 Or Int(y1 + PasY) > bm\bmHeight - 1
            c01 = 0
          Else
            c01 = PeekL(Mem + (Int(x1) + Int(y1 + PasY) * bm\bmWidth) * 4)
          EndIf
          If Int(x1 + PasX) < 0 Or Int(x1 + PasX) > bm\bmWidth - 1 Or Int(y1 + PasY) < 0 Or Int(y1 + PasY) > bm\bmHeight - 1
            c11 = 0
          Else
            c11 = PeekL(Mem + (Int(x1 + PasX) + Int(y1 + PasY) * bm\bmWidth) * 4)
          EndIf
          fx.f = Abs(x1 - Int(x1))
          fy.f = Abs(y1 - Int(y1))
          f00.f = (1 - fx) * (1 - fy)
          f01.f = (1 - fx) * fy
          f10.f = fx * (1 - fy)
          f11.f = fx * fy
          r = Int(Red(c00) * f00 + Red(c10) * f10 + Red(c01) * f01 + Red(c11) * f11)
          g = Int(Green(c00) * f00 + Green(c10) * f10 + Green(c01) * f01 + Green(c11) * f11)
          b = Int(Blue(c00) * f00 + Blue(c10) * f10 + Blue(c01) * f01 + Blue(c11) * f11)
         
          PokeL(Mem2 + (n + nn * bmi2\bmiHeader\biWidth) * 4, RGB(r, g, b))
         
        Next
      Next
     
      ; On crée la nouvelle image
      NewImageID = CreateImage(#PB_Any, bmi2\bmiHeader\biWidth, bmi2\bmiHeader\biHeight)
      Hdc = CreateCompatibleDC_(GetDC_(ImageID()))
      If Hdc
        SetDIBits_(Hdc, ImageID(), 0, bmi2\bmiHeader\biHeight, Mem2, @bmi2, #DIB_RGB_COLORS) ; on envoie la liste dans l'image
        ReleaseDC_(0, Hdc)
      EndIf
     
      FreeMemory(Mem2)
    EndIf
    FreeMemory(Mem)
  EndIf
 
  ProcedureReturn NewImageID
EndProcedure



;-----------------------------------------
;- Test de rapidité

ImageOrigine = CreateImage(0, 1000, 1000)
StartDrawing(ImageOutput())
  For n = 0 To 999
    For nn = 0 To 999
      Plot(n, nn, Random($FFFFFF))
    Next
  Next
StopDrawing()
Dim Liste(ImageWidth() - 1, ImageHeight() - 1)

#NbTest = 2

Temps1 = ElapsedMilliseconds()

For n = 1 To #NbTest
  ImageModifiee = RotateImageEx2(ImageOrigine, 30)
Next

Temps2 = ElapsedMilliseconds()

Vitesse = (Temps2 - Temps1) / #NbTest
NbPixel = ImageHeight() * ImageWidth()

MessageRequester("Temps", Str(Vitesse) + " ms" + Chr(10) + "Image de " + Str(ImageWidth()) + " * " + Str(ImageHeight()) + " pixels" + Chr(10) + "Nb pixels traités = " + Str(NbPixel), 0)


;-----------------------------------------
;- Test  d'affichage d'image avec rotation
; On dessine une image
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()

ImageRotation = RotateImageEx2(UseImage(ImageNormale), 30)

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

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

TextGadget(#PB_Any, 10, 135, 100, 15, "Rotation de 30")
ImageGadget(#PB_Any, 10, 150, 0, 0, UseImage(ImageRotation))

Repeat
  Event = WaitWindowEvent()
 
Until Event = #PB_EventCloseWindow

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)]


Haut
 Profil  
 
 Sujet du message:
MessagePosté: Lun 14/Fév/2005 19:50 
Hors ligne
Avatar de l’utilisateur

Inscription: Mer 28/Jan/2004 20:58
Messages: 4311
Localisation: Clermont ferrand OU Olsztyn
Bon, optimisation du code pour faire la rotation d'image avec un angle quelconque.

Sur mon 900mhz, la rotation d'une image de 1000*1000 d'un angle de 30° met 1.3s au lieu 4.5s auparavant :D

J'ai mis à jour la lib sur mon site pour les intéressés

_________________
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)]


Haut
 Profil  
 
 Sujet du message:
MessagePosté: Lun 14/Fév/2005 20:25 
Hors ligne
Avatar de l’utilisateur

Inscription: Sam 27/Mar/2004 16:44
Messages: 467
Moi aussi j'ai optimisé le code PureBasic avant de m'attaquer à l'optimisation en assembleur. Pour pouvoir comparer équitablement les deux versions.( Le code ASM dans la procédure n'est là que à cause des nombres signés, j'ai juste remplacé les MOVSX )
Code:
#Pi = 3.1415926
ProcedureDLL.l RotateImageEx2(ImageID, Angle.f) ; Rotation d'une image d'un angle en °
          Protected bmi.BITMAPINFO, bmi2.BITMAPINFO, hDC.l, NewImageID, Mem, n, nn, bm.BITMAP, Temp1, Temp2
         
          Angle = Angle * #Pi / 180 ; On convertit en radian
          CosAngle.f = Cos(Angle)
          SinAngle.f = Sin(Angle)
         
          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
         
          bmi2\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
          bmi2\bmiHeader\biWidth = Int(bm\bmWidth * Abs(CosAngle) + bm\bmHeight * Abs(SinAngle) + 0.5)
          bmi2\bmiHeader\biHeight = Int(bm\bmHeight * Abs(CosAngle) + bm\bmWidth * Abs(SinAngle) + 0.5)
          bmi2\bmiHeader\biPlanes = 1
          bmi2\bmiHeader\biBitCount = 32
          bmi2\bmiHeader\biCompression = #BI_RGB
         
          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
                                        ReleaseDC_(0, hDC)
                              EndIf
                             
                              CX1 = (bm\bmWidth - 1) * 100 / 2
                              CY1 = (bm\bmHeight - 1) * 100 / 2
                              CX2 = (bmi2\bmiHeader\biWidth - 1) * 100 / 2
                              CY2 = (bmi2\bmiHeader\biHeight - 1) * 100 / 2
                             
                              Largeur = bm\bmHeight - 1
                              longueur = bm\bmWidth - 1
                             
                              CouleurNoir = 0
                             
                              *pMem2.RGBQUAD = Mem2
                              For nn = 0 To bmi2\bmiHeader\biHeight - 1
                                        y2 = nn * 100 - CY2
                                        CX1y2Sin = CX1  - y2 * SinAngle
                                        CY1y2Cos = CY1 + y2 * CosAngle
                                        For n = 0 To bmi2\bmiHeader\biWidth - 1
                                                  x2 = n * 100 - CX2
                                                  x1.f = Int(x2 * CosAngle + CX1y2Sin) / 100
                                                  y1.f = Int(x2 * SinAngle + CY1y2Cos) / 100
                                                 
                                                  IntX1 = Int(x1)
                                                  Inty1 = Int(y1)
                                                 
                                                  If x1 < 0 : PasX = IntX1 - 1 : Else : PasX = IntX1 + 1 : EndIf
                                                  If y1 < 0 : PasY = Inty1 - 1 : Else : PasY = Inty1 + 1 : EndIf
                                                 
                                                  If IntX1 < 0 Or IntX1 > longueur Or Inty1 < 0 Or Inty1 > Largeur
                                                            *c00.RGBQUAD = @CouleurNoir
                                                  Else
                                                            *c00 = Mem + (IntX1 + Inty1 * bm\bmWidth) * 4
                                                  EndIf
                                                  If PasX < 0 Or PasX > longueur Or Inty1 < 0 Or Inty1 > Largeur
                                                            *c10.RGBQUAD = @CouleurNoir
                                                  Else
                                                            *c10 = Mem + (PasX + Inty1 * bm\bmWidth) * 4
                                                  EndIf
                                                  If IntX1 < 0 Or IntX1 > longueur Or PasY < 0 Or PasY > Largeur
                                                            *c01.RGBQUAD = @CouleurNoir
                                                  Else
                                                            *c01 = Mem + (IntX1 + PasY * bm\bmWidth) * 4
                                                  EndIf
                                                  If PasX < 0 Or PasX > longueur Or PasY < 0 Or PasY > Largeur
                                                            *c11.RGBQUAD = @Couleur
                                                  Else
                                                            *c11 = Mem + (PasX + PasY * bm\bmWidth) * 4
                                                  EndIf
                                                 
                                                  fx.f = Abs(x1 - IntX1)
                                                  fy.f = Abs(y1 - Inty1)
                                                  f00.f = (1 - fx) * (1 - fy)
                                                  f01.f = (1 - fx) * fy
                                                  f10.f = fx * (1 - fy)
                                                  f11.f = fx * fy
                                                 
                                                  !XOR eax,eax
                                                  ; *pMem2\rgbRed = Int(*c00\rgbRed * f00 + *c10\rgbRed * f10 + *c01\rgbRed * f01 + *c11\rgbRed * f11)
                                                  !MOV    ebp,dword [esp+232]
                                                  !MOV  al,byte [ebp+2]
                                                  !MOV    dword [esp-4],eax
                                                  !FILD   dword [esp-4]
                                                  !FMUL   dword [esp+260]
                                                  !MOV    ebp,dword [esp+236]
                                                  !MOV  al,byte [ebp+2]
                                                  !MOV    dword [esp-4],eax
                                                  !FILD   dword [esp-4]
                                                  !FMUL   dword [esp+268]
                                                  !FADDP  ST1,ST0
                                                  !MOV    ebp,dword [esp+240]
                                                  !MOV  al,byte [ebp+2]
                                                  !MOV    dword [esp-4],eax
                                                  !FILD   dword [esp-4]
                                                  !FMUL   dword [esp+264]
                                                  !FADDP  ST1,ST0
                                                  !MOV    ebp,dword [esp+244]
                                                  !MOV  al,byte [ebp+2]
                                                  !MOV    dword [esp-4],eax
                                                  !FILD   dword [esp-4]
                                                  !FMUL   dword [esp+272]
                                                  !FADDP  ST1,ST0
                                                  !SUB    esp,4
                                                  !FSTP   dword [esp]
                                                  !CALL  _PB_Int@4
                                                  !MOV    ebp,dword [esp+192-4]
                                                  !MOV    byte [ebp+2],al
                                                  ; *pMem2\rgbGreen = Int(*c00\rgbGreen * f00 + *c10\rgbGreen * f10 + *c01\rgbGreen * f01 + *c11\rgbGreen * f11)
                                                  !MOV    ebp,dword [esp+232]
                                                  !MOV  al,byte [ebp+1]
                                                  !MOV    dword [esp-4],eax
                                                  !FILD   dword [esp-4]
                                                  !FMUL   dword [esp+260]
                                                  !MOV    ebp,dword [esp+236]
                                                  !MOV  al,byte [ebp+1]
                                                  !MOV    dword [esp-4],eax
                                                  !FILD   dword [esp-4]
                                                  !FMUL   dword [esp+268]
                                                  !FADDP  ST1,ST0
                                                  !MOV    ebp,dword [esp+240]
                                                  !MOV  al,byte [ebp+1]
                                                  !MOV    dword [esp-4],eax
                                                  !FILD   dword [esp-4]
                                                  !FMUL   dword [esp+264]
                                                  !FADDP  ST1,ST0
                                                  !MOV    ebp,dword [esp+244]
                                                  !MOV  al,byte [ebp+1]
                                                  !MOV    dword [esp-4],eax
                                                  !FILD   dword [esp-4]
                                                  !FMUL   dword [esp+272]
                                                  !FADDP  ST1,ST0
                                                  !SUB    esp,4
                                                  !FSTP   dword [esp]
                                                  !CALL  _PB_Int@4
                                                  !MOV    ebp,dword [esp+192-4]
                                                  !MOV    byte [ebp+1],al
                                                  ; *pMem2\rgbBlue = Int(*c00\rgbBlue * f00 + *c10\rgbBlue * f10 + *c01\rgbBlue * f01 + *c11\rgbBlue * f11)
                                                  !MOV    ebp,dword [esp+232]
                                                  !MOV  al,byte [ebp]
                                                  !MOV    dword [esp-4],eax
                                                  !FILD   dword [esp-4]
                                                  !FMUL   dword [esp+260]
                                                  !MOV    ebp,dword [esp+236]
                                                  !MOV  al,byte [ebp]
                                                  !MOV    dword [esp-4],eax
                                                  !FILD   dword [esp-4]
                                                  !FMUL   dword [esp+268]
                                                  !FADDP  ST1,ST0
                                                  !MOV    ebp,dword [esp+240]
                                                  !MOV  al,byte [ebp]
                                                  !MOV    dword [esp-4],eax
                                                  !FILD   dword [esp-4]
                                                  !FMUL   dword [esp+264]
                                                  !FADDP  ST1,ST0
                                                  !MOV    ebp,dword [esp+244]
                                                  !MOV  al,byte [ebp]
                                                  !MOV    dword [esp-4],eax
                                                  !FILD   dword [esp-4]
                                                  !FMUL   dword [esp+272]
                                                  !FADDP  ST1,ST0
                                                  !SUB    esp,4
                                                  !FSTP   dword [esp]
                                                  !CALL  _PB_Int@4
                                                  !MOV    ebp,dword [esp+192-4]
                                                  !MOV    byte [ebp],al
                                                 
                                                  *pMem2 + 4
                                        Next
                              Next
                             
                              ; On crée la nouvelle image
                              NewImageID = CreateImage(#PB_Any, bmi2\bmiHeader\biWidth, bmi2\bmiHeader\biHeight)
                              hDC = CreateCompatibleDC_(GetDC_(ImageID()))
                              If hDC
                                        SetDIBits_(hDC, ImageID(), 0, bmi2\bmiHeader\biHeight, Mem2, @bmi2, #DIB_RGB_COLORS) ; on envoie la liste dans l'image
                                        ReleaseDC_(0, hDC)
                              EndIf
                             
                              FreeMemory(Mem2)
                    EndIf
                    FreeMemory(Mem)
          EndIf
         
          ProcedureReturn NewImageID
EndProcedure



;-----------------------------------------
;- Test de rapidité

ImageOrigine = CreateImage(0, 1000, 1000)
StartDrawing(ImageOutput())
For n = 0 To 999
          For nn = 0 To 999
                    Plot(n, nn, Random($FFFFFF))
          Next
Next
StopDrawing()
Dim Liste(ImageWidth() - 1, ImageHeight() - 1)

#NbTest = 2

Temps1 = ElapsedMilliseconds()

For n = 1 To #NbTest
          ImageModifiee = RotateImageEx2(ImageOrigine, 30)
Next

Temps2 = ElapsedMilliseconds()

Vitesse = (Temps2 - Temps1) / #NbTest
NbPixel = ImageHeight() * ImageWidth()

MessageRequester("Temps", Str(Vitesse) + " ms" + Chr(10) + "Image de " + Str(ImageWidth()) + " * " + Str(ImageHeight()) + " pixels" + Chr(10) + "Nb pixels traités = " + Str(NbPixel), 0)


;-----------------------------------------
;- Test  d'affichage d'image avec rotation
; On dessine une image
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()

ImageRotation = RotateImageEx2(UseImage(ImageNormale), 30)

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

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

TextGadget(#PB_Any, 10, 135, 100, 15, "Rotation de 30")
ImageGadget(#PB_Any, 10, 150, 0, 0, UseImage(ImageRotation))

Repeat
          Event = WaitWindowEvent()
         
Until Event = #PB_EventCloseWindow

End

_________________
fanghua bu ru yuan er


Haut
 Profil  
 
 Sujet du message:
MessagePosté: Lun 14/Fév/2005 20:42 
Hors ligne
Avatar de l’utilisateur

Inscription: Mer 28/Jan/2004 20:58
Messages: 4311
Localisation: Clermont ferrand OU Olsztyn
marrant, on a pratiquement fais la même chose :wink: sauf que tu as ajouté l'ASM et pour l'idée de la structure, pas bête :D

je regarde ;)

_________________
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)]


Haut
 Profil  
 
 Sujet du message:
MessagePosté: Lun 14/Fév/2005 21:32 
Hors ligne
Avatar de l’utilisateur

Inscription: Mer 28/Jan/2004 20:58
Messages: 4311
Localisation: Clermont ferrand OU Olsztyn
Bon, j'ai continuer d'optimiser mon code

je suis à 1.2 seconde pour une image de 1000*1000 avec une rotation de 30°

Pour info Erix14, tu es à 1.5s chez moi. En faisant bénificer ton code de mes changements, tu es a 1.3 seconde. visiblement, les pointeurs sont pas une bonne solution



voici mon code :

Code:
#Pi.f = 3.14159265

ProcedureDLL.l RotateImageEx2(ImageID, Angle.f) ; Rotation d'une image d'un angle en °
  Protected bmi.BITMAPINFO, bmi2.BITMAPINFO, Hdc.l, NewImageID, Mem, n, nn, bm.BITMAP, Temp1, Temp2, Temp3.f, Temp4.f, Temp5.f, Temp6.f
 
  Angle = Angle * #Pi / 180 ; On convertit en radian
 
  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
  bmi\bmiHeader\biCompression = #BI_RGB
 
  bmi2\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
  bmi2\bmiHeader\biWidth = bm\bmWidth * Abs(Cos(Angle)) + bm\bmHeight * Abs(Sin(Angle))
  bmi2\bmiHeader\biHeight = bm\bmHeight * Abs(Cos(Angle)) + bm\bmWidth * Abs(Sin(Angle))
  bmi2\bmiHeader\biPlanes = 1
  bmi2\bmiHeader\biBitCount = 32
  bmi2\bmiHeader\biCompression = #BI_RGB
 
  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
        ReleaseDC_(0, Hdc)
      EndIf
     
      Temp1 = bm\bmWidth - 1
      Temp2 = bm\bmHeight - 1
      Temp3.f = Cos(Angle)
      Temp4.f = Sin(Angle)
      CX1 = Temp1 * 100 / 2
      CY1 = Temp2 * 100 / 2
      CX2 = (bmi2\bmiHeader\biWidth - 1) * 100 / 2
      CY2 = (bmi2\bmiHeader\biHeight - 1) * 100 / 2
     
      For n = 0 To bmi2\bmiHeader\biWidth - 1
        x1b.l = n * 100 - CX2
        Temp5 = CX1 + x1b * Temp3
        Temp6 = CY1 + x1b * Temp4
        For nn = 0 To bmi2\bmiHeader\biHeight - 1
          y1b.l = nn * 100 - CY2
         
          x1.f = (Temp5 - y1b * Temp4) / 100
          y1.f = (Temp6 + y1b * Temp3) / 100
         
          x2.l = x1
          y2.l = y1
         
          fx.f = Abs(x1 - x2)
          fy.f = Abs(y1 - y2)
          f00.f = (1 - fx) * (1 - fy)
          f01.f = (1 - fx) * fy
          f10.f = fx * (1 - fy)
          f11.f = fx * fy
         
          If x1 < x2 : x2b = x2 - 1 : Else : x2b = x2 + 1 : EndIf
          If y1 < y2 : y2b = y2 - 1 : Else : y2b = y2 + 1 : EndIf
         
          If x2 < 0 Or x2 > Temp1
            c00 = 0
            c01 = 0
          Else
            If y2 < 0 Or y2 > Temp2
              c00 = 0
            Else
              c00 = PeekL(Mem + (x2 + y2 * bm\bmWidth) * 4)
            EndIf
            If y2b < 0 Or y2b > Temp2
              c01 = 0
            Else
              c01 = PeekL(Mem + (x2 + y2b * bm\bmWidth) * 4)
            EndIf
          EndIf
          If x2b < 0 Or x2b > Temp1
            c10 = 0
            c11 = 0
          Else
            If y2 < 0 Or y2 > Temp2
              c10 = 0
            Else
              c10 = PeekL(Mem + (x2b + y2 * bm\bmWidth) * 4)
            EndIf
            If  y2b < 0 Or y2b > Temp2
              c11 = 0
            Else
              c11 = PeekL(Mem + (x2b + y2b * bm\bmWidth) * 4)
            EndIf
          EndIf
         
          r = Red(c00) * f00 + Red(c10) * f10 + Red(c01) * f01 + Red(c11) * f11
          g = Green(c00) * f00 + Green(c10) * f10 + Green(c01) * f01 + Green(c11) * f11
          b = Blue(c00) * f00 + Blue(c10) * f10 + Blue(c01) * f01 + Blue(c11) * f11
         
          PokeL(Mem2 + (n + nn * bmi2\bmiHeader\biWidth) * 4, RGB(r, g, b))
         
        Next
      Next
     
      ; On crée la nouvelle image
      NewImageID = CreateImage(#PB_Any, bmi2\bmiHeader\biWidth, bmi2\bmiHeader\biHeight)
      Hdc = CreateCompatibleDC_(GetDC_(ImageID()))
      If Hdc
        SetDIBits_(Hdc, ImageID(), 0, bmi2\bmiHeader\biHeight, Mem2, @bmi2, #DIB_RGB_COLORS) ; on envoie la liste dans l'image
        ReleaseDC_(0, Hdc)
      EndIf
     
      FreeMemory(Mem2)
    EndIf
    FreeMemory(Mem)
  EndIf
 
  ProcedureReturn NewImageID
EndProcedure


;-----------------------------------------
;- Test de rapidité

ImageOrigine = CreateImage(0, 1000, 1000)
StartDrawing(ImageOutput())
  For n = 0 To 999
    For nn = 0 To 999
      Plot(n, nn, Random($FFFFFF))
    Next
  Next
StopDrawing()
Dim Liste(ImageWidth() - 1, ImageHeight() - 1)

#NbTest = 2

Temps1 = ElapsedMilliseconds()

For n = 1 To #NbTest
  ImageModifiee = RotateImageEx2(ImageOrigine, 30)
Next

Temps2 = ElapsedMilliseconds()

Vitesse = (Temps2 - Temps1) / #NbTest
NbPixel = ImageHeight() * ImageWidth()

MessageRequester("Temps", Str(Vitesse) + " ms" + Chr(10) + "Image de " + Str(ImageWidth()) + " * " + Str(ImageHeight()) + " pixels" + Chr(10) + "Nb pixels traités = " + Str(NbPixel), 0)


;-----------------------------------------
;- Test  d'affichage d'image avec rotation
; On dessine une image
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()

ImageRotation = RotateImageEx2(UseImage(ImageNormale), 30)

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

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

TextGadget(#PB_Any, 10, 135, 100, 15, "Rotation de 30")
ImageGadget(#PB_Any, 10, 150, 0, 0, UseImage(ImageRotation))

Repeat
  Event = WaitWindowEvent()
 
Until Event = #PB_EventCloseWindow

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)]


Haut
 Profil  
 
 Sujet du message:
MessagePosté: Lun 14/Fév/2005 22:44 
Hors ligne
Avatar de l’utilisateur

Inscription: Ven 11/Fév/2005 17:34
Messages: 3063
Localisation: Arras, France
On peut jouer? :D

_________________
The shooting crew ~> http://www.shootingcrew.com
Bobble Puzzle ~> http://djes.free.fr


Haut
 Profil  
 
Afficher les messages postés depuis:  Trier par  
Poster un nouveau sujet Répondre au sujet  [ 111 messages ]  Aller à la page Précédente  1, 2, 3, 4, 5, 6 ... 8  Suivante

Heures au format UTC + 1 heure


Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 1 invité


Vous ne pouvez pas poster de nouveaux sujets
Vous ne pouvez pas répondre aux sujets
Vous ne pouvez pas éditer vos messages
Vous ne pouvez pas supprimer vos messages

Rechercher:
Aller à:  
cron

 


Powered by phpBB © 2008 phpBB Group | Traduction par: phpBB-fr.com
subSilver+ theme by Canver Software, sponsor Sanal Modifiye