Librairie Effect

Vous avez développé un logiciel en PureBasic et vous souhaitez le faire connaitre ?
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

Le dernier code du soldat 324 ms , de mieux en mieux :)

pour l'instant , the winner is "le dernier code de djes 257 ms"
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

c'est quoi ton Processeur ?
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)]
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

P4 2,66 512 Mo de Ram
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

bon, j'ai repris une idée du code de djes qui m'avait échappé

je suis à 766ms

j'ai essayé les autres astuces de djes mais je suis toujours plus lent avec :(
Faudrait que je test sur mon XP2000+, les optimisation sont surement pas les meme que mon 900Athlon et je pense que je vais obtenir des résultats différents

Code : Tout sélectionner

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
  
  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
  bmi\bmiHeader\biCompression = #BI_RGB
  
  bmi2\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
  bmi2\bmiHeader\biWidth = bm\bmWidth * Abs(Cos) + bm\bmHeight * Abs(Sin)
  bmi2\bmiHeader\biHeight = bm\bmHeight * Abs(Cos) + bm\bmWidth * Abs(Sin)
  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
      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
            
            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(Mem2Temp, RGB(r, g, b))
          
          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)
      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 = 4

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)]
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

Bon, je change de sujet, je reviens à la rotation simple de 0, 90, 180, 270°

j'ai testé avec l'APi PlgBlt_(
cette API est dispo uniquement sur 2000 et XP

Et bien vous allez rire, je suis plus rapide sans :D 2 fois plus rapide même

Code : Tout sélectionner

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
    X = bm\bmWidth
    Y = bm\bmHeight
    
    Mem = AllocateMemory(6 * 4)
    If Mem
      
      ; On récupère l'image dans un espace mémoire
      Hdc = GetDC_(0) ; CreateCompatibleDC_(GetDC_(ImageID))
      If Hdc
        HCDC = CreateCompatibleDC_(Hdc) 
        SelectObject_(HCDC, ImageID)
        
        ; On fait la rotation de l'image de 90, 180 ou 270°
        Select Angle
          Case 90 ; rotation de 90°
            ; Point haut gauche
            PokeL(Mem, bm\bmHeight)
            ; PokeL(Mem + 4, 0)
            ; Point haut droit
            PokeL(Mem + 8, bm\bmHeight)
            PokeL(Mem + 12, bm\bmWidth)
            ; Point bas gauche
            ; PokeL(Mem+ 16, 0)
            ; PokeL(Mem + 20, 0)
            
            Temp1 = bm\bmHeight : bm\bmHeight = bm\bmWidth : bm\bmWidth = Temp1
            NewImageID = CreateImage(#PB_Any, bm\bmWidth, bm\bmHeight)
            
          Case 180
            ; Point haut gauche
            PokeL(Mem, bm\bmWidth)
            PokeL(Mem + 4, bm\bmHeight)
            ; Point haut droit
            ; PokeL(Mem + 8,0)
            PokeL(Mem + 12, bm\bmHeight)
            ; Point bas gauche
            PokeL(Mem+ 16, bm\bmWidth)
            ; PokeL(Mem + 20, 0)
            
            NewImageID = CreateImage(#PB_Any, bm\bmWidth, bm\bmHeight)
            
          Case 270
            ; Point haut gauche
            ; PokeL(Mem, 0)
            PokeL(Mem + 4, bm\bmWidth)
            ; Point haut droit
            ; PokeL(Mem + 8, 0t)
            ; PokeL(Mem + 12, 0)
            ; Point bas gauche
            PokeL(Mem+ 16, bm\bmHeight)
            PokeL(Mem + 20, bm\bmWidth)
            
            Temp1 = bm\bmHeight : bm\bmHeight = bm\bmWidth : bm\bmWidth = Temp1
            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
        HCDC2 = CreateCompatibleDC_(Hdc) 
        SelectObject_(HCDC2, UseImage(NewImageID))
        If HCDC2
          PlgBlt_(HCDC2, Mem, HCDC, 0, 0, bm\bmHeight, bm\bmWidth, 0, 0, 0)
          DeleteDC_(HCDC2)
        EndIf
        DeleteDC_(HCDC)
        ReleaseDC_(0, Hdc)
      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 = 4

Temps1 = ElapsedMilliseconds()

For n = 1 To #NbTest
  ImageModifiee = RotateImage2(ImageOrigine, 90)
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 = RotateImage2(UseImage(ImageNormale), 90)

; 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)]
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Message par djes »

Héhé! En même temps si ils savaient (ou voulaient) optimiser chez Microsoft ça se saurait! Mais ça n'est pas leur but, leur but c'est que ça marche, quel que soit le moyen...

Pour ta routine, y'a aussi moyen de charger par gros paquets (multiples de 8 ou 16?) plutôt qu'à l'unité; je ne me souviens plus des instructions mais je sais que c'est possible!
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

Pour ta routine, y'a aussi moyen de charger par gros paquets (multiples de 8 ou 16?) plutôt qu'à l'unité; je ne me souviens plus des instructions mais je sais que c'est possible!
pas saisi ou tu veux utiliser ceci ?

Sur mon XP2000+ ton code et le mien (le tout dernier) sont aussi rapide.
Je vais combiné les codes dessus pour voir si j'obtiens un gain supplémentaire (normalement oui)

Bon, sinon, j'ai optimiser encore un poil la rotation de 90, 180, 270° et la symétrie d'image
Et j'ai mis à jour la lib sur mon site.
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

Message par djes »

Le Soldat Inconnu a écrit :
Pour ta routine, y'a aussi moyen de charger par gros paquets (multiples de 8 ou 16?) plutôt qu'à l'unité; je ne me souviens plus des instructions mais je sais que c'est possible!
pas saisi ou tu veux utiliser ceci ?

Sur mon XP2000+ ton code et le mien (le tout dernier) sont aussi rapide.
Je vais combiné les codes dessus pour voir si j'obtiens un gain supplémentaire (normalement oui)

Bon, sinon, j'ai optimiser encore un poil la rotation de 90, 180, 270° et la symétrie d'image
Et j'ai mis à jour la lib sur mon site.
Je parlais des routines de symétrie/rotation 90, 180, 270. Pour la rotation, effectivement, l'utilisation des entiers ne s'impose pas, voire est plus lente! Je vais pour ma part faire la partie asm pour virer les CALL (fonctions pure poke, peek, rgb)...
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Message par djes »

Bon voilà c'est fait! Je crois que je vais en rester là!

Code : Tout sélectionner

#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
 
  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
  bmi\bmiHeader\biCompression = #BI_RGB
 
  bmi2\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
  bmi2\bmiHeader\biWidth = bm\bmWidth * Abs(Cos) + bm\bmHeight * Abs(Sin)
  bmi2\bmiHeader\biHeight = bm\bmHeight * Abs(Cos) + bm\bmWidth * Abs(Sin)
  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
      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)/2
        Temp2.f = (CY1 + y1b * Cos)/2
        For x1b = -CX2/2 To (CX2*2-CX2)/2
         
          x1.f = Temp1 + x1b * Cos  ;on pourrait virer ces mult avec des tables mais le gain n'est pas évident
          y1.f = Temp2 + x1b * Sin
         
          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 
            f10.f = 1 - fy
            f01.f = f00 * fy
            f00 * f10
            f10 * fx
            f11.f = fx * fy
         
            MemTemp = (x2 + y2 * bm\bmWidth) * 4
            DefType.l c00, c01, c11, c10
           
            If x2 >= 0 And x2 <= CX1
              If y2 >= 0 And y2 <= CY1
                MOV eax,mem
                ADD eax,memtemp
                MOV eax,[eax]
                MOV c00,eax
                ;c00 = PeekL(Mem + MemTemp)
              Else
                c00 = 0
              EndIf
              If y2b >= 0 And y2b <= CY1
                MOV eax,mem01
                ADD eax,memtemp
                MOV eax,[eax]
                MOV c01,eax
                ;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
                MOV eax,mem10
                ADD eax,memtemp
                MOV eax,[eax]
                MOV c10,eax
                ;c10 = PeekL(Mem10 + MemTemp)
              Else
                c10 = 0
              EndIf
              If  y2b >= 0 And y2b <= CY1
                MOV eax,mem11
                ADD eax,memtemp
                MOV eax,[eax]
                MOV c11,eax
                ;c11 = PeekL(Mem11 + MemTemp)
              Else
                c11 = 0
              EndIf
            Else
              c10 = 0
              c11 = 0
            EndIf
    
            DefType.l r1,r2,r3,r4 , g1,g2,g3,g4 , b1,b2,b3,b4

            MOV eax,c00
            MOV ebx,eax
            MOV ecx,eax

            AND eax,$FF
            MOV r1,eax
            AND ebx,$FF00
            MOV g1,ebx
            AND ecx,$FF0000
            MOV b1,ecx

            MOV eax,c10
            MOV ebx,eax
            MOV ecx,eax

            AND eax,$FF
            MOV r2,eax
            AND ebx,$FF00
            MOV g2,ebx
            AND ecx,$FF0000
            MOV b2,ecx

            MOV eax,c01
            MOV ebx,eax
            MOV ecx,eax

            AND eax,$FF
            MOV r3,eax
            AND ebx,$FF00
            MOV g3,ebx
            AND ecx,$FF0000
            MOV b3,ecx

            MOV eax,c11
            MOV ebx,eax
            MOV ecx,eax

            AND eax,$FF
            MOV r4,eax
            AND ebx,$FF00
            MOV g4,ebx
            AND ecx,$FF0000
            MOV b4,ecx
     
            r = r1 * f00 + r2 * f10 + r3 * f01 + r4 * f11   ;pure fait très bien tout ça
            g = g1 * f00 + g2 * f10 + g3 * f01 + g4 * f11 
            b = b1 * f00 + b2 * f10 + b3 * f01 + b4 * f11 
         
            MOV eax,r
            MOV ebx,g
            MOV ecx,b
            AND eax,$FF                                      ;toute l'astuce consiste à laisser les triplets à leur place et à les multiplier là. On évite ainsi les décalages
            AND ebx,$FF00
            AND ecx,$FF0000
            OR eax,ebx
            OR eax,ecx

            MOV ebx,Mem2Temp
            MOV [ebx],eax
         
          Else

            MOV ebx,Mem2Temp
            XOR eax,eax
            MOV [ebx],eax

          EndIf
         
          Mem2Temp + 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 = 4

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
; ExecutableFormat=
; EnableAsm
; DisableDebugger
; EOF
:)
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

je viens pratiquemet de faire la même 668 ms sur mon 900mhz, tu es a 640 ms :D

c'est génial

la différence, c'est que tu a zappé les décalages :wink:

Moi aussi je vais en rester la :D merci de votre colaboration, très cher 8)
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

Message par djes »

Le Soldat Inconnu a écrit :je viens pratiquemet de faire la même 668 ms sur mon 900mhz, tu es a 640 ms :D

c'est génial

la différence, c'est que tu a zappé les décalages :wink:

Moi aussi je vais en rester la :D merci de votre colaboration, très cher 8)
:D On s'est bien amusé :wink:

Quand tu veux!
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

Bon la nouvelle lib est sur le site ;)

j'ai fait bénéficié des astuces utilisés ci-dessus pour optimiser à toutes les fonction de la LIB

voici un récapitulatif des gains en pourcentage depuis le début de l'optimisation de la lib (test réalisé sur XP2000+)

GetImageBits, SetImageBits : 5%
ImageSymmetryH : 5%
ImageSymmetryV : 5%
RotateImage : 6%
RotateImageEx : 86%
ColorLuminosity : 28%
ColorContrast : 65%
ColorGrey : 60%
ColorRedIntensity : 50%
ColorGreenIntensity : 44%
ColorBlueIntensity : 50%
ColorTint : 30%
ColorLevel : 24%
ColorBlending : 30%
ColorAdd : 45%
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

Message par djes »

Pas mal tout ça :)
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Message par djes »

Je suis bête! J'avais oublié que les expressions dans les boucles for étaient interprétées à chaque fois! J'ai donc tout mis dans deux variables séparées. J'ai aussi changé la priorité de notre programme pour que les tests ne soient pas interrompus par d'autres tâches. On ne gagne pas beaucoup mais ça m'empêchait de dormir :lol:

Code : Tout sélectionner

#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
 
  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
  bmi\bmiHeader\biCompression = #BI_RGB
 
  bmi2\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
  bmi2\bmiHeader\biWidth = bm\bmWidth * Abs(Cos) + bm\bmHeight * Abs(Sin)
  bmi2\bmiHeader\biHeight = bm\bmHeight * Abs(Cos) + bm\bmWidth * Abs(Sin)
  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
      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

      deb=-CX2/2 : fin=(CX2*2-CX2)/2
     
      For nn = 0 To CY2
        y1b.l = nn * 2 - CY2
        Temp1.f = (CX1 - y1b * Sin)/2
        Temp2.f = (CY1 + y1b * Cos)/2
        For x1b = deb To fin
         
          x1.f = Temp1 + x1b * Cos  ;on pourrait virer ces mult avec des tables mais le gain n'est pas évident
          y1.f = Temp2 + x1b * Sin
         
          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
            f10.f = 1 - fy
            f01.f = f00 * fy
            f00 * f10
            f10 * fx
            f11.f = fx * fy
         
            MemTemp = (x2 + y2 * bm\bmWidth) * 4
            DefType.l c00, c01, c11, c10
           
            If x2 >= 0 And x2 <= CX1
              If y2 >= 0 And y2 <= CY1
                MOV eax,mem
                ADD eax,memtemp
                MOV eax,[eax]
                MOV c00,eax
                ;c00 = PeekL(Mem + MemTemp)
              Else
                c00 = 0
              EndIf
              If y2b >= 0 And y2b <= CY1
                MOV eax,mem01
                ADD eax,memtemp
                MOV eax,[eax]
                MOV c01,eax
                ;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
                MOV eax,mem10
                ADD eax,memtemp
                MOV eax,[eax]
                MOV c10,eax
                ;c10 = PeekL(Mem10 + MemTemp)
              Else
                c10 = 0
              EndIf
              If  y2b >= 0 And y2b <= CY1
                MOV eax,mem11
                ADD eax,memtemp
                MOV eax,[eax]
                MOV c11,eax
                ;c11 = PeekL(Mem11 + MemTemp)
              Else
                c11 = 0
              EndIf
            Else
              c10 = 0
              c11 = 0
            EndIf
   
            DefType.l r1,r2,r3,r4 , g1,g2,g3,g4 , b1,b2,b3,b4

            MOV eax,c00
            MOV ebx,eax
            MOV ecx,eax

            AND eax,$FF
            MOV r1,eax
            AND ebx,$FF00
            MOV g1,ebx
            AND ecx,$FF0000
            MOV b1,ecx

            MOV eax,c10
            MOV ebx,eax
            MOV ecx,eax

            AND eax,$FF
            MOV r2,eax
            AND ebx,$FF00
            MOV g2,ebx
            AND ecx,$FF0000
            MOV b2,ecx

            MOV eax,c01
            MOV ebx,eax
            MOV ecx,eax

            AND eax,$FF
            MOV r3,eax
            AND ebx,$FF00
            MOV g3,ebx
            AND ecx,$FF0000
            MOV b3,ecx

            MOV eax,c11
            MOV ebx,eax
            MOV ecx,eax

            AND eax,$FF
            MOV r4,eax
            AND ebx,$FF00
            MOV g4,ebx
            AND ecx,$FF0000
            MOV b4,ecx
     
            r = r1 * f00 + r2 * f10 + r3 * f01 + r4 * f11   ;pure fait très bien tout ça
            g = g1 * f00 + g2 * f10 + g3 * f01 + g4 * f11
            b = b1 * f00 + b2 * f10 + b3 * f01 + b4 * f11
         
            MOV eax,r
            MOV ebx,g
            MOV ecx,b
            AND eax,$FF                                      ;toute l'astuce consiste à laisser les triplets à leur place et à les multiplier là. On évite ainsi les décalages
            AND ebx,$FF00
            AND ecx,$FF0000
            OR eax,ebx
            OR eax,ecx

            MOV ebx,Mem2Temp
            MOV [ebx],eax
         
          Else

            MOV ebx,Mem2Temp
            XOR eax,eax
            MOV [ebx],eax

          EndIf
         
          Mem2Temp + 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é

SetPriorityClass_(GetCurrentProcess_(),#REALTIME_PRIORITY_CLASS)

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 = 4

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)

SetPriorityClass_(GetCurrentProcess_(),#NORMAL_PRIORITY_CLASS)

; 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
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message par Flype »

j'ai voulu voir ce que votre routine donne en temps réel...
voici le bout de code qui montre que ca tourne bien...

et puis je me demandais si on pouvait définir la couleur de fond de l'image tournée de la facon suivante ( mais c'est plus lent car ca ne filtre plus les points en dehors de l'image pour remplir tout le rectangle ) :

Code : Tout sélectionner

#Pi.f=3.14159265 

ProcedureDLL.l RotateImageEx2(ImageID, Angle.f, CouleurFond)
  
  Protected bmi.BITMAPINFO, bmi2.BITMAPINFO, hdc.l, NewImageID, Mem, n, nn, bm.BITMAP 
  
  Angle = Angle * #Pi / 180
  
  Cos.f = Cos(Angle) 
  Sin.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 = bm\bmWidth * Abs(Cos) + bm\bmHeight * Abs(Sin) 
  bmi2\bmiHeader\biHeight = bm\bmHeight * Abs(Cos) + bm\bmWidth * Abs(Sin) 
  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)
        ReleaseDC_(0, 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 
      
      deb=-CX2/2 : fin=(CX2*2-CX2)/2 
      
      For nn = 0 To CY2 
        
        y1b.l = nn * 2 - CY2 
        Temp1.f = (CX1 - y1b * Sin)/2 
        Temp2.f = (CY1 + y1b * Cos)/2 
        For x1b = deb To fin 
          
          x1.f = Temp1 + x1b * Cos
          y1.f = Temp2 + x1b * Sin 
          
          x2.l = x1 
          y2.l = y1 
          
          If x1 < x2 
            DEC x2 
          EndIf 
          If y1 < y2 
            DEC y2 
          EndIf 
          
          x2b = x2 + 1 
          y2b = y2 + 1 
          
            fx.f = x1 - x2 
            fy.f = y1 - y2 
            f00.f = 1 - fx 
            f10.f = 1 - fy 
            f01.f = f00 * fy 
            f00 * f10 
            f10 * fx 
            f11.f = fx * fy 
            
            MemTemp = (x2 + y2 * bm\bmWidth) * 4 
            DefType.l c00, c01, c11, c10 
            If x2 >= 0 And x2 <= CX1 
              If y2 >= 0 And y2 <= CY1 
                MOV Eax,Mem 
                ADD Eax,MemTemp 
                MOV Eax,[Eax] 
                MOV c00,Eax 
              Else 
                c00 = CouleurFond
              EndIf 
              If y2b >= 0 And y2b <= CY1 
                MOV Eax,Mem01 
                ADD Eax,MemTemp 
                MOV Eax,[Eax] 
                MOV c01,Eax 
              Else 
                c01 = CouleurFond
              EndIf 
            Else 
              c00 = CouleurFond
              c01 = CouleurFond
            EndIf 
            If x2b >= 0 And x2b <= CX1 
              If y2 >= 0 And y2 <= CY1 
                MOV Eax,Mem10 
                ADD Eax,MemTemp 
                MOV Eax,[Eax] 
                MOV c10,Eax 
              Else 
                c10 = CouleurFond
              EndIf 
              If  y2b >= 0 And y2b <= CY1 
                MOV Eax,Mem11 
                ADD Eax,MemTemp 
                MOV Eax,[Eax] 
                MOV c11,Eax 
              Else 
                c11 = CouleurFond
              EndIf 
            Else 
              c10 = CouleurFond
              c11 = CouleurFond
            EndIf 
            
            DefType.l r1,r2,r3,r4 , g1,g2,g3,g4 , b1,b2,b3,b4 
            
            MOV Eax,c00 
            MOV Ebx,Eax 
            MOV Ecx,Eax 
            
            And Eax,$FF 
            MOV r1,Eax 
            And Ebx,$FF00 
            MOV g1,Ebx 
            And Ecx,$FF0000 
            MOV b1,Ecx 
            
            MOV Eax,c10 
            MOV Ebx,Eax 
            MOV Ecx,Eax 
            
            And Eax,$FF 
            MOV r2,Eax 
            And Ebx,$FF00 
            MOV g2,Ebx 
            And Ecx,$FF0000 
            MOV b2,Ecx 
            
            MOV Eax,c01 
            MOV Ebx,Eax 
            MOV Ecx,Eax 
            
            And Eax,$FF 
            MOV r3,Eax 
            And Ebx,$FF00 
            MOV g3,Ebx 
            And Ecx,$FF0000 
            MOV b3,Ecx 
            
            MOV Eax,c11 
            MOV Ebx,Eax 
            MOV Ecx,Eax 
            
            And Eax,$FF 
            MOV r4,Eax 
            And Ebx,$FF00 
            MOV g4,Ebx 
            And Ecx,$FF0000 
            MOV b4,Ecx 
            
            r = r1 * f00 + r2 * f10 + r3 * f01 + r4 * f11
            g = g1 * f00 + g2 * f10 + g3 * f01 + g4 * f11 
            b = b1 * f00 + b2 * f10 + b3 * f01 + b4 * f11 
            
            MOV Eax,r 
            MOV Ebx,g 
            MOV Ecx,b 
            And Eax,$FF
            And Ebx,$FF00 
            And Ecx,$FF0000 
            Or Eax,Ebx 
            Or Eax,Ecx 
            
            MOV Ebx,Mem2Temp 
            MOV [Ebx],Eax 
            
          Mem2Temp + 4 
          
        Next 
      Next 
      
      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 

CreateImage(0, 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() 

OpenWindow(0, 0, 0, 250, 300, #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget, "Effect - Rotation d'image")
CreateGadgetList(WindowID())
TextGadget(0, 10, 10, 100, 15, "Image normale") 
ImageGadget(1, 10, 25, 0, 0, UseImage(0)) 
TextGadget(2, 10, 135, 200, 15, "Image en rotation") 
ImageGadget(3, 10, 150, 0, 0, 0) 

CouleurFond = $AAFFAA

SetTimer_(WindowID(),0,1,0)

Repeat 
  Select WaitWindowEvent()
    Case #WM_CLOSE : Break
    Case #WM_TIMER
      If Image
        FreeImage(Image)
      EndIf
      Angle.f + 0.666666
      If Angle > 360.0
        Angle = 0
      EndIf
      Image.l = RotateImageEx2(UseImage(0),Angle,CouleurFond)
      ResizeGadget(3,0,WindowHeight()-ImageHeight(),-1,-1)
      SetGadgetState(3,UseImage(Image))
  EndSelect
ForEver

KillTimer_(WindowID(),0)
Image
Répondre