PureBasic

Forums PureBasic
Nous sommes le Jeu 25/Fév/2021 9:03

Heures au format UTC + 1 heure




Poster un nouveau sujet Répondre au sujet  [ 11 messages ] 
Auteur Message
 Sujet du message: filtre brightness - bend
MessagePosté: Mer 29/Juil/2020 8:41 
Hors ligne

Inscription: Jeu 14/Mai/2020 7:40
Messages: 66
voici deux filtres qui permettent de jouer sur la luminosité d'une image

le filtre "brightness"
- new pixel = pixel + Val ( Val peut être négatif ou positif )

le filtre "bend"
- new pixel = sin (pixel * val) * 127 + val
( la valeur 'val' doit être comprise entre 0 et 360 )
- toutes les nouvelles valeurs sont précalculées et stockées dans un tableau.
D'autres filtre fonctionnent de la même façon, comme le filtre "gamma"

Code:
EnableExplicit

Global Dim Reg_memory.q(4*344)

; 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 , taille.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

  taille = lg * ht
EndMacro

Macro clampRGB(r,g,b)
  If r<0:r=0:EndIf
  If g<0:g=0:EndIf
  If b<0:b=0:EndIf
  If r>255:r=255:EndIf
  If g>255:g=255:EndIf
  If b>255:b=255:EndIf
EndMacro

Macro returnRGB(pixel,r,g,b)
    r=(pixel & $ff0000)>>16
    g=(pixel & $ff00)>>8
    b=(pixel & $ff)
  EndMacro

;-------------------------------------------------------------------
; sauvegarde de registres
Macro Save_reg()
  s=@reg_memory()
  EnableASM
  !mov rax,[p.v_s]
  !mov [rax+000],rbx
  !mov [rax+008],rcx ;
  !mov [rax+016],rdx ;
  !mov [rax+024],rsi
  !mov [rax+032],rdi
  !mov [rax+040],r8 ;
  !mov [rax+048],r9 ;
  !mov [rax+056],r10
  !mov [rax+064],r11
  !mov [rax+072],r12
  !mov [rax+080],r13
  !mov [rax+088],r14
  !mov [rax+096],r15

  !movdqu [rax+104],xmm0 ;
  !movdqu [rax+120],xmm1 ;
  !movdqu [rax+136],xmm2 ;
  !movdqu [rax+152],xmm3 ;
  !movdqu [rax+168],xmm4
  !movdqu [rax+184],xmm5
  !movdqu [rax+200],xmm6
  !movdqu [rax+216],xmm7
  !movdqu [rax+232],xmm8
  !movdqu [rax+248],xmm9
  !movdqu [rax+264],xmm10
  !movdqu [rax+280],xmm11
  !movdqu [rax+296],xmm12
  !movdqu [rax+312],xmm13
  !movdqu [rax+328],xmm14
  !movdqu [rax+344],xmm15
  DisableASM
EndMacro

Macro Rest_Reg()
; restore les registres
  s=@reg_memory()
  EnableASM
  !mov rax,[p.v_s]
  !mov rbx,[rax+000]
  !mov rcx,[rax+008]
  !mov rdx,[rax+016]
  !mov rsi,[rax+024]
  !mov rdi,[rax+032]
  !mov r8,[rax+040]
  !mov r9,[rax+048]
  !mov r10,[rax+056]
  !mov r11,[rax+064]
  !mov r12,[rax+072]
  !mov r13,[rax+080]
  !mov r14,[rax+088]
  !mov r15,[rax+096]

  !movdqu xmm0,[rax+104] ;
  !movdqu xmm1,[rax+120] ;
  !movdqu xmm2,[rax+136] ;
  !movdqu xmm3,[rax+152] ;
  !movdqu xmm4,[rax+168]
  !movdqu xmm5,[rax+184]
  !movdqu xmm6,[rax+200]
  !movdqu xmm7,[rax+216]
  !movdqu xmm8,[rax+232]
  !movdqu xmm9,[rax+248]
  !movdqu xmm10,[rax+264]
  !movdqu xmm11,[rax+280]
  !movdqu xmm12,[rax+296]
  !movdqu xmm13,[rax+312]
  !movdqu xmm14,[rax+328]
  !movdqu xmm15,[rax+344]
  DisableASM

EndMacro
;-------------------------------------------------------------------

Procedure Filter_bend_pb(source.q,cible.q,r.q,g.q,b.q)
  Protected i.q , pixel.l , v.f
  Protected r1.f , g1.f , b1.f

  sp(source,cible)

  ;If r<0:r=0:EndIf
  ;If g<0:g=0:EndIf
  ;If b<0:b=0:EndIf
  ;If r>360:r=360:EndIf
  ;If g>360:g=360:EndIf
  ;If b>360:b=360:EndIf

  r=r-180
  g=g-180
  b=b-180

  r1.f=r/255.0*3.14/180.0
  g1.f=g/255.0*3.14/180.0
  b1.f=b/255.0*3.14/180.0

  Dim tabr(255)
  Dim tabg(255)
  Dim tabb(255)

  For i=0 To 255
    tabr(i)=Sin(i*r1)*127+i
    tabg(i)=Sin(i*g1)*127+i
    tabb(i)=Sin(i*b1)*127+i
    clampRGB(tabr(i),tabg(i),tabb(i))
  Next

  For i=0 To taille
    pixel=PeekL(source_p+i*4)
    returnRGB(pixel,r,g,b)
    PokeL(cible_p+i*4, tabr(r)<<16 + tabg(g)<<8 + tabb(b))
  Next
  FreeArray(tabr())
  FreeArray(tabg())
  FreeArray(tabb())

EndProcedure


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

; min = 0  :  max = 360
Procedure Filter_bend(source.q,cible.q,r.q,g.q,b.q)
  Protected s.q , palr.q , palg.q , palb.q , v.f , i.q
  Protected r1.f , g1.f , b1.f

  sp(source,cible)

  r=r-180
  g=g-180
  b=b-180

  r1.f=r/255.0*3.14/180.0
  g1.f=g/255.0*3.14/180.0
  b1.f=b/255.0*3.14/180.0

  Dim tabr(255)
  Dim tabg(255)
  Dim tabb(255)
  palr=@tabr()
  palg=@tabg()
  palb=@tabb()
  For i=0 To 255
    tabr(i)=Sin(i*r1)*127+i
    tabg(i)=Sin(i*g1)*127+i
    tabb(i)=Sin(i*b1)*127+i
    clampRGB(tabr(i),tabg(i),tabb(i))
  Next

  Dim save.q(14)
  s=@save()

  EnableASM
  Save_reg()
  !mov rsi,[p.v_source_p]
  !mov rdi,[p.v_cible_p]
  !mov r8,[p.v_palr]
  !mov r9,[p.v_palg]
  !mov r10,[p.v_palb]
  !mov rdx,[p.v_taille]
  !bend_2:
    !xor rax,rax
    !xor rbx,rbx
    !mov bl,[rsi+2]
    !mov al,[r8+rbx*8]
    !shl rax,8
    !mov bl,[rsi+1]
    !mov al,[r9+rbx*8]
    !shl rax,8
    !mov bl,[rsi+0]
    !mov al,[r10+rbx*8]
    !mov [rdi],eax
    !add rsi,4
    !add rdi,4
    !sub rdx,1
  !jnz bend_2
  Rest_reg()
  DisableASM
  FreeArray(save())
  FreeArray(tabr())
  FreeArray(tabg())
  FreeArray(tabb())
EndProcedure
;-------------------------------------------------------------------

Procedure Filter_Brightness(source,cible,r,g,b)
  Protected color.q , s.q
  sp(source,cible)
  color = r<<32 + g<<16 + b
  EnableASM
  Save_reg()
  !pxor xmm3,xmm3
    !mov rsi,[p.v_source_p]
    !mov rdi,[p.v_cible_p]
    !mov rdx,[p.v_taille]
    !shr rdx,1
    !mov rax,[p.v_color]
    !movq xmm0,rax
    !VPBROADCASTQ xmm0,xmm0 ; | 64bits A | 64 bits B |   ; A = B
    !xor rcx,rcx
    !Filter_Brightness_1:
    !movq xmm1,[rsi+rcx]
      !punpcklbw xmm1,xmm3 ; converti r,g,b 8bits en r,g,b 16bits
      !paddsw xmm1,xmm0  ; addition signée (-32767 a 32768 ) ; si var=(a-+b) if var<-32767 : var= -32767 :  if var>32768 : var = 32768
      !packuswb xmm1,xmm1 ; converti r,g,b 16bits en rgb 8bits de 0 a 255 : if var<0 : var =0 : if var >255 : var =255
      !movq [rdi+rcx],xmm1
      !add rcx,8
      !dec rdx
  !jnz Filter_Brightness_1
  Rest_reg()
  DisableASM
EndProcedure

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

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


If OpenWindow(0, 0, 0, imgx, imgy, "balance", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  Define source.q , cible.q , t.q , file$ , i , var

  ScrollBarGadget(1, imgx/4, 1, imgx/2, 24, 0, 720, 25)
  ScrollBarGadget(2, imgx/4, 25, imgx/2, 24, 0, 512, 25)
  SetGadgetState(2, 256)

   file$ = OpenFileRequester("Image","","",0)
   source=10
   cible=20
   
   If Load_Image(source,file$) = 0 ; <- commande differente de "LOADIMAGE"
     MessageRequester("erreur", "image non chargeé" ,#PB_MessageRequester_Ok )
     End
   EndIf
   
   ResizeImage(source,imgx,imgy,#PB_Image_Smooth)
   
   CreateImage(cible,imgx,imgy,32) ; l'image doit entre en mode 32bits
   
   var=200
   SetGadgetState(1,var)
   Filter_bend(source,cible,var,var,var)
   
   Repeat
     Select WaitWindowEvent()

        Case  #PB_Event_CloseWindow
          End
        Case  #PB_Event_Gadget
         
          Select EventGadget()
             
            Case 1
              var=GetGadgetState(1)
              t=ElapsedMilliseconds()
              Filter_bend(source,cible,var,var,var) ; version asm
              ;Filter_bend_pb(source,cible,var,var,var) ; version pureabsic
              t=ElapsedMilliseconds()-t
             
            Case 2
              var=GetGadgetState(2)-256
              t=ElapsedMilliseconds()
              Filter_Brightness(source,cible,var,var,var)
              t=ElapsedMilliseconds()-t
             
          EndSelect
      EndSelect
       
       StartDrawing(WindowOutput(0))
       DrawImage(ImageID(cible),0,50)
       DrawText(5,50,"temps : "+Str(t))
       DrawText(5,5,Str(GetGadgetState(1))+"     ")
       DrawText(5,25,Str(GetGadgetState(2)-256)+"     ")
       StopDrawing()
   
    ForEver
EndIf


Dernière édition par manababel le Mer 29/Juil/2020 18:17, édité 1 fois.

Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: filtre brightness - bend
MessagePosté: Mer 29/Juil/2020 12:57 
Hors ligne
Avatar de l’utilisateur

Inscription: Mer 09/Nov/2005 9:53
Messages: 4307
Hmmmmm, je me mefis des codes du premier venu contenant de l'asm...

Perso, je ne testerais pas. Désolé :idea:

Mais, bravo si c'est toi qui 'a codé !!

_________________
http://HexaScrabble.com/
!i!i!i!i!i!i!i!i!i!
!i!i!i!i!i!i!
!i!i!i!
//// Informations ////
Portable LENOVO ideapad 110-17ACL 64 bits
Version de PB : 5.73LTS - 32 bits


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: filtre brightness - bend
MessagePosté: Mer 29/Juil/2020 14:29 
Hors ligne
Avatar de l’utilisateur

Inscription: Dim 09/Oct/2005 16:51
Messages: 9093
Ce n'est pas le 1er code qu'il poste non plus...
Moi j'ai testé et c'est très réactif.

_________________
~~~~Règles du forum ~~~~
.: Ar-S :. Tour + portable W10 x64 PB 5.6x / 5.7x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: filtre brightness - bend
MessagePosté: Mer 29/Juil/2020 15:33 
Hors ligne

Inscription: Jeu 14/Mai/2020 7:40
Messages: 66
Dans ce programme, il y a 3 procédures.
-Filter_bend_pb
-Filter_bend
-Filter_Brightness

Filter_bend_pb est écrite en basic
Filter_bend et Filter_bend_pb font la meme chose
Filter_Brightness, c'est juste :
r=r+val1
g=g+val2
b=b+val3

Si vous avez une image en 32 bits, vous pouvez supprimer toutes les parties en asm et tester seulement la procédure Filter_bend_Pb.

Filter_bend_ pb est juste posté à titre de comparaison


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: filtre brightness - bend
MessagePosté: Mer 29/Juil/2020 17:46 
Hors ligne
Avatar de l’utilisateur

Inscription: Dim 22/Aoû/2010 15:24
Messages: 6935
Localisation: IDF (Yvelines)
@SPH : Ben dit donc Monsieur SPH veux tu être aimable s'il te plait ? :wink:

@manababel : Je ne connais rien en Assembleur. Alors bravo pour l'énergie déployée pour ce code.

■ J'ai testé avec avec des photos récentes de 10 Mo environ. Les modifications appliquées sont immédiates. Par contre j'ai des soucis de resize avec des photos de 2010 et certaines passent en dégradés de gris à l'ouverture de la photo.

■ Un souci mineur. Crash de l'exécutable si on ne choisit pas d'image.

_________________

➽ Config PureBasic : Windows 10 Version 64 Bits - DirectX 11 - PB 5.72

➽ Je ne réponds pas aux MP techniques


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: filtre brightness - bend
MessagePosté: Mer 29/Juil/2020 18:25 
Hors ligne

Inscription: Jeu 14/Mai/2020 7:40
Messages: 66
j'ai corrigé le code, il ne devrait plus avoir d'erreur si on ne choisit pas de photo .

je ne comprends pas d'où viens le problème avec la photo qui passe en dégradé de gris.

Dans le doc de purebasic, "loadimage" convertit les images en 24 ou 32 bits.
la partie de mon programme ne convertit que les images 24 bits en 32 bits.


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: filtre brightness - bend
MessagePosté: Mer 29/Juil/2020 18:40 
Hors ligne
Avatar de l’utilisateur

Inscription: Dim 22/Aoû/2010 15:24
Messages: 6935
Localisation: IDF (Yvelines)
Je vais te passer une des photos et le résultat que j'obtiens avec ton code en mp

_________________

➽ Config PureBasic : Windows 10 Version 64 Bits - DirectX 11 - PB 5.72

➽ Je ne réponds pas aux MP techniques


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: filtre brightness - bend
MessagePosté: Mer 29/Juil/2020 19:28 
Hors ligne

Inscription: Jeu 14/Mai/2020 7:40
Messages: 66
Effectivement il y a un problème avec l'image que vous m'avez envoyée.
Je pense que le problème vient du fait que votre image ne soit pas un multiple de 2.
Il se peut que "createimage" ne crée que des images multiples de 2.

voici la partie à remplacé pour que ça fonctionne votre image

Code:
;-------------------------------------------------------------------
Procedure load_image(nom,file$)
  Protected source_p , cible_p , s.q
  Protected lg.q , ht.q , taille.q , depth.q , lg1.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
      Save_reg()
      !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
      Rest_Reg()
    DisableASM
    FreeArray(save())
   
    FreeImage(nom) ; supprime l'image 24bits
   
    lg1=lg ; test si l'image est un miltiple de 2
    lg1 = lg1 / 2
    lg1 = lg1 * 2
    If lg1 <> lg
      CreateImage(nom,lg+1,ht,32)
    Else
      CreateImage(nom,lg,ht,32)
    EndIf
   
    StartDrawing(ImageOutput(nom))
    source_p = DrawingBuffer()
    StopDrawing()
   
    CopyMemory( cible_p , source_p , taille*4 )
    FreeMemory(cible_p)
  EndIf

  ProcedureReturn 1
EndProcedure


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: filtre brightness - bend
MessagePosté: Mer 05/Aoû/2020 16:56 
Hors ligne
Avatar de l’utilisateur

Inscription: Sam 23/Sep/2006 18:32
Messages: 6763
Localisation: Isere
Bonjour Manababel, toujours impressionné par l'ASM que je ne connais pas, j'ai essayé le code que tu as eu la gentillesse de nous donner
Code:
For i=0 To 255
Et j'ai l'erreur que la boucle for ne supporte pas les variables de type quad :|
Surement une histoire de X64 / X86

_________________
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: filtre brightness - bend
MessagePosté: Mer 05/Aoû/2020 17:23 
Hors ligne

Inscription: Jeu 14/Mai/2020 7:40
Messages: 66
Bonjour Kwai chang caine ,

Oui ce programme est en 64 bits.
Je peux 'récrire' en 32 bits si vous voulez ?


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: filtre brightness - bend
MessagePosté: Mar 11/Aoû/2020 18:04 
Hors ligne
Avatar de l’utilisateur

Inscription: Sam 23/Sep/2006 18:32
Messages: 6763
Localisation: Isere
C'est gentil, mais ne perd pas ton temps si tu n'en a pas besoin 8)
Je me doutais un peu de la réponse car avec l'ASM c'est souvent ça, mais j'ai ma réponse c'est le principal :wink:

J'adore tester les codes, même si ils ne me serviront peut être jamais :oops:
Surtout en ASM que j'admire depuis que j'ai appris qu'il existait et ce qu'il pouvait faire :wink:
Parfois ça peut aider le développeur (si ça ne fonctionne pas chez moi par exemple) et en plus chaque code (ASM ou non) me passionne et m’enrichis un petit peu plus
J'suis un peu un des BETA testeurs des forums PB, enfin plus BETA que testeur d'ailleurs :mrgreen:

En tout cas bravo de pouvoir jouer avec le "Langage des langages", ils auraient du l’appeler le LDL d'ailleurs :lol:
Encore merci de ton travail et partage 8)

_________________
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic


Haut
 Profil  
Répondre en citant le message  
Afficher les messages postés depuis:  Trier par  
Poster un nouveau sujet Répondre au sujet  [ 11 messages ] 

Heures au format UTC + 1 heure


Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 2 invités


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 à:  

 


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