rotation verticale et horizontale d'une image

Programmation d'applications complexes
manababel
Messages : 136
Inscription : jeu. 14/mai/2020 7:40

rotation verticale et horizontale d'une image

Message par manababel »

À la base ses programmes étaient destinés au forum ASM, mais le gain obtenu est trop insignifiant.
Purebasic fait très bien le travail.

L'image cible doit être différente de la source.

Code : Tout sélectionner

EnableExplicit

; charge une image et la convertie en 32bit
;-------------------------------------------------------------------
Procedure load_image(nom,file$)
  Protected source_p , cible_p , s.q
  Protected lg.q , ht.q , taille.q , depth.q
 
  LoadImage(nom,file$)
  If Not IsImage(nom) : ProcedureReturn 0 : EndIf
   
  StartDrawing(ImageOutput(nom))
  source_p = DrawingBuffer()
  ht = ImageHeight(nom)
  lg = ImageWidth(nom)
  Depth=OutputDepth()
  StopDrawing()
 
  If Depth=24
    taille=lg*ht
    cible_p=AllocateMemory(taille*4)
    Dim save.q(4)
    s=@save()
    EnableASM
      !mov rax,[p.v_s]
      !mov [rax],rcx
      !mov [rax+8],rdx
      !mov [rax+16],r8
      !mov rcx,[p.v_source_p]
      !mov rdx,[p.v_cible_p]
      !mov r8,[p.v_taille]
      !sub r8,1 ; <---------------- ????
      !copy_boucle24:
        !mov eax,[rcx]     
        !mov [rdx],eax
        !add rcx,3
        !add rdx,4
        !dec r8
       !jnz copy_boucle24
      !mov rax,[p.v_s]
      !mov rcx,[rax]
      !mov rdx, [rax+8]
      !mov r8,[rax+16]
    DisableASM
    FreeArray(save())
   
    FreeImage(nom) ; supprime l'image 24bits
    CreateImage(nom,lg,ht,32)
    StartDrawing(ImageOutput(nom))
    source_p = DrawingBuffer()
    StopDrawing()
    CopyMemory( cible_p , source_p , taille*4 )
    FreeMemory(cible_p)
  EndIf
  ProcedureReturn 1
EndProcedure




; partie du programme à modifier pour adapter se programme au votre
; convertie les "IDs" des images en pointer d'adresse
; test si les images sont en 32bits et de la meme taille
;-------------------------------------------------------------------

Macro sp(source,cible)
  Protected Depth.q , lg.q , ht.q , lg1.q , ht1.q 
  Protected cible_p.q , source_p.q
 
  StartDrawing(ImageOutput(cible))
  cible_p = DrawingBuffer()
  ht1 = ImageHeight(cible)
  lg1 = ImageWidth(cible)
  Depth=OutputDepth()
  StopDrawing()
  If depth<>32 : ProcedureReturn : EndIf
 
  StartDrawing(ImageOutput(source))
  source_p = DrawingBuffer()
  ht = ImageHeight(source)
  lg = ImageWidth(source)
  Depth=OutputDepth()
  StopDrawing()
  If depth<>32 : ProcedureReturn : EndIf
 
  If lg<>lg1 Or ht<>ht1 : ProcedureReturn : EndIf
 
EndMacro

;-------------------------------------------------------------------
Procedure Filter_Rotate_Horizontal_pb(source,cible,pos)
  Protected taille.q , pos1.q , pos2.q
  sp(source,cible)
  
  If pos<0 Or pos>=ht : ProcedureReturn : EndIf
  
  taille=lg*(ht-pos)*4
  pos1=source_p+(pos*lg*4)
  pos2=cible_p
  CopyMemory(pos1,pos2,taille)
  
  taille=lg*pos*4
  pos1=source_p
  pos2=cible_p+(ht-pos)*lg*4
  CopyMemory(pos1,pos2,taille)
  
EndProcedure

;-------------------------------------------------------------------
UseJPEGImageDecoder()
UsePNGImageDecoder()
Global imgx=1200
Global imgy=800


If OpenWindow(0, 0, 0, imgx, imgy+16, "Rotation horizontale", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  Define source.q , cible.q , t.q , file$ , i , pos.q , mem_pos.q 
 
   file$ = OpenFileRequester("Image","","",0)
   source=10
   cible=20
   
   If Not Load_Image(source,file$) ; <- commande differente de "LOADIMAGE"
     MessageRequester("load_image","erreur de chargement",#PB_MessageRequester_Ok | #PB_MessageRequester_Error)
     End
   EndIf
   
   ScrollBarGadget(1, 0, 00, 1200, 16, 0, imgy, 1 )     
   ResizeImage(source,imgx,imgy,#PB_Image_Smooth)  
   CreateImage(cible,imgx,imgy,32) ; l'image doit entre en mode 32bits
   
   mem_pos=1
   Repeat 
     pos=GetGadgetState(1)
     If pos<>mem_pos
       pos=GetGadgetState(1)
       Filter_Rotate_Horizontal_pb(source,cible,pos)
       StartDrawing(WindowOutput(0))
       DrawImage(ImageID(cible),0,16)
       StopDrawing()
       mem_pos = pos
     EndIf
     
   Until WindowEvent() = #PB_Event_CloseWindow
EndIf



Code : Tout sélectionner

EnableExplicit

; charge une image et la convertie en 32bit
;-------------------------------------------------------------------
Procedure load_image(nom,file$)
  Protected source_p , cible_p , s.q
  Protected lg.q , ht.q , taille.q , depth.q
 
  LoadImage(nom,file$)
  If Not IsImage(nom) : ProcedureReturn 0 : EndIf
   
  StartDrawing(ImageOutput(nom))
  source_p = DrawingBuffer()
  ht = ImageHeight(nom)
  lg = ImageWidth(nom)
  Depth=OutputDepth()
  StopDrawing()
 
  If Depth=24
    taille=lg*ht
    cible_p=AllocateMemory(taille*4)
    Dim save.q(4)
    s=@save()
    EnableASM
      !mov rax,[p.v_s]
      !mov [rax],rcx
      !mov [rax+8],rdx
      !mov [rax+16],r8
      !mov rcx,[p.v_source_p]
      !mov rdx,[p.v_cible_p]
      !mov r8,[p.v_taille]
      !sub r8,1 ; <---------------- ????
      !copy_boucle24:
        !mov eax,[rcx]     
        !mov [rdx],eax
        !add rcx,3
        !add rdx,4
        !dec r8
       !jnz copy_boucle24
      !mov rax,[p.v_s]
      !mov rcx,[rax]
      !mov rdx, [rax+8]
      !mov r8,[rax+16]
    DisableASM
    FreeArray(save())
   
    FreeImage(nom) ; supprime l'image 24bits
    CreateImage(nom,lg,ht,32)
    StartDrawing(ImageOutput(nom))
    source_p = DrawingBuffer()
    StopDrawing()
    CopyMemory( cible_p , source_p , taille*4 )
    FreeMemory(cible_p)
  EndIf
  ProcedureReturn 1
EndProcedure




; partie du programme à modifier pour adapter se programme au votre
; convertie les "IDs" des images en pointer d'adresse
; test si les images sont en 32bits et de la meme taille
;-------------------------------------------------------------------

Macro sp(source,cible)
  Protected Depth.q , lg.q , ht.q , lg1.q , ht1.q 
  Protected cible_p.q , source_p.q
 
  StartDrawing(ImageOutput(cible))
  cible_p = DrawingBuffer()
  ht1 = ImageHeight(cible)
  lg1 = ImageWidth(cible)
  Depth=OutputDepth()
  StopDrawing()
  If depth<>32 : ProcedureReturn : EndIf
 
  StartDrawing(ImageOutput(source))
  source_p = DrawingBuffer()
  ht = ImageHeight(source)
  lg = ImageWidth(source)
  Depth=OutputDepth()
  StopDrawing()
  If depth<>32 : ProcedureReturn : EndIf
 
  If lg<>lg1 Or ht<>ht1 : ProcedureReturn : EndIf
 
EndMacro

;-------------------------------------------------------------------

Procedure Filter_Rotate_Vertical_pb(source,cible,pos)
  Protected y.q
  Protected pos1.q , pos2.q , taille.q
  sp(source,cible)
  
  If pos<0 Or pos>=lg : ProcedureReturn : EndIf
  
  For y=0 To ht-1
    taille=(lg-pos)*4
    pos1=source_p+(((lg*y)+pos)*4)
    pos2=cible_p+(y*lg*4)
    CopyMemory(pos1,pos2,taille)
    
    taille=pos*4
    pos1=source_p+(lg*y*4)
    pos2=cible_p+(((y*lg)+(lg-pos))*4)
    CopyMemory(pos1,pos2,taille)
  Next

EndProcedure

;-------------------------------------------------------------------
UseJPEGImageDecoder()
UsePNGImageDecoder()
Global imgx=1200
Global imgy=800


If OpenWindow(0, 0, 0, imgx, imgy+16, "Rotation Verticale", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  Define source.q , cible.q , t.q , file$ , i , pos.q , mem_pos.q 
 
   file$ = OpenFileRequester("Image","","",0)
   source=10
   cible=20
   
   If Not Load_Image(source,file$) ; <- commande differente de "LOADIMAGE"
     MessageRequester("load_image","erreur de chargement",#PB_MessageRequester_Ok | #PB_MessageRequester_Error)
     End
   EndIf
   
   ScrollBarGadget(1, 0, 00, 1200, 16, 0, imgy, 1 )     
   ResizeImage(source,imgx,imgy,#PB_Image_Smooth)  
   CreateImage(cible,imgx,imgy,32) ; l'image doit entre en mode 32bits
   
   mem_pos=1
   Repeat 
     pos=GetGadgetState(1)
     If pos<>mem_pos
       pos=GetGadgetState(1)
       Filter_Rotate_Vertical_pb(source,cible,pos)
       StartDrawing(WindowOutput(0))
       DrawImage(ImageID(cible),0,16)
       StopDrawing()
       mem_pos = pos
     EndIf
     
   Until WindowEvent() = #PB_Event_CloseWindow
EndIf
robels
Messages : 1
Inscription : jeu. 19/nov./2020 23:54

Re: rotation verticale et horizontale d'une image

Message par robels »

Hello,

Merci pour le travail ! :o
Répondre