effer smudge

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

effer smudge

Message par manababel »

Ce n'est pas vraiment l'effet smudge, mais ça sent rapproché

Code : Tout sélectionner

;***********************************************
;Titre      : smudge

;Date       : 04/07/2021
;Version PB : PureBasic 5.70 LTS (Windows - x64)
;
;Info       : ne fonctionne qu'avec des images 32bits
;             la fonction "load_image" convertis les images 24bits en 32bits            
;***********************************************

EnableExplicit

UseJPEGImageDecoder()
UseJPEG2000ImageDecoder()
UsePNGImageDecoder()
UseTGAImageDecoder()
UseTIFFImageDecoder()
UseGIFImageDecoder()

Global mx, my

; charge une image et la convertie en 32bit
;-------------------------------------------------------------------
Procedure load_image(nom,file$)
  Protected nom_p.i , temps_p.i , x.l , y.l , r.l,g.l,b.l , i.l
  Protected lg.l , ht.l , depth.l , temps.i  , dif.l , dif1.l
  
  LoadImage(nom,file$)
  If Not IsImage(nom) : ProcedureReturn 0 : EndIf
  
  StartDrawing(ImageOutput(nom))
  Depth=OutputDepth()
  StopDrawing()
  
  If Depth=24
    CopyImage(nom,temps)
    FreeImage(nom)
    StartDrawing(ImageOutput(temps))
    temps_p = DrawingBuffer()
    lg = ImageWidth(temps)
    ht = ImageHeight(temps)
    dif = DrawingBufferPitch() - (lg*3)
    StopDrawing()
    
    
    CreateImage(nom,lg,ht,32)
    StartDrawing(ImageOutput(nom))
    nom_p = DrawingBuffer()
    StopDrawing()
    
    For y=0 To ht-1
      For x=0 To lg-1
        i = ((y*lg)+x)*3
        r=PeekA(temps_p + i + 2 + dif1)
        g=PeekA(temps_p + i + 1 + dif1)
        b=PeekA(temps_p + i + 0 + dif1)
        PokeL(nom_p + ((y*lg)+x)*4 , r<<16 + g<<8 + b)
      Next
      dif1 = dif1 + dif
    Next
    
    FreeImage(temps) ; supprime l'image 24bits
    
  EndIf
  
  ProcedureReturn 1
EndProcedure
;------------------------------------------------------------------

Procedure disque(x,y,r)
  Protected nx , ny , px , py , i , i1.f
  nx = Cos(0) * r + x
  ny = Sin(0) * r + y
  For i=12 To 360 Step 12
    i1 = Radian(i)
    px = Cos(i1) * r + x
    py = Sin(i1) * r + y    
    LineXY(nx,ny,px,py)
    nx = px
    ny = py
  Next
EndProcedure

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

Procedure main( source , radius.f , amp.f , mx , my , mx1 , my1)
  Protected lg ,ht , taille
  Protected source_p 
  Protected x , y , x1 , y1 , dx , dy , dis , pos , pos3 
  Protected rgb , r , g , b , nx , ny , compt , difx , dify
  
  If mx=mx1 And my=my1 : ProcedureReturn : EndIf
  difx = mx1 - mx
  dify = my1 - my
  
  StartDrawing(ImageOutput(source))
  lg = ImageWidth(source)
  ht = ImageHeight(source)
  taille=lg*ht*4
  source_p=DrawingBuffer()
  StopDrawing()
  
  If mx<0 : mx=0 : EndIf
  If my<0 : my=0 : EndIf
  If mx>lg-1:mx=lg-1 : EndIf
  If my>ht-1:my=ht-1 : EndIf
  
  For y=0 To ht-1
    For x=0 To lg-1
      dx = x-mx
      dy = y-my
      dis = Sqr(dx*dx+dy*dy)
      If dis<radius  
        r = 0 : g = 0 : b = 0
        For y1 = - 1 To 1
          For x1 = -1 To 1
            nx= x +  x1 + (difx * amp)
            ny= y +  y1 + (dify * amp)
            If nx<0 : nx=0 : EndIf
            If ny<0 : ny=0 : EndIf
            If nx>lg-1 : nx=lg-1 : EndIf
            If ny>ht-1 : ny=ht-1 : EndIf
            pos3 = (ny*lg+nx)*4
            rgb=PeekL(source_p + pos3)
            r = r + ((rgb>> 16)& 255)
            g = g + ((rgb>> 8)& 255)
            b = b + (rgb & 255)
          Next
        Next    
        r=r/9
        g=g/9
        b=b/9
        pos = (y*lg+x)*4
        PokeL(source_p + pos , r<<16 + g<<8 + b)
      EndIf
    Next
  Next             
  
EndProcedure




Global imgx=800
Global imgy=600
Define mousedown = 0, event=0

If OpenWindow(0, 0, 0, imgx, imgy+60, "Water Ripples...", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  Define source , cible , t , t1 , t2 ,ti , file$ , mx1 , my1
  
  ; selectionne le rayon
  ScrollBarGadget(1, 0, 0, imgx, 19, 1, 50,1 )
  SetGadgetState(1,25)
  ; selection la "force" ( max = 1 )
  ScrollBarGadget(2, 0, 20, imgx, 19, 1, 100,1 )
  SetGadgetState(2,100)

  
  source = 4
  ;cible = 5
  mousedown = 0
  file$ = OpenFileRequester("Image","","",0)
  If Not Load_Image(source,file$) ; <- commande differente de "LOADIMAGE"
    MessageRequester("load_image","erreur de chargement",#PB_MessageRequester_Ok | #PB_MessageRequester_Error)
    End
  EndIf
  ResizeImage(source,imgx,imgy,#PB_Image_Smooth)
  
  ;CreateImage(cible,imgx,imgy,32)
  
  StartDrawing(WindowOutput(0))
  DrawImage(ImageID(source),0,60)
  StopDrawing()
  
  Repeat 
    
    mx = WindowMouseX(0)
    my = WindowMouseY(0)
    event = WaitWindowEvent(1)
    
    If event = #WM_LBUTTONDOWN
      mousedown = 1
    ElseIf event = #PB_Event_LeftClick
      mousedown = 0
    EndIf
    
    
    If mousedown = 1
      main(source,GetGadgetState(1),GetGadgetState(2)/100,mx,imgy-(my-60) , mx1 , imgy-(my1-60))
    
      StartDrawing(WindowOutput(0))
      DrawImage(ImageID(source),0,60)
      If (my - GetGadgetState(1))> 60
        disque(mx,my,GetGadgetState(1))
      EndIf     
      StopDrawing()
    EndIf 
    
    mx1=mx
    my1=my
    Delay(1)
  Until event = #PB_Event_CloseWindow
EndIf
Avatar de l’utilisateur
kernadec
Messages : 1606
Inscription : ven. 25/avr./2008 11:14

Re: effer smudge

Message par kernadec »

bjj manababel
Merci pour le partage :D
Super top effect, on dirait la fonction: "Doigt" de Photoshop
avec un menu palette cela pourrait devenir une fonction gomme
Cordialement

petite modif pour effacer le cercle lorsque le bouton est relâché

Code : Tout sélectionner

If mousedown = 1
      main(source,GetGadgetState(1),GetGadgetState(2)/100,mx,imgy-(my-60) , mx1 , imgy-(my1-60))
    
      StartDrawing(WindowOutput(0))
      DrawImage(ImageID(source),0,60)
      If (my - GetGadgetState(1))> 60
        disque(mx,my,GetGadgetState(1))
      EndIf     
      StopDrawing()
    Else 
      StartDrawing(WindowOutput(0))
      DrawImage(ImageID(source),0,60)
      If (my - GetGadgetState(1))> 60
        disque(mx,my,0)
      EndIf     
      StopDrawing()
     EndIf 
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: effer smudge

Message par blendman »

coucou

wahouuuuuu !
c'est excellent, un grand bravo, c'est la fonction "doigt" (smudge) de photoshop :).
C'est génial, bravo Manababel, tu cartonnes !

L'effet est vraiment sympa.
Je vais l'intégrer dans mon logiciel de dessin Animatoon, si cela ne te dérange pas ;).

Lorsqu'on modifie les paramètres avec les scrollbar, j'ai ajouté ce code pour pas que ça produise un effet sur l'image en même temps :

Code : Tout sélectionner

If event = #WM_LBUTTONDOWN
      If my > 40
        mousedown = 1
      EndIf
    ElseIf event = #PB_Event_LeftClick
      mousedown = 0
    EndIf
Sinon, je me disais qu'en modifiant légèrement, tu pourrais avoir un effet "flou" quand on clique et qu'on bouge la souris (effet flou, mais qui ne déplace pas les pixels). Comme l'outil "goutte d'eau" de photoshop gimp :). D'ailleurs, en inversant ce flou, ça fera l'outil "sharpen" (ajout de netteté).
Mais punaise, en fait, ton code il est vraiment fabuleux !! :)


Ah oui, j'avais une autre question : là, ça utilise un cercle comme "forme" qui déplace les pixels, mais est-il possible d'utiliser une image transparente comme "forme" pour cet effet ?
Ce serait génial ;).



Kernadec : c'est quoi un menu palette ?
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: effer smudge

Message par Kwai chang caine »

Je connais pas l'effet doigt de photoshop car je ne l'ai jamais utilisé :oops:
Mais le code fonctionne ici
Merci pour le partage 8)
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
Avatar de l’utilisateur
kernadec
Messages : 1606
Inscription : ven. 25/avr./2008 11:14

Re: effer smudge

Message par kernadec »

bjr à tous
Voici quelques codes sources intéressants contenant des routines de logiciel dessin
MacPaint version 1.3 source code (5 files, 67.8k)
QuickDraw source (37 files, 180.4k)
Adobe Photoshop Source Code, February 13, 2013
Electronic Arts DeluxePaint Early Source Code, July 22, 2015
Microsoft Word for Windows Version 1.1a Source Code, March 25, 2014
https://www.clubic.com/insolite/actuali ... paint.html

Cordialement
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: effer smudge

Message par Kwai chang caine »

C'est toujours sympa de voir aujourd'hui ce que des centaines de programmeurs ont rêvé de voir il y a "quelques" temps :D
Même si j'y entrave quedal :mrgreen:
Merci pour ce lien 8)
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
Répondre