Page 1 sur 1

fonction 'lasso'

Publié : mer. 17/mars/2021 20:39
par manababel
bonjour
Avec kernadec , nous avons écrit ce programme .

voici une fonction "lasso" similaire à celle d'un logiciel de dessin

le code est très brouillon, n'hésitez pas à l'améliorer.

Code : Tout sélectionner

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

#width = 800
#height = 600

Enumeration
#Lasso_Window_0
#Lasso_Window_1
#Lasso_Image_0
#Lasso_Image_1
#Lasso_Image_2
#Lasso_Image_3
#Lasso_Gadget_0
#Lasso_Gadget_1
#Lasso_Gadget_2
#Lasso_Gadget_3
#lasso_Menu_0
EndEnumeration


Structure copys
  index.i
  addr.i
  px.i
  py.i
  lg.i
  ht.i
  dx.i
  dy.i
EndStructure
Global NewList mescopy.copys()

Global source = 0
Global cible = 20
Global original = 40
Global img_tmps = 50

Global NewList V.point()

Macro Coo_Segment( Pa, Pb, Liste )
  *Situation = @Liste
  Pa = Liste : If NextElement( Liste ) = 0 : FirstElement( Liste ) : EndIf
  Pb = Liste : ChangeCurrentElement( Liste, *Situation )
  
EndMacro

; 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 , $ff000000 + r<<16 + g<<8 + b)
      Next
      dif1 = dif1 + dif
    Next
   
    FreeImage(temps) ; supprime l'image 24bits
   
  EndIf

  ProcedureReturn 1
EndProcedure
;------------------------------------------------------------------

Procedure fusionner(List mescopy.copys(),cible)
  source_p = mescopy()\addr
  ht1 = mescopy()\ht
  lg1 = mescopy()\lg
  px = mescopy()\px
  py = mescopy()\py
  
  StartDrawing(ImageOutput(cible))
  cible_p = DrawingBuffer()
  ht2 = ImageHeight(cible)
  lg2 = ImageWidth(cible)
  StopDrawing()
  
  For y=0 To ht1-1
    For x=0 To lg1-1
      pos1 = source_p + ((y * lg1) + x) * 4  
      x2 = x + px
      y2 = y + py
      If x2>=0 And x2<lg2 And y2>=0 And y2<ht2
        pos2 = cible_p + ((y2 * lg2) + x2) * 4
        a = PeekA(pos1 + 3)
        If a<>0
          rgb = PeekL(pos1)
          PokeL(pos2  , rgb)
        EndIf        
      EndIf
    Next
  Next


EndProcedure

Procedure cn_PnPoly( px,py , List Polylist.point() )
  Define pa.point, pb.point, cn.l
  ForEach Polylist() : Coo_Segment( Pa, Pb, Polylist() )
    If (((pa\y <= py) And (pb\y > py)) Or ((pa\y > py) And (pb\y <= py)))
      vt.f = (py - pa\y) / (pb\y - pa\y);
      If (px < pa\x + vt * (pb\x - pa\x)) ;
        cn+1 ; ;
      EndIf
    EndIf
  Next
  ProcedureReturn (cn&1); // 0 if even (out), and 1 if odd (in)
EndProcedure

Procedure copy(source , cible , px , py)

  StartDrawing(ImageOutput(source))
  source_p = DrawingBuffer()
  ht1 = ImageHeight(source)
  lg1 = ImageWidth(source)
  StopDrawing()
  
  StartDrawing(ImageOutput(cible))
  cible_p = DrawingBuffer()
  ht2 = ImageHeight(cible)
  lg2 = ImageWidth(cible)
  StopDrawing()
  
  StartDrawing(ImageOutput(#Lasso_Image_3))
  lasso_p = DrawingBuffer()
  ht3 = ImageHeight(#Lasso_Image_3)
  lg3 = ImageWidth(#Lasso_Image_3)
  StopDrawing()
  
  ; si le pixel est dans le 'lasso' : pixel_alpha=255 : si non : pixel_alpha=0
  For y=0 To ht2-1
    For x=0 To lg2-1
      pos2 = ((y*lg2)+x)*4
      PokeL(cible_p + pos2 , 0) ; rempli l'image de 0 ( a=0 : r=0 : g=0 : b=0)
      If cn_PnPoly( px+x,py+y , v() )> 0
        y1 = (y + py) * lg1
        pos1 = ((y1+x+px) * 4); lit l'image source rgb
        argb = PeekL(source_p + pos1)
        PokeL(cible_p + pos2 , argb) ; $ff000000 = alpha
        
        ; cree le "" sur l'image source
        rgb = PeekL(lasso_p + ((y*lg3)+x)*4)
        PokeL(source_p + pos1,rgb & $00ffffff)
      EndIf
    Next
  Next
EndProcedure

Procedure create_new_picture(source)
  ; calcul la taille de l'image selectionnée par le 'lasso' 
  If ListSize(v()) = 0 : ProcedureReturn : EndIf
  pminx=999999
  pminy=999999
  pmaxx=0
  pmaxy=0
  ForEach v()   
    If pminx > v()\x : pminx = v()\x :EndIf
    If pminy > v()\y : pminy = v()\y :EndIf
    If pmaxx < v()\x : pmaxx = v()\x :EndIf
    If pmaxy < v()\y : pmaxy = v()\y :EndIf
  Next
  lg = pmaxx - pminx
  ht = pmaxy - pminy
  
  ; cree la nouvelle image 
  CreateImage(cible,lg,ht,32, #PB_Image_Transparent)
  copy(source , cible ,pminx , pminy)
  
  OpenWindow(#Lasso_Window_1, 0, 0, lg, ht, "Calque", #PB_Window_SystemMenu )
  StartDrawing(ImageOutput(#Lasso_Image_1))
  DrawingMode(#PB_2DDrawing_AlphaBlend)
  DrawImage(ImageID(#Lasso_Image_3), 0, 0)
  DrawAlphaImage(ImageID(cible),0,0)
  StopDrawing()
  
  img = CopyImage(cible,#PB_Any)
  AddElement(mescopy())
  StartDrawing(ImageOutput(img))
  mescopy()\index = img
  mescopy()\addr = DrawingBuffer()
  mescopy()\ht = ImageHeight(img)
  mescopy()\lg = ImageWidth(img)
  mescopy()\px = ListSize(mescopy()) * 25
  mescopy()\py = ListSize(mescopy()) * 25
  StopDrawing()
  ImageGadget(#Lasso_Gadget_1, 0, 0, WindowWidth(1), WindowHeight(1), ImageID(#Lasso_Image_1))
EndProcedure


Procedure draw_alpha(List mescopy.copys(),cible)
 
  source_p = mescopy()\addr
  ht1 = mescopy()\ht
  lg1 = mescopy()\lg
  px = mescopy()\px
  py = mescopy()\py
  
  StartDrawing(ImageOutput(cible))
  cible_p = DrawingBuffer()
  ht2 = ImageHeight(cible)
  lg2 = ImageWidth(cible)
  StopDrawing()
  
  For y=0 To ht1-1
    For x=0 To lg1-1
      pos1 = source_p + ((y * lg1) + x) * 4  
      x2 = x + px
      y2 = y + py
      If x2>=0 And x2<lg2 And y2>=0 And y2<ht2
        pos2 = cible_p + ((y2 * lg2) + x2) * 4
        a = PeekA(pos1 + 3)
        If a<>0
          rgb = PeekL(pos1)
          PokeL(pos2, rgb)
        EndIf        
      EndIf
    Next
  Next
  
EndProcedure



OpenWindow(#Lasso_Window_0, 0, 0, #width, #height, "lasso- " + Str(TotalSeconds),#PB_Window_SystemMenu|#PB_Window_ScreenCentered)

If CreateMenu(#lasso_Menu_0, WindowID(#Lasso_Window_0))
  MenuTitle("Fichiers")
  MenuItem(1, "Ouvrir" +Chr(9)+"Ctrl+O")
  MenuBar()
  MenuItem(2, "Enregistrer sous"+Chr(9)+"Ctrl+R")
  MenuBar()
  MenuItem(3, "Quitter" +Chr(9)+"Ctrl+Q")
  MenuTitle("Edition")
  MenuItem(4, "Annuler" +Chr(9)+"Ctrl+Z")
  MenuBar()
  MenuItem(5, "Copier" +Chr(9)+"Ctrl+C")
  MenuItem(6, "Coller" +Chr(9)+"Ctrl+V")
  MenuBar()
  MenuItem(7, "Couper" +Chr(9)+"Ctrl+X")
  MenuTitle("Outils")
  MenuItem(8, "Selection Lasso")
EndIf

CreateImage(#Lasso_Image_0, #width,#height,32)
CreateImage(#Lasso_Image_1, #width,#height,32)
CreateImage(#Lasso_Image_2, #width,#height,32)
CreateImage(#Lasso_Image_3, #width,#height,32)
CreateImage(img_tmps, #width,#height,32)

StartDrawing(ImageOutput(#Lasso_Image_3)) ; auteur netmaestro ;) je n'ai mis que la couleur à 204 comme photoshop
For i = 0 To WindowWidth(0) * 2 Step 16
  For j = 0 To WindowWidth(0) * 2 Step 16
    Box(j,i,8,8,RGB(204,204,204))
    Box(j+8,i,8,8,#White)
    Box(j,i+8,8,8,#White)
    Box(j+8,i+8,8,8,RGB(204,204,204))
  Next
Next
StopDrawing()
ImageGadget(#Lasso_Gadget_3, 0, 0, WindowWidth(0), WindowHeight(0), ImageID(#Lasso_Image_3))



capture = 1 ; "capture"  est similaire a "opt"
opt = 0
Repeat
  mx = WindowMouseX(#Lasso_Window_0)
  my = WindowMouseY(#Lasso_Window_0)
 
  Event = WaitWindowEvent()
  Select event
    Case #WM_LBUTTONDOWN
      If capture = 1
        If opt = 0
          AddElement(v()) ; ajoute une coordonnee au lasso
          v()\x = mx
          v()\y = #height - my
        EndIf
      EndIf
      
      If capture = 0
        If deplace = 0 And ListSize(mescopy())>0
          
          ; selection une copy a deplacer
          LastElement(mescopy())
          my1 = #height - my
          If mx > mescopy()\px And mx < (mescopy()\px + mescopy()\lg)
            If my1 > mescopy()\py And my1 < (mescopy()\py + mescopy()\ht)
              mescopy()\dx = mescopy()\px - mx
              mescopy()\dy = mescopy()\py - my1
              deplace = 1
            EndIf
          EndIf
          
          If deplace = 0
            ForEach mescopy()
              If mx > mescopy()\px And mx < (mescopy()\px + mescopy()\lg)
                If my1 > mescopy()\py And my1 < (mescopy()\py + mescopy()\ht)
                  mescopy()\dx = mescopy()\px - mx
                  mescopy()\dy = mescopy()\py - my1
                  deplace = 1
                  MoveElement(mescopy(),#PB_List_Last)
                  Break
                EndIf
              EndIf
            Next
          EndIf
          
        Else
          deplace = 0
        EndIf   
      EndIf
      
    Case #WM_RBUTTONDOWN
      If deplace = 0 And capture = 0
        Resultat = MessageRequester("fusionner", "voulez vous fusionner le calque avec 'limage" ,#PB_MessageRequester_YesNoCancel)
        If Resultat = 6
          fusionner(mescopy(),source)
          DeleteElement(mescopy())
          deplace = 0
        EndIf
      EndIf
      
      
    Case #PB_Event_Menu
      
      Select EventMenu() ; To see which menu has been selected    
        Case 1 ; charge image
          file$ = OpenFileRequester("Image","","",0)
          source = 10
          If Not Load_Image(source,file$)
            MessageRequester("load_image","erreur de chargement",#PB_MessageRequester_Ok | #PB_MessageRequester_Error)
            End
          EndIf
          
          ResizeImage(source,#width,#height,#PB_Image_Smooth)
          CopyImage(source,original)
          SetActiveWindow(#Lasso_Window_0) ; Restore la source
          StartDrawing(WindowOutput(#Lasso_Window_0))
          ;If IsImage(source) : DrawImage(ImageID(original),0,0) : EndIf
          If IsImage(source) : DrawImage(ImageID(source),0,0) : EndIf
          StopDrawing()
          
        Case 2 ; sauve image
          
        Case 3 ; eXit
          End
          
        Case 4 ; annuler
          ClearList(v())
          
        Case 5 ; copier
          If opt = 0
            opt = 1
            create_new_picture(source)
            *Memory = EncodeImage(cible, #PB_ImagePlugin_PNG)
            SetClipboardText(Str(*Memory))
            *Memory = Val(GetClipboardText())
            CatchImage(#Lasso_Image_2, *Memory) ; L'image est en mémoire
            SaveImage(#Lasso_Image_2, "d:\purebasic64\\Imagelassot.png",#PB_ImagePlugin_PNG,32)
          EndIf
          
          ; retour activation de la fenetre principale
          capture = 0
          ClearList(v())
          SetActiveWindow(#Lasso_Window_0) ; Restore la source
          StartDrawing(WindowOutput(#Lasso_Window_0))
          ;If IsImage(source) : DrawImage(ImageID(original),0,0) : EndIf
          If IsImage(source) : DrawImage(ImageID(source),0,0) : EndIf
          StopDrawing()
          ;CopyImage(oroginal,source); on restore l'original
          
        Case 6 ; coller 

        Case 7 ; couper  

        Case 8 ; lasso
          ClearList(v())         
          opt = 0         
          If capture = 0 : capture = 1 : EndIf
          
      EndSelect
  EndSelect
  

  If capture = 1
    If ListSize(v()) > 0 ; "affiche" le lasso
      StartDrawing(WindowOutput(#Lasso_Window_0))
      DrawImage(ImageID(img_tmps),0,0)
      FirstElement(v())
      x1 = v()\x
      y1 = v()\y
      ForEach v()
        x = v()\x
        y = v()\y
        DrawingMode(#PB_2DDrawing_XOr)
        If opt = 0 : LineXY(x1,#height - y1,x,#height - y,$ffffff) : EndIf
        x1=x
        y1=y
      Next   
      StopDrawing()
    EndIf  
  EndIf
  
  
  If deplace = 1
    LastElement(mescopy())
    mescopy()\px = mx + mescopy()\dx
    mescopy()\py = (#height - my) + mescopy()\dy
  EndIf
  
  
  StartDrawing(ImageOutput(img_tmps))
  If source <> 0 
    DrawImage(ImageID(source),0,0)
  Else
    DrawImage(ImageID(#Lasso_Image_3),0,0)
  EndIf
  StopDrawing()
  

  ; update affichage des copy
  ForEach mescopy()
    draw_alpha(mescopy(), img_tmps)
  Next
  
  StartDrawing(WindowOutput(#Lasso_Window_0))
  DrawImage(ImageID(img_tmps),0,0)
  StopDrawing()
  
  ; affichage le rectangle autour de l'image selectionnee
  my1 = #height - my
  ForEach mescopy()
    If mx > mescopy()\px And mx < (mescopy()\px + mescopy()\lg) 
      If my1 > mescopy()\py And my1 < (mescopy()\py + mescopy()\ht)  
        StartDrawing(WindowOutput(#Lasso_Window_0))
        DrawingMode(#PB_2DDrawing_XOr)
        Line(mescopy()\px,#height - mescopy()\py,1,-mescopy()\ht)
        Line(mescopy()\px,#height - mescopy()\py,mescopy()\lg,1)
        Line(mescopy()\px + mescopy()\lg,#height - mescopy()\py,1,-mescopy()\ht)
        Line(mescopy()\px ,#height - mescopy()\py - mescopy()\ht ,mescopy()\lg , 1)
        StopDrawing()
      EndIf
    EndIf  
  Next
  
  
Until Event = #PB_Event_CloseWindow

End

Re: fonction 'lasso'

Publié : jeu. 18/mars/2021 16:19
par Kwai chang caine
Chez moi, ça ne ressemble pas vraiment à la fonction "lasso", mais plutôt à un style de sélection "ligne connectées", c'est à dire chaque clic fini une ligne droite et recommence une suivante droite aussi.
En tout cas merci pour le partage 8)

Re: fonction 'lasso'

Publié : jeu. 18/mars/2021 17:32
par kernadec
bjr Kcc
Je suis heureux de te lire, merci :D
Alors voilà, C'est un Lasso polygonal :wink:
il est différent du Lasso qui suit le parcours du curseur appuyé.
mais l'avantage de celui-ci,
c'est qu'on peut l'utiliser avec des points courts ou longs
l'important c'est de réaliser une clôture :mrgreen:

ps:
Comme il est très compliqué de copier une image avec transparence dans le Presse Papier
le calque est encodé en mémoire avec la fonction EncodeImage()
c 'est l'adresse de l'image qui est Copiée Collée depuis le Presse Papier.

Cordialement

Re: fonction 'lasso'

Publié : jeu. 18/mars/2021 19:22
par manababel
voici une version qui vous permet de sélectionner "lasso" ou "polygone".
En mode "capture" appuyiez sur le bouton droit de la souris pour changer de mode.

Code : Tout sélectionner

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

#width = 800
#height = 600

Enumeration
#Lasso_Window_0
#Lasso_Window_1
#Lasso_Image_0
#Lasso_Image_1
#Lasso_Image_2
#Lasso_Image_3
#Lasso_Gadget_0
#Lasso_Gadget_1
#Lasso_Gadget_2
#Lasso_Gadget_3
#lasso_Menu_0
EndEnumeration


Structure copys
  index.i
  addr.i
  px.i
  py.i
  lg.i
  ht.i
  dx.i
  dy.i
EndStructure
Global NewList mescopy.copys()

Global source = 0
Global cible = 20
Global original = 40
Global img_tmps = 50

Global NewList V.point()

Macro Coo_Segment( Pa, Pb, Liste )
  *Situation = @Liste
  Pa = Liste : If NextElement( Liste ) = 0 : FirstElement( Liste ) : EndIf
  Pb = Liste : ChangeCurrentElement( Liste, *Situation )
  
EndMacro

; 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 , $ff000000 + r<<16 + g<<8 + b)
      Next
      dif1 = dif1 + dif
    Next
   
    FreeImage(temps) ; supprime l'image 24bits
   
  EndIf

  ProcedureReturn 1
EndProcedure
;------------------------------------------------------------------

Procedure fusionner(List mescopy.copys(),cible)
  source_p = mescopy()\addr
  ht1 = mescopy()\ht
  lg1 = mescopy()\lg
  px = mescopy()\px
  py = mescopy()\py
  
  StartDrawing(ImageOutput(cible))
  cible_p = DrawingBuffer()
  ht2 = ImageHeight(cible)
  lg2 = ImageWidth(cible)
  StopDrawing()
  
  For y=0 To ht1-1
    For x=0 To lg1-1
      pos1 = source_p + ((y * lg1) + x) * 4  
      x2 = x + px
      y2 = y + py
      If x2>=0 And x2<lg2 And y2>=0 And y2<ht2
        pos2 = cible_p + ((y2 * lg2) + x2) * 4
        a = PeekA(pos1 + 3)
        If a<>0
          rgb = PeekL(pos1)
          PokeL(pos2  , rgb)
        EndIf        
      EndIf
    Next
  Next


EndProcedure

Procedure cn_PnPoly( px,py , List Polylist.point() )
  Define pa.point, pb.point, cn.l
  ForEach Polylist() : Coo_Segment( Pa, Pb, Polylist() )
    If (((pa\y <= py) And (pb\y > py)) Or ((pa\y > py) And (pb\y <= py)))
      vt.f = (py - pa\y) / (pb\y - pa\y);
      If (px < pa\x + vt * (pb\x - pa\x)) ;
        cn+1 ; ;
      EndIf
    EndIf
  Next
  ProcedureReturn (cn&1); // 0 if even (out), and 1 if odd (in)
EndProcedure

Procedure copy(source , cible , px , py)

  StartDrawing(ImageOutput(source))
  source_p = DrawingBuffer()
  ht1 = ImageHeight(source)
  lg1 = ImageWidth(source)
  StopDrawing()
  
  StartDrawing(ImageOutput(cible))
  cible_p = DrawingBuffer()
  ht2 = ImageHeight(cible)
  lg2 = ImageWidth(cible)
  StopDrawing()
  
  StartDrawing(ImageOutput(#Lasso_Image_3))
  lasso_p = DrawingBuffer()
  ht3 = ImageHeight(#Lasso_Image_3)
  lg3 = ImageWidth(#Lasso_Image_3)
  StopDrawing()
  
  ; si le pixel est dans le 'lasso' : pixel_alpha=255 : si non : pixel_alpha=0
  For y=0 To ht2-1
    For x=0 To lg2-1
      pos2 = ((y*lg2)+x)*4
      PokeL(cible_p + pos2 , 0) ; rempli l'image de 0 ( a=0 : r=0 : g=0 : b=0)
      If cn_PnPoly( px+x,py+y , v() )> 0
        y1 = (y + py) * lg1
        pos1 = ((y1+x+px) * 4); lit l'image source rgb
        argb = PeekL(source_p + pos1)
        PokeL(cible_p + pos2 , argb) ; $ff000000 = alpha
        
        ; cree le "" sur l'image source
        rgb = PeekL(lasso_p + ((y*lg3)+x)*4)
        PokeL(source_p + pos1,rgb & $00ffffff)
      EndIf
    Next
  Next
EndProcedure

Procedure create_new_picture(source)
  ; calcul la taille de l'image selectionnée par le 'lasso' 
  If ListSize(v()) = 0 : ProcedureReturn : EndIf
  pminx=999999
  pminy=999999
  pmaxx=0
  pmaxy=0
  ForEach v()   
    If pminx > v()\x : pminx = v()\x :EndIf
    If pminy > v()\y : pminy = v()\y :EndIf
    If pmaxx < v()\x : pmaxx = v()\x :EndIf
    If pmaxy < v()\y : pmaxy = v()\y :EndIf
  Next
  lg = pmaxx - pminx
  ht = pmaxy - pminy
  
  ; cree la nouvelle image 
  CreateImage(cible,lg,ht,32, #PB_Image_Transparent)
  copy(source , cible ,pminx , pminy)
  
  OpenWindow(#Lasso_Window_1, 0, 0, lg, ht, "Calque", #PB_Window_SystemMenu )
  StartDrawing(ImageOutput(#Lasso_Image_1))
  DrawingMode(#PB_2DDrawing_AlphaBlend)
  DrawImage(ImageID(#Lasso_Image_3), 0, 0)
  DrawAlphaImage(ImageID(cible),0,0)
  StopDrawing()
  
  img = CopyImage(cible,#PB_Any)
  AddElement(mescopy())
  StartDrawing(ImageOutput(img))
  mescopy()\index = img
  mescopy()\addr = DrawingBuffer()
  mescopy()\ht = ImageHeight(img)
  mescopy()\lg = ImageWidth(img)
  mescopy()\px = ListSize(mescopy()) * 25
  mescopy()\py = ListSize(mescopy()) * 25
  StopDrawing()
  ImageGadget(#Lasso_Gadget_1, 0, 0, WindowWidth(1), WindowHeight(1), ImageID(#Lasso_Image_1))
EndProcedure


Procedure draw_alpha(List mescopy.copys(),cible)
 
  source_p = mescopy()\addr
  ht1 = mescopy()\ht
  lg1 = mescopy()\lg
  px = mescopy()\px
  py = mescopy()\py
  
  StartDrawing(ImageOutput(cible))
  cible_p = DrawingBuffer()
  ht2 = ImageHeight(cible)
  lg2 = ImageWidth(cible)
  StopDrawing()
  
  For y=0 To ht1-1
    For x=0 To lg1-1
      pos1 = source_p + ((y * lg1) + x) * 4  
      x2 = x + px
      y2 = y + py
      If x2>=0 And x2<lg2 And y2>=0 And y2<ht2
        pos2 = cible_p + ((y2 * lg2) + x2) * 4
        a = PeekA(pos1 + 3)
        If a<>0
          rgb = PeekL(pos1)
          PokeL(pos2, rgb)
        EndIf        
      EndIf
    Next
  Next
  
EndProcedure



OpenWindow(#Lasso_Window_0, 0, 0, #width, #height, "lasso- " + Str(TotalSeconds),#PB_Window_SystemMenu|#PB_Window_ScreenCentered)

If CreateMenu(#lasso_Menu_0, WindowID(#Lasso_Window_0))
  MenuTitle("Fichiers")
  MenuItem(1, "Ouvrir" +Chr(9)+"Ctrl+O")
  MenuBar()
  MenuItem(2, "Enregistrer sous"+Chr(9)+"Ctrl+R")
  MenuBar()
  MenuItem(3, "Quitter" +Chr(9)+"Ctrl+Q")
  MenuTitle("Edition")
  MenuItem(4, "Annuler" +Chr(9)+"Ctrl+Z")
  MenuBar()
  MenuItem(5, "Copier" +Chr(9)+"Ctrl+C")
  MenuItem(6, "Coller" +Chr(9)+"Ctrl+V")
  MenuBar()
  MenuItem(7, "Couper" +Chr(9)+"Ctrl+X")
  MenuTitle("Outils")
  MenuItem(8, "Selection Lasso")
EndIf

CreateImage(#Lasso_Image_0, #width,#height,32)
CreateImage(#Lasso_Image_1, #width,#height,32)
CreateImage(#Lasso_Image_2, #width,#height,32)
CreateImage(#Lasso_Image_3, #width,#height,32)
CreateImage(img_tmps, #width,#height,32)

StartDrawing(ImageOutput(#Lasso_Image_3)) ; auteur netmaestro ;) je n'ai mis que la couleur à 204 comme photoshop
For i = 0 To WindowWidth(0) * 2 Step 16
  For j = 0 To WindowWidth(0) * 2 Step 16
    Box(j,i,8,8,RGB(204,204,204))
    Box(j+8,i,8,8,#White)
    Box(j,i+8,8,8,#White)
    Box(j+8,i+8,8,8,RGB(204,204,204))
  Next
Next
StopDrawing()
ImageGadget(#Lasso_Gadget_3, 0, 0, WindowWidth(0), WindowHeight(0), ImageID(#Lasso_Image_3))



capture = 1 ; "capture"  est similaire a "opt"
opt = 0
Repeat
  mx = WindowMouseX(#Lasso_Window_0)
  my = WindowMouseY(#Lasso_Window_0)
 
  Event = WaitWindowEvent()
  Select event
    Case #WM_LBUTTONDOWN
      If IsImage(source)<>0
        If capture = 1
          If opt = 0
            AddElement(v()) ; ajoute une coordonnee au lasso
            v()\x = mx
            v()\y = #height - my
          EndIf
        EndIf
             
        If capture = 0
          If deplace = 0 And ListSize(mescopy())>0
            
            ; selection une copy a deplacer
            LastElement(mescopy())
            my1 = #height - my
            If mx > mescopy()\px And mx < (mescopy()\px + mescopy()\lg)
              If my1 > mescopy()\py And my1 < (mescopy()\py + mescopy()\ht)
                mescopy()\dx = mescopy()\px - mx
                mescopy()\dy = mescopy()\py - my1
                deplace = 1
              EndIf
            EndIf
            
            If deplace = 0
              ForEach mescopy()
                If mx > mescopy()\px And mx < (mescopy()\px + mescopy()\lg)
                  If my1 > mescopy()\py And my1 < (mescopy()\py + mescopy()\ht)
                    mescopy()\dx = mescopy()\px - mx
                    mescopy()\dy = mescopy()\py - my1
                    deplace = 1
                    MoveElement(mescopy(),#PB_List_Last)
                    Break
                  EndIf
                EndIf
              Next
            EndIf
            
          Else
            deplace = 0
          EndIf   
        EndIf
      EndIf
    
    Case #WM_RBUTTONDOWN
      If IsImage(source)<>0
        If capture = 1
          capture = 2
        Else
          If capture = 2 
            capture = 1
          EndIf
        EndIf
        
        If deplace = 0 And capture = 0
          Resultat = MessageRequester("fusionner", "voulez vous fusionner le calque avec 'limage" ,#PB_MessageRequester_YesNoCancel)
          If Resultat = 6
            fusionner(mescopy(),source)
            DeleteElement(mescopy())
            deplace = 0
          EndIf
        EndIf
      EndIf
      
    Case #PB_Event_Menu
      
      Select EventMenu() ; To see which menu has been selected    
        Case 1 ; charge image
          file$ = OpenFileRequester("Image","","",0)
          source = 10
          If Not Load_Image(source,file$)
            MessageRequester("load_image","erreur de chargement",#PB_MessageRequester_Ok | #PB_MessageRequester_Error)
            End
          EndIf
          
          ResizeImage(source,#width,#height,#PB_Image_Smooth)
          CopyImage(source,original)
          SetActiveWindow(#Lasso_Window_0) ; Restore la source
          StartDrawing(WindowOutput(#Lasso_Window_0))
          ;If IsImage(source) : DrawImage(ImageID(original),0,0) : EndIf
          If IsImage(source) : DrawImage(ImageID(source),0,0) : EndIf
          StopDrawing()
          
        Case 2 ; sauve image
          
        Case 3 ; eXit
          End
          
        Case 4 ; annuler
          ClearList(v())
          
        Case 5 ; copier
          If ListSize(v())>0
            If opt = 0
              opt = 1
              create_new_picture(source)
              *Memory = EncodeImage(cible, #PB_ImagePlugin_PNG)
              SetClipboardText(Str(*Memory))
              *Memory = Val(GetClipboardText())
              CatchImage(#Lasso_Image_2, *Memory) ; L'image est en mémoire
              SaveImage(#Lasso_Image_2, "d:\purebasic64\\Imagelassot.png",#PB_ImagePlugin_PNG,32)
            EndIf
            
            ; retour activation de la fenetre principale
            capture = 0
            ClearList(v())
            SetActiveWindow(#Lasso_Window_0) ; Restore la source
            StartDrawing(WindowOutput(#Lasso_Window_0))
            ;If IsImage(source) : DrawImage(ImageID(original),0,0) : EndIf
            If IsImage(source) : DrawImage(ImageID(source),0,0) : EndIf
            StopDrawing()
            ;CopyImage(oroginal,source); on restore l'original
          EndIf
        Case 6 ; coller 

        Case 7 ; couper  

        Case 8 ; lasso
          ClearList(v())         
          opt = 0         
          If capture = 0 : capture = 1 : EndIf
          
      EndSelect
  EndSelect
  
  
  If capture = 2
    If opt = 0
      If mmx<>mx Or mmy<>mmy
        AddElement(v()) ; ajoute une coordonnee au lasso
        v()\x = mx
        v()\y = #height - my
        mmx=mx
        mmy=my
      EndIf 
    EndIf
  EndIf
  
      
  If capture > 0
    If ListSize(v()) > 0 ; "affiche" le lasso
      StartDrawing(WindowOutput(#Lasso_Window_0))
      DrawImage(ImageID(img_tmps),0,0)
      FirstElement(v())
      x1 = v()\x
      y1 = v()\y
      ForEach v()
        x = v()\x
        y = v()\y
        DrawingMode(#PB_2DDrawing_XOr)
        If opt = 0 : LineXY(x1,#height - y1,x,#height - y,$ffffff) : EndIf
        x1=x
        y1=y
      Next   
      StopDrawing()
    EndIf  
  EndIf
  
  
  If deplace = 1
    LastElement(mescopy())
    mescopy()\px = mx + mescopy()\dx
    mescopy()\py = (#height - my) + mescopy()\dy
  EndIf
  
  
  StartDrawing(ImageOutput(img_tmps))
  If source <> 0 
    DrawImage(ImageID(source),0,0)
  Else
    DrawImage(ImageID(#Lasso_Image_3),0,0)
  EndIf
  StopDrawing()
  

  ; update affichage des copy
  ForEach mescopy()
    draw_alpha(mescopy(), img_tmps)
  Next
  
  StartDrawing(WindowOutput(#Lasso_Window_0))
  DrawImage(ImageID(img_tmps),0,0)
  Select capture
    Case 0
      t$="no capture"
    Case 1
      t$="polygon"
    Case 2
      t$="laso"
  EndSelect
  DrawText(0,0,t$) 
  StopDrawing()
  
  ; affichage le rectangle autour de l'image selectionnee
  my1 = #height - my
  ForEach mescopy()
    If mx > mescopy()\px And mx < (mescopy()\px + mescopy()\lg) 
      If my1 > mescopy()\py And my1 < (mescopy()\py + mescopy()\ht)  
        StartDrawing(WindowOutput(#Lasso_Window_0))
        DrawingMode(#PB_2DDrawing_XOr)
        Line(mescopy()\px,#height - mescopy()\py,1,-mescopy()\ht)
        Line(mescopy()\px,#height - mescopy()\py,mescopy()\lg,1)
        Line(mescopy()\px + mescopy()\lg,#height - mescopy()\py,1,-mescopy()\ht)
        Line(mescopy()\px ,#height - mescopy()\py - mescopy()\ht ,mescopy()\lg , 1)
        StopDrawing()
      EndIf
    EndIf  
  Next
  
  
Until Event = #PB_Event_CloseWindow

End

Re: fonction 'lasso'

Publié : ven. 19/mars/2021 15:27
par blendman
salut


Merci, c'est intéressant. Justement , je cherchais comment faire des outils de sélection comme le lasso, baguette magique, etc de gimp/photoshop :).

il y a un peu de flickering quand on utilise le lasso et qu'on bouge la souris.

j'avais lu dans la doc qu'il fallait essayer de regrouper les opérations d'affichage dans le minimum de startdrawing()/stopdrawing() ;).
Ca pourrait réduire ce flickering.

Mais surtout, il faut utiliser le canvasgadget les amis ;)
C'est fait pour ça.

j'ai corrigé vite fait, juste pour que vous voyez la différence, il n'y a plus de flickering avec le canvas, et l'affichage peut s'effectuer en un seul coup, après les opérations (c'est juste un essai).

Code : Tout sélectionner

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

#width = 800
#height = 600

Enumeration
  #Lasso_Window_0
  #Lasso_Window_1
  #Lasso_Image_0
  #Lasso_Image_1
  #Lasso_Image_2
  #Lasso_Image_3
  #Lasso_Gadget_0
  #Lasso_Gadget_1
  #Lasso_Gadget_2
  #Lasso_Gadget_3
  #Canvas_Drawingsurface
  #lasso_Menu_0
EndEnumeration


Structure copys
  index.i
  addr.i
  px.i
  py.i
  lg.i
  ht.i
  dx.i
  dy.i
EndStructure
Global NewList mescopy.copys()

Global source = 0
Global cible = 20
Global original = 40
Global img_tmps = 50

Global NewList V.point()

Macro Coo_Segment( Pa, Pb, Liste )
  *Situation = @Liste
  Pa = Liste : If NextElement( Liste ) = 0 : FirstElement( Liste ) : EndIf
  Pb = Liste : ChangeCurrentElement( Liste, *Situation )
  
EndMacro

; 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 , $ff000000 + r<<16 + g<<8 + b)
      Next
      dif1 = dif1 + dif
    Next
    
    FreeImage(temps) ; supprime l'image 24bits
    
  EndIf
  
  ProcedureReturn 1
EndProcedure
;------------------------------------------------------------------

Procedure fusionner(List mescopy.copys(),cible)
  source_p = mescopy()\addr
  ht1 = mescopy()\ht
  lg1 = mescopy()\lg
  px = mescopy()\px
  py = mescopy()\py
  
  StartDrawing(ImageOutput(cible))
  cible_p = DrawingBuffer()
  ht2 = ImageHeight(cible)
  lg2 = ImageWidth(cible)
  StopDrawing()
  
  For y=0 To ht1-1
    For x=0 To lg1-1
      pos1 = source_p + ((y * lg1) + x) * 4 
      x2 = x + px
      y2 = y + py
      If x2>=0 And x2<lg2 And y2>=0 And y2<ht2
        pos2 = cible_p + ((y2 * lg2) + x2) * 4
        a = PeekA(pos1 + 3)
        If a<>0
          rgb = PeekL(pos1)
          PokeL(pos2  , rgb)
        EndIf       
      EndIf
    Next
  Next
  
  
EndProcedure

Procedure cn_PnPoly( px,py , List Polylist.point() )
  Define pa.point, pb.point, cn.l
  ForEach Polylist() : Coo_Segment( Pa, Pb, Polylist() )
    If (((pa\y <= py) And (pb\y > py)) Or ((pa\y > py) And (pb\y <= py)))
      vt.f = (py - pa\y) / (pb\y - pa\y);
      If (px < pa\x + vt * (pb\x - pa\x)) ;
        cn+1                              ; ;
      EndIf
    EndIf
  Next
  ProcedureReturn (cn&1); // 0 if even (out), and 1 if odd (in)
EndProcedure

Procedure copy(source , cible , px , py)
  
  StartDrawing(ImageOutput(source))
  source_p = DrawingBuffer()
  ht1 = ImageHeight(source)
  lg1 = ImageWidth(source)
  StopDrawing()
  
  StartDrawing(ImageOutput(cible))
  cible_p = DrawingBuffer()
  ht2 = ImageHeight(cible)
  lg2 = ImageWidth(cible)
  StopDrawing()
  
  StartDrawing(ImageOutput(#Lasso_Image_3))
  lasso_p = DrawingBuffer()
  ht3 = ImageHeight(#Lasso_Image_3)
  lg3 = ImageWidth(#Lasso_Image_3)
  StopDrawing()
  
  ; si le pixel est dans le 'lasso' : pixel_alpha=255 : si non : pixel_alpha=0
  For y=0 To ht2-1
    For x=0 To lg2-1
      pos2 = ((y*lg2)+x)*4
      PokeL(cible_p + pos2 , 0) ; rempli l'image de 0 ( a=0 : r=0 : g=0 : b=0)
      If cn_PnPoly( px+x,py+y , v() )> 0
        y1 = (y + py) * lg1
        pos1 = ((y1+x+px) * 4); lit l'image source rgb
        argb = PeekL(source_p + pos1)
        PokeL(cible_p + pos2 , argb) ; $ff000000 = alpha
        
        ; cree le "" sur l'image source
        rgb = PeekL(lasso_p + ((y*lg3)+x)*4)
        PokeL(source_p + pos1,rgb & $00ffffff)
      EndIf
    Next
  Next
EndProcedure

Procedure create_new_picture(source)
  ; calcul la taille de l'image selectionnée par le 'lasso'
  If ListSize(v()) = 0 : ProcedureReturn : EndIf
  pminx=999999
  pminy=999999
  pmaxx=0
  pmaxy=0
  ForEach v()   
    If pminx > v()\x : pminx = v()\x :EndIf
    If pminy > v()\y : pminy = v()\y :EndIf
    If pmaxx < v()\x : pmaxx = v()\x :EndIf
    If pmaxy < v()\y : pmaxy = v()\y :EndIf
  Next
  lg = pmaxx - pminx
  ht = pmaxy - pminy
  
  ; cree la nouvelle image
  CreateImage(cible,lg,ht,32, #PB_Image_Transparent)
  copy(source , cible ,pminx , pminy)
  
  OpenWindow(#Lasso_Window_1, 0, 0, lg, ht, "Calque", #PB_Window_SystemMenu )
  StartDrawing(ImageOutput(#Lasso_Image_1))
  DrawingMode(#PB_2DDrawing_AlphaBlend)
  DrawImage(ImageID(#Lasso_Image_3), 0, 0)
  DrawAlphaImage(ImageID(cible),0,0)
  StopDrawing()
  
  img = CopyImage(cible,#PB_Any)
  AddElement(mescopy())
  StartDrawing(ImageOutput(img))
  mescopy()\index = img
  mescopy()\addr = DrawingBuffer()
  mescopy()\ht = ImageHeight(img)
  mescopy()\lg = ImageWidth(img)
  mescopy()\px = ListSize(mescopy()) * 25
  mescopy()\py = ListSize(mescopy()) * 25
  StopDrawing()
  ImageGadget(#Lasso_Gadget_1, 0, 0, WindowWidth(1), WindowHeight(1), ImageID(#Lasso_Image_1))
EndProcedure


Procedure draw_alpha(List mescopy.copys(),cible)
  
  source_p = mescopy()\addr
  ht1 = mescopy()\ht
  lg1 = mescopy()\lg
  px = mescopy()\px
  py = mescopy()\py
  
  StartDrawing(ImageOutput(cible))
  cible_p = DrawingBuffer()
  ht2 = ImageHeight(cible)
  lg2 = ImageWidth(cible)
  StopDrawing()
  
  For y=0 To ht1-1
    For x=0 To lg1-1
      pos1 = source_p + ((y * lg1) + x) * 4 
      x2 = x + px
      y2 = y + py
      If x2>=0 And x2<lg2 And y2>=0 And y2<ht2
        pos2 = cible_p + ((y2 * lg2) + x2) * 4
        a = PeekA(pos1 + 3)
        If a<>0
          rgb = PeekL(pos1)
          PokeL(pos2, rgb)
        EndIf       
      EndIf
    Next
  Next
  
EndProcedure



OpenWindow(#Lasso_Window_0, 0, 0, #width, #height, "lasso- " + Str(TotalSeconds),#PB_Window_SystemMenu|#PB_Window_ScreenCentered)

If CreateMenu(#lasso_Menu_0, WindowID(#Lasso_Window_0))
  MenuTitle("Fichiers")
  MenuItem(1, "Ouvrir" +Chr(9)+"Ctrl+O")
  MenuBar()
  MenuItem(2, "Enregistrer sous"+Chr(9)+"Ctrl+R")
  MenuBar()
  MenuItem(3, "Quitter" +Chr(9)+"Ctrl+Q")
  MenuTitle("Edition")
  MenuItem(4, "Annuler" +Chr(9)+"Ctrl+Z")
  MenuBar()
  MenuItem(5, "Copier" +Chr(9)+"Ctrl+C")
  MenuItem(6, "Coller" +Chr(9)+"Ctrl+V")
  MenuBar()
  MenuItem(7, "Couper" +Chr(9)+"Ctrl+X")
  MenuTitle("Outils")
  MenuItem(8, "Selection Lasso")
EndIf

CreateImage(#Lasso_Image_0, #width,#height,32)
CreateImage(#Lasso_Image_1, #width,#height,32)
CreateImage(#Lasso_Image_2, #width,#height,32)
CreateImage(#Lasso_Image_3, #width,#height,32)
CreateImage(img_tmps, #width,#height,32)

StartDrawing(ImageOutput(#Lasso_Image_3)) ; auteur netmaestro ;) je n'ai mis que la couleur à 204 comme photoshop
For i = 0 To WindowWidth(0) * 2 Step 16
  For j = 0 To WindowWidth(0) * 2 Step 16
    Box(j,i,8,8,RGB(204,204,204))
    Box(j+8,i,8,8,#White)
    Box(j,i+8,8,8,#White)
    Box(j+8,i+8,8,8,RGB(204,204,204))
  Next
Next
StopDrawing()
; ImageGadget(#Lasso_Gadget_3, 0, 0, WindowWidth(0), WindowHeight(0), ImageID(#Lasso_Image_3))


CanvasGadget(#Canvas_Drawingsurface, 0, 0, WindowWidth(0), WindowHeight(0))

capture = 1 ; "capture"  est similaire a "opt"
opt = 0

Repeat
  mx = WindowMouseX(#Lasso_Window_0)
  my = WindowMouseY(#Lasso_Window_0)
  
  Event = WaitWindowEvent()
  Select event
      
    Case #WM_LBUTTONDOWN
      If capture = 1
        If opt = 0
          AddElement(v()) ; ajoute une coordonnee au lasso
          v()\x = mx
          v()\y = #height - my
        EndIf
      EndIf
      
      If capture = 0
        If deplace = 0 And ListSize(mescopy())>0
          
          ; selection une copy a deplacer
          LastElement(mescopy())
          my1 = #height - my
          If mx > mescopy()\px And mx < (mescopy()\px + mescopy()\lg)
            If my1 > mescopy()\py And my1 < (mescopy()\py + mescopy()\ht)
              mescopy()\dx = mescopy()\px - mx
              mescopy()\dy = mescopy()\py - my1
              deplace = 1
            EndIf
          EndIf
          
          If deplace = 0
            ForEach mescopy()
              If mx > mescopy()\px And mx < (mescopy()\px + mescopy()\lg)
                If my1 > mescopy()\py And my1 < (mescopy()\py + mescopy()\ht)
                  mescopy()\dx = mescopy()\px - mx
                  mescopy()\dy = mescopy()\py - my1
                  deplace = 1
                  MoveElement(mescopy(),#PB_List_Last)
                  Break
                EndIf
              EndIf
            Next
          EndIf
          
        Else
          deplace = 0
        EndIf   
      EndIf
      
    Case #WM_RBUTTONDOWN
      If deplace = 0 And capture = 0
        Resultat = MessageRequester("fusionner", "voulez vous fusionner le calque avec 'limage" ,#PB_MessageRequester_YesNoCancel)
        If Resultat = 6
          fusionner(mescopy(),source)
          DeleteElement(mescopy())
          deplace = 0
        EndIf
      EndIf
      
      
    Case #PB_Event_Menu
      
      Select EventMenu() ; To see which menu has been selected   
        Case 1           ; charge image
          file$ = OpenFileRequester("Image","","",0)
          source = 10 
          If Not Load_Image(source,file$)
            MessageRequester("load_image","erreur de chargement",#PB_MessageRequester_Ok | #PB_MessageRequester_Error)
            End
          EndIf
          
          ResizeImage(source,#width,#height,#PB_Image_Smooth)
          CopyImage(source, original)
          SetActiveWindow(#Lasso_Window_0) ; Restore la source
;           StartDrawing(WindowOutput(#Lasso_Window_0))
;           ;If IsImage(source) : DrawImage(ImageID(original),0,0) : EndIf
;           If IsImage(source) : DrawImage(ImageID(source),0,0) : EndIf
;           StopDrawing()
          
        Case 2 ; sauve image
          
        Case 3 ; eXit
          End
          
        Case 4 ; annuler
          ClearList(v())
          
        Case 5 ; copier
          If opt = 0
            opt = 1
            create_new_picture(source)
            *Memory = EncodeImage(cible, #PB_ImagePlugin_PNG)
            SetClipboardText(Str(*Memory))
            *Memory = Val(GetClipboardText())
            CatchImage(#Lasso_Image_2, *Memory) ; L'image est en mémoire
            SaveImage(#Lasso_Image_2, "d:\purebasic64\\Imagelassot.png",#PB_ImagePlugin_PNG,32)
          EndIf
          
          ; retour activation de la fenetre principale
          capture = 0
          ClearList(v())
          SetActiveWindow(#Lasso_Window_0) ; Restore la source
          StartDrawing(WindowOutput(#Lasso_Window_0))
          ;If IsImage(source) : DrawImage(ImageID(original),0,0) : EndIf
          If IsImage(source) : DrawImage(ImageID(source),0,0) : EndIf
          StopDrawing()
          ;CopyImage(oroginal,source); on restore l'original
          
        Case 6 ; coller
          
        Case 7 ; couper 
          
        Case 8 ; lasso
          ClearList(v())         
          opt = 0         
          If capture = 0 : capture = 1 : EndIf
          
      EndSelect
  EndSelect
  
  
  ; update affichage des copy
  ForEach mescopy()
    draw_alpha(mescopy(), img_tmps)
  Next
  
  If StartDrawing(CanvasOutput(#Canvas_Drawingsurface))
    
    ; on dessine le fond
    DrawImage(ImageID(#Lasso_Image_3),0,0)
    
    ; on dessine l'image
    If source <> 0
      DrawImage(ImageID(source),0,0)
    EndIf
      
    ; on dessine le lasso
    If capture = 1
      If ListSize(v()) > 0 ; "affiche" le lasso
        ;DrawImage(ImageID(img_tmps),0,0)
        
        DrawingMode(#PB_2DDrawing_XOr)
        FirstElement(v())
        x1 = v()\x
        y1 = v()\y
        ForEach v()
          x = v()\x
          y = v()\y
           
          If opt = 0 
            LineXY(x1,#height - y1,x,#height - y,$ffffff) 
            ;LineXY(x1-1,#height - y1-1,x-1,#height - y-1,$0000000) 
          EndIf
          x1=x
          y1=y
        Next   
        
      EndIf 
    EndIf
    
    ; affichage le rectangle autour de l'image selectionnee
    my1 = #height - my
    ForEach mescopy()
      If mx > mescopy()\px And mx < (mescopy()\px + mescopy()\lg)
        If my1 > mescopy()\py And my1 < (mescopy()\py + mescopy()\ht) 
          DrawingMode(#PB_2DDrawing_XOr)
          Line(mescopy()\px,#height - mescopy()\py,1,-mescopy()\ht)
          Line(mescopy()\px,#height - mescopy()\py,mescopy()\lg,1)
          Line(mescopy()\px + mescopy()\lg,#height - mescopy()\py,1,-mescopy()\ht)
          Line(mescopy()\px ,#height - mescopy()\py - mescopy()\ht ,mescopy()\lg , 1)
        EndIf
      EndIf 
    Next
    
    StopDrawing()
  EndIf
  
  If deplace = 1
    LastElement(mescopy())
    mescopy()\px = mx + mescopy()\dx
    mescopy()\py = (#height - my) + mescopy()\dy
  EndIf
  
Until Event = #PB_Event_CloseWindow

End

Re: fonction 'lasso'

Publié : sam. 20/mars/2021 20:10
par Kwai chang caine
Kernadec a écrit :Je suis heureux de te lire
Et moi donc :wink:
Merci à toi de ton explication 8)
J'avais compris que le lasso était comme dans le logiciel que j'utilise depuis 20 ans pour faire toutes les conneries que j'ai déposé sur les forums PB :mrgreen:
Il y a les deux fonctions, le lasso et les lignes connectées au choix

@MANABABEL
Niquel cette fois y'a les deux méthodes comme dans mon logiciel préféré :wink:
Merci de ce partage 8)

@BLENDMAN
C'est vrai tu as raison le clignotement change au déplacement de la souris et c'est un peu déroutant :wink:
Par contre dans ton code, y'a plus du tout de clignotement, et c'est vrai que dans les logiciels du commerce que j'utilise, le clignotement de la sélection existe bel et bien, c'est peut être ce que Manababel et Kernadec ont voulu faire apparaitre ?
Et c'est bien aussi que ça clignote pour différencier la sélection de certains traits qui peuvent être sur le dessin sélectionné :idea:
Maintenant que le clignotement soit modifié au déplacement souris...là...je vois pas pourquoi 8O

Re: fonction 'lasso'

Publié : dim. 21/mars/2021 11:07
par blendman
Coucou KCC ;)
Kwai chang caine a écrit : @BLENDMAN
C'est vrai tu as raison le clignotement change au déplacement de la souris et c'est un peu déroutant :wink:
Par contre dans ton code, y'a plus du tout de clignotement, et c'est vrai que dans les logiciels du commerce que j'utilise, le clignotement de la sélection existe bel et bien, c'est peut être ce que Manababel et Kernadec ont voulu faire apparaitre ?
Et c'est bien aussi que ça clignote pour différencier la sélection de certains traits qui peuvent être sur le dessin sélectionné :idea:
Maintenant que le clignotement soit modifié au déplacement souris...là...je vois pas pourquoi 8O
OUi, dans les applications de retouche photo ou de dessins, il y a des sélections avec des pointillés. En fait, quand on regarde, ça ne clignote pas vraiment, je crois que les pointillés se déplacent sur la ligne de selection.

Ca donne ce genre de chose :

Code : Tout sélectionner

If OpenWindow(0, 0, 0, 400, 200, "VectorDrawing", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  CanvasGadget(0, 0, 0, 400, 200)
  
  U.d = 5
  Dim dashes.d(1)
  v.d = 10
  
  Repeat
    Event = WindowEvent()
    
    If StartVectorDrawing(CanvasVectorOutput(0))
      
      MovePathCursor(0, 0)
      AddPathBox(0, 0, 400, 200)
      VectorSourceColor(RGBA(255,255,255, 255))
      FillPath()
      
      MovePathCursor(40, 20)
      
        AddPathLine(80, 0, #PB_Path_Relative)
        AddPathLine(120, 60, #PB_Path_Relative)
        AddPathLine(100, 100, #PB_Path_Relative)
      ClosePath()
      
      v+0.0003
      If v > 5*2
        v=u
      EndIf
      
      VectorSourceColor(RGBA(0, 0, 0, 255))
      dashes(0) = u
      dashes(1) = v
      
      
;       CustomDashPath(1, dashes(), #PB_Path_Default, v)  ; don't work ? 
      CustomDashPath(1, dashes())
      
      StopVectorDrawing()
    EndIf
    
    
  Until Event = #PB_Event_CloseWindow
EndIf
Il y a un bug avec CustomDashPath(), qui ne fonctionne plus si on mets les paramètres additionnels, c'est pour ça que j'ai dû utiliser une technique un peu bilouteuse ^^.

D'ailleurs l'emploi de la lib vector pourrait être intéressante pour l'affichage de la ligne de sélection ;).

Re: fonction 'lasso'

Publié : dim. 21/mars/2021 11:36
par kernadec
bjr Blendman
pour ce qui est de la saisie en mode lasso
je post deux codes un de "einander de 2006"
et l'autre de "netmaestro" celui la est particulièrement costaud
il ne font que le lasso, il faut manque le capture image avec encodeimage()

#####code einander
https://www.purebasic.fr/english/viewto ... 12&t=22465

#####code netmaestro
http://www.purebasic.fr/english/viewtop ... 13&t=44892

ps: En ce moment, j'ai mis le code lasso de coté car je me suis replongé dans un de mes code sur l'astrologie et je peux pas le quitter, j'ai trop de mémoire impliquée dans cette mise a jours...car ca m'a bien pris le chou de me remettre dans ce vieux code :mrgreen:
cordialement

Re: fonction 'lasso'

Publié : dim. 21/mars/2021 11:48
par kernadec
si le code de netmaestro bug
il faut ajouter ce bout de code avant le commentaire GLOBALS
deplacer le bloc code *unpacked juste après la procèdure

Code : Tout sélectionner

Procedure.i UnpackMemory(Source, Destination) ;remplace unpackmemory
		UseJCALG1Packer()
		ProcedureReturn UncompressMemory(Source, 0, Destination, 0, #PB_PackerPlugin_JCALG1)
EndProcedure

*unpacked = AllocateMemory(12344)
UnpackMemory(?PicPak, *unpacked)
hatch = CatchImage(#PB_Any, *unpacked, 12344)
FreeMemory(*unpacked)

;==============================================
;                 GLOBALS
;==============================================


Re: fonction 'lasso'

Publié : lun. 22/mars/2021 16:04
par blendman
Merci ;)


En fait, je suis très intéressé par l'intégration de la sélection (polygonal et lasso) et bien sûr la capture des pixels de l'image (copier, coller, etc...), pour l'intégrer dans mon logiciel animatoon, car c'est vraiment un outil nécessaire je trouve.

Donc, je vais regarder tout ceci lorsque j'intégrerai de meilleurs outils de sélection, car pour le moment, je n'ai qu'une sélection par rectangle, et c'est un peu léger je trouve ^^.

Je pourrais d'ailleurs ajouter facilement une sélection qu'on dessine nous-même (avec un drawingmode() clip alpha, il doit y avoir moyen de copier-coller le résultat sur une nouvelle image je pense).

Je n'utilise pas beaucoup DrawingBuffer(), car je n'ai pas encore compris comment ça fonctionne.
Je trouve que la doc n'est pas du tout explicite et facile à comprendre à ce sujet.
Il faut que je me penche là-dessus lorsque j'aurais un peu de temps, mais je n'ai pas encore trouvé d'explication sur ça.

Re: fonction 'lasso'

Publié : lun. 22/mars/2021 18:29
par manababel
bonjour
en ce moment, je n'ai pas trop le temps de travailler sur ce projet.

le problème de flickering est un bug, ce n'est pas voulu

plus j'avance sur ce programme, plus il devient confus, je dois repenser le programme.


les parties les plus importantes(la basse) du programme sont les fonctions suivantes;
-Create_new_picture ( détermine la taille(cadre) de l'image sélectionnée avec le polygone)
-copy ( c'est dans cette fonction que vous pouvez copier/supprime et/ou coller l'image sélectionnée)
-Cn_PnPoly ( détermine quel point de l'image est à l'intérieure/extérieure du polygone)


blendman :
"Mais surtout, il faut utiliser le canvasgadget les amis ;)
C'est fait pour ça."
je suis d'acore avec toi blendman, on en a déjà discuté Avec Kernadec, mais les "canvasgadget", je ne metrise pas tu tout.

j'utilise DrawingBuffer() car c'est plus rapide et plus proche du language Asm d'utilser peek/poke, mais ç'a marche aussi avec plot/point, tab(x, y) ....

pour la version ci-dessous , je n'ai pas tenu compte de vos modifications (pour le moment).
il y a quelques ajouts en plus.
(toutes les "images" sont en 32 bits car c'est plus facile de gerer le canal alpha)

Code : Tout sélectionner

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

#width = 800
#height = 600

Enumeration
#Lasso_Window_0
#Lasso_Window_1
#Lasso_Image_0
#Lasso_Image_1
#Lasso_Image_2
#Lasso_Image_3
#Lasso_Gadget_0
#Lasso_Gadget_1
#Lasso_Gadget_2
#Lasso_Gadget_3
#lasso_Menu_0
EndEnumeration


Structure copys
  index.i
  addr.i
  px.i
  py.i
  lg.i
  ht.i
  dx.i
  dy.i
EndStructure
Global NewList mescopy.copys()

Global source = 0
Global cible = 20
Global original = 40
Global img_tmps = 50

Global NewList V.point()

Macro Coo_Segment( Pa, Pb, Liste )
  *Situation = @Liste
  Pa = Liste : If NextElement( Liste ) = 0 : FirstElement( Liste ) : EndIf
  Pb = Liste : ChangeCurrentElement( Liste, *Situation )
 
EndMacro

; 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 , $ff000000 + r<<16 + g<<8 + b)
      Next
      dif1 = dif1 + dif
    Next
   
    FreeImage(temps) ; supprime l'image 24bits
   
  EndIf

  ProcedureReturn 1
EndProcedure
;------------------------------------------------------------------

Procedure fusionner(List mescopy.copys(),cible)
  source_p = mescopy()\addr
  ht1 = mescopy()\ht
  lg1 = mescopy()\lg
  px = mescopy()\px
  py = mescopy()\py
 
  StartDrawing(ImageOutput(cible))
  cible_p = DrawingBuffer()
  ht2 = ImageHeight(cible)
  lg2 = ImageWidth(cible)
  StopDrawing()
 
  For y=0 To ht1-1
    For x=0 To lg1-1
      pos1 = source_p + ((y * lg1) + x) * 4 
      x2 = x + px
      y2 = y + py
      If x2>=0 And x2<lg2 And y2>=0 And y2<ht2
        pos2 = cible_p + ((y2 * lg2) + x2) * 4
        a = PeekA(pos1 + 3)
        If a<>0
          rgb = PeekL(pos1)
          PokeL(pos2  , rgb)
        EndIf       
      EndIf
    Next
  Next


EndProcedure

Procedure cn_PnPoly( px,py , List Polylist.point() )
  Define pa.point, pb.point, cn.l
  ForEach Polylist() : Coo_Segment( Pa, Pb, Polylist() )
    If (((pa\y <= py) And (pb\y > py)) Or ((pa\y > py) And (pb\y <= py)))
      vt.f = (py - pa\y) / (pb\y - pa\y);
      If (px < pa\x + vt * (pb\x - pa\x)) ;
        cn+1 ; ;
      EndIf
    EndIf
  Next
  ProcedureReturn (cn&1); // 0 if even (out), and 1 if odd (in)
EndProcedure

Procedure copy(source , cible , px , py,opt)

  StartDrawing(ImageOutput(source))
  source_p = DrawingBuffer()
  ht1 = ImageHeight(source)
  lg1 = ImageWidth(source)
  StopDrawing()
 
  StartDrawing(ImageOutput(cible))
  cible_p = DrawingBuffer()
  ht2 = ImageHeight(cible)
  lg2 = ImageWidth(cible)
  StopDrawing()
 
  StartDrawing(ImageOutput(#Lasso_Image_3))
  lasso_p = DrawingBuffer()
  ht3 = ImageHeight(#Lasso_Image_3)
  lg3 = ImageWidth(#Lasso_Image_3)
  StopDrawing()
 
  ; si le pixel est dans le 'lasso' : pixel_alpha=255 : si non : pixel_alpha=0
  For y=0 To ht2-1
    For x=0 To lg2-1
      pos2 = ((y*lg2)+x)*4
      PokeL(cible_p + pos2 , 0) ; rempli l'image de 0 ( a=0 : r=0 : g=0 : b=0)
      If cn_PnPoly( px+x,py+y , v() )> 0
        y1 = (y + py) * lg1
        pos1 = ((y1+x+px) * 4); lit l'image source rgb
        argb = PeekL(source_p + pos1)
        PokeL(cible_p + pos2 , argb) ; $ff000000 = alpha
       
        If opt > 0
          ; cree le "" sur l'image source
          rgb = PeekL(lasso_p + ((y*lg3)+x)*4)
          PokeL(source_p + pos1,rgb & $00ffffff)
        EndIf
      EndIf
    Next
  Next
EndProcedure

Procedure create_new_picture(source,opt=0)
  Debug opt
  ; calcul la taille de l'image selectionnée par le 'lasso'
  If ListSize(v()) = 0 : ProcedureReturn : EndIf
  pminx=999999
  pminy=999999
  pmaxx=0
  pmaxy=0
  ForEach v()   
    If pminx > v()\x : pminx = v()\x :EndIf
    If pminy > v()\y : pminy = v()\y :EndIf
    If pmaxx < v()\x : pmaxx = v()\x :EndIf
    If pmaxy < v()\y : pmaxy = v()\y :EndIf
  Next
  lg = pmaxx - pminx
  ht = pmaxy - pminy
 
  ; cree la nouvelle image
  CreateImage(cible,lg,ht,32, #PB_Image_Transparent)
  copy(source , cible ,pminx , pminy,opt)
 
  If opt = 1 ; on supprime la partie de l'image selectionné
    FreeImage(cible)
    ProcedureReturn
  EndIf
 
  ; ici peut etre ajouter une fonction qui addtionne tous les masque dans la deuxieme fenetre
  OpenWindow(#Lasso_Window_1, 0, 0, lg, ht, "Calque", #PB_Window_SystemMenu )
  StartDrawing(ImageOutput(#Lasso_Image_1))
  DrawingMode(#PB_2DDrawing_AlphaBlend)
  DrawImage(ImageID(#Lasso_Image_3), 0, 0)
  DrawAlphaImage(ImageID(cible),0,0)
  StopDrawing()
 
  img = CopyImage(cible,#PB_Any)
  AddElement(mescopy())
  StartDrawing(ImageOutput(img))
  mescopy()\index = img
  mescopy()\addr = DrawingBuffer()
  mescopy()\ht = ImageHeight(img)
  mescopy()\lg = ImageWidth(img)
  mescopy()\px = ListSize(mescopy()) * 25
  mescopy()\py = ListSize(mescopy()) * 25
  StopDrawing()
  ImageGadget(#Lasso_Gadget_1, 0, 0, WindowWidth(1), WindowHeight(1), ImageID(#Lasso_Image_1))
EndProcedure


Procedure draw_alpha(List mescopy.copys(),cible)

  source_p = mescopy()\addr
  ht1 = mescopy()\ht
  lg1 = mescopy()\lg
  px = mescopy()\px
  py = mescopy()\py
 
  StartDrawing(ImageOutput(cible))
  cible_p = DrawingBuffer()
  ht2 = ImageHeight(cible)
  lg2 = ImageWidth(cible)
  StopDrawing()
 
  For y=0 To ht1-1
    For x=0 To lg1-1
      pos1 = source_p + ((y * lg1) + x) * 4 
      x2 = x + px
      y2 = y + py
      If x2>=0 And x2<lg2 And y2>=0 And y2<ht2
        pos2 = cible_p + ((y2 * lg2) + x2) * 4
        a = PeekA(pos1 + 3)
        If a<>0
          rgb = PeekL(pos1)
          PokeL(pos2, rgb)
        EndIf       
      EndIf
    Next
  Next
 
EndProcedure


;-- programme
OpenWindow(#Lasso_Window_0, 0, 0, #width, #height, "lasso- " + Str(TotalSeconds),#PB_Window_SystemMenu|#PB_Window_ScreenCentered)

If CreateMenu(#lasso_Menu_0, WindowID(#Lasso_Window_0))
  MenuTitle("Fichiers")
  MenuItem(1, "Ouvrir" +Chr(9)+"Ctrl+O")
  MenuBar()
  MenuItem(2, "Enregistrer sous"+Chr(9)+"Ctrl+R")
  MenuBar()
  MenuItem(3, "Quitter" +Chr(9)+"Ctrl+Q")
  MenuTitle("Edition")
  MenuItem(4, "Annuler" +Chr(9)+"Ctrl+Z")
  MenuBar()
  MenuItem(5, "Copier" +Chr(9)+"Ctrl+C")
  MenuItem(6, "Coller" +Chr(9)+"Ctrl+V")
  MenuBar()
  MenuItem(7, "Couper" +Chr(9)+"Ctrl+X")
  MenuItem(8, "Coller & Couper" )
  MenuBar()
  MenuItem(9, "Undo" )
  MenuTitle("Outils")
  MenuItem(10, "Selection Lasso")
EndIf

CreateImage(#Lasso_Image_0, #width,#height,32)
CreateImage(#Lasso_Image_1, #width,#height,32)
CreateImage(#Lasso_Image_2, #width,#height,32)
CreateImage(#Lasso_Image_3, #width,#height,32)
CreateImage(img_tmps, #width,#height,32)

StartDrawing(ImageOutput(#Lasso_Image_3)) ; auteur netmaestro ;) je n'ai mis que la couleur à 204 comme photoshop
For i = 0 To WindowWidth(0) * 2 Step 16
  For j = 0 To WindowWidth(0) * 2 Step 16
    Box(j,i,8,8,RGB(204,204,204))
    Box(j+8,i,8,8,#White)
    Box(j,i+8,8,8,#White)
    Box(j+8,i+8,8,8,RGB(204,204,204))
  Next
Next
StopDrawing()
ImageGadget(#Lasso_Gadget_3, 0, 0, WindowWidth(0), WindowHeight(0), ImageID(#Lasso_Image_3))



capture = 1 ; "capture"  est similaire a "opt"
opt = 0
Repeat
  mx = WindowMouseX(#Lasso_Window_0)
  my = WindowMouseY(#Lasso_Window_0)

  Event = WaitWindowEvent()
  Select event
    Case #WM_LBUTTONDOWN
      If IsImage(source)<>0
        If capture = 1
          If opt = 0
            AddElement(v()) ; ajoute une coordonnee au lasso
            v()\x = mx
            v()\y = #height - my
          EndIf
        EndIf
             
        If capture = 0
          If deplace = 0 And ListSize(mescopy())>0
           
            ; selection une copy a deplacer
            LastElement(mescopy())
            my1 = #height - my
            If mx > mescopy()\px And mx < (mescopy()\px + mescopy()\lg)
              If my1 > mescopy()\py And my1 < (mescopy()\py + mescopy()\ht)
                mescopy()\dx = mescopy()\px - mx
                mescopy()\dy = mescopy()\py - my1
                deplace = 1
              EndIf
            EndIf
           
            If deplace = 0
              ForEach mescopy()
                If mx > mescopy()\px And mx < (mescopy()\px + mescopy()\lg)
                  If my1 > mescopy()\py And my1 < (mescopy()\py + mescopy()\ht)
                    mescopy()\dx = mescopy()\px - mx
                    mescopy()\dy = mescopy()\py - my1
                    deplace = 1
                    MoveElement(mescopy(),#PB_List_Last)
                    Break
                  EndIf
                EndIf
              Next
            EndIf
           
          Else
            deplace = 0
          EndIf   
        EndIf
      EndIf
   
    Case #WM_RBUTTONDOWN
      If IsImage(source)<>0 ; selectionne le mode polygone ou le mode lasso
        If capture = 1
          capture = 2
        Else
          If capture = 2
            capture = 1
          EndIf
        EndIf
       
        If deplace = 0 And capture = 0
          Resultat = MessageRequester("fusionner", "voulez vous fusionner le calque avec 'limage" ,#PB_MessageRequester_YesNoCancel)
          If Resultat = 6
            fusionner(mescopy(),source)
            DeleteElement(mescopy())
            deplace = 0
          EndIf
        EndIf
      EndIf
     
    Case #PB_Event_Menu
     
      Select EventMenu() ; To see which menu has been selected   
        Case 1 ; charge image
          file$ = OpenFileRequester("Image","","",0)
          source = 10
          If Not Load_Image(source,file$)
            MessageRequester("load_image","erreur de chargement",#PB_MessageRequester_Ok | #PB_MessageRequester_Error)
            End
          EndIf
         
          ResizeImage(source,#width,#height,#PB_Image_Smooth)
          CopyImage(source,original)
          SetActiveWindow(#Lasso_Window_0) ; Restore la source
          StartDrawing(WindowOutput(#Lasso_Window_0))
          ;If IsImage(source) : DrawImage(ImageID(original),0,0) : EndIf
          If IsImage(source) : DrawImage(ImageID(source),0,0) : EndIf
          StopDrawing()
         
        Case 2 ; sauve image
         
        Case 3 ; eXit
          End
         
        Case 4 ; annuler
          ClearList(v())
         
        ;-- copier
        Case 5 ; copier
          If capture = 0
            If ListSize(mescopy())>0
              t_index=mescopy()\index
              t_px=mescopy()\px
              t_py=mescopy()\py
             
              img = CopyImage(mescopy()\index,#PB_Any)
              StartDrawing(ImageOutput(img))
              AddElement(mescopy())
              mescopy()\index = img
              mescopy()\addr = DrawingBuffer()
              mescopy()\ht = ImageHeight(img)
              mescopy()\lg = ImageWidth(img)
              mescopy()\px = t_px+10
              mescopy()\py = t_py+15
              StopDrawing()
             
            EndIf
           
            Else
              If ListSize(v())>0
                If opt = 0
                  opt = 1
                  create_new_picture(source)
                  *Memory = EncodeImage(cible, #PB_ImagePlugin_PNG)
                  SetClipboardText(Str(*Memory))
                  *Memory = Val(GetClipboardText())
                  CatchImage(#Lasso_Image_2, *Memory) ; L'image est en mémoire
                  SaveImage(#Lasso_Image_2, "d:\purebasic64\\Imagelassot.png",#PB_ImagePlugin_PNG,32)
                EndIf
               
                ; retour activation de la fenetre principale
                capture = 0
                ClearList(v())
                SetActiveWindow(#Lasso_Window_0) ; Restore la source
                StartDrawing(WindowOutput(#Lasso_Window_0))
                ;If IsImage(source) : DrawImage(ImageID(original),0,0) : EndIf
                If IsImage(source) : DrawImage(ImageID(source),0,0) : EndIf
                StopDrawing()
                ;CopyImage(oroginal,source); on restore l'original
              EndIf
            EndIf
           
        ;-- coller   
          Case 6 ; coller
            If capture = 0
              If ListSize(mescopy())>0
                fusionner(mescopy(),source)
                DeleteElement(mescopy())
              EndIf
            EndIf
             
        ;-- couper
        Case 7 ; couper 
          If capture = 0
            If ListSize(mescopy())>0
              FreeImage((mescopy()\index))
              DeleteElement(mescopy())
            EndIf
          Else
           
            If ListSize(v())>0
              If opt = 0
                opt = 1
                create_new_picture(source,1)
                capture = 0
                ClearList(v())
                SetActiveWindow(#Lasso_Window_0) ; Restore la source           
                StartDrawing(WindowOutput(#Lasso_Window_0))
                If IsImage(source) : DrawImage(ImageID(source),0,0) : EndIf
                StopDrawing()
              EndIf
            EndIf
          EndIf
         
        ;-- coller & couper
        Case 8
          If capture > 0
            If ListSize(v())>0
              If opt = 0
                opt = 1
                create_new_picture(source,2)
                capture = 0
                ClearList(v())
                SetActiveWindow(#Lasso_Window_0) ; Restore la source           
                StartDrawing(WindowOutput(#Lasso_Window_0))
                If IsImage(source) : DrawImage(ImageID(source),0,0) : EndIf
                StopDrawing()
              EndIf
            EndIf
          EndIf
         
        ;-- undo
        Case 9
          If ListSize(v())>0
            DeleteElement(v())
          EndIf
         
        Case 10 ; lasso
          ClearList(v())         
          opt = 0         
          If capture = 0 : capture = 1 : EndIf
         
      EndSelect
  EndSelect
 
 
  If capture = 2
    If opt = 0
      If mmx<>mx Or mmy<>mmy
        AddElement(v()) ; ajoute une coordonnee au lasso
        v()\x = mx
        v()\y = #height - my
        mmx=mx
        mmy=my
      EndIf
    EndIf
  EndIf
 
     
  If capture > 0
    If ListSize(v()) > 0 ; "affiche" le lasso
      StartDrawing(WindowOutput(#Lasso_Window_0))
      DrawImage(ImageID(img_tmps),0,0)
      FirstElement(v())
      x1 = v()\x
      y1 = v()\y
      ForEach v()
        x = v()\x
        y = v()\y
        DrawingMode(#PB_2DDrawing_XOr)
        If opt = 0 : LineXY(x1,#height - y1,x,#height - y,$ffffff) : EndIf
        x1=x
        y1=y
      Next   
      StopDrawing()
    EndIf 
  EndIf
 
 
  If deplace = 1
    LastElement(mescopy())
    mescopy()\px = mx + mescopy()\dx
    mescopy()\py = (#height - my) + mescopy()\dy
  EndIf
 
 
  StartDrawing(ImageOutput(img_tmps))
  If source <> 0
    DrawImage(ImageID(source),0,0)
  Else
    DrawImage(ImageID(#Lasso_Image_3),0,0)
  EndIf
  StopDrawing()
 

  ; update affichage des copy
  ForEach mescopy()
    draw_alpha(mescopy(), img_tmps)
  Next
 
  StartDrawing(WindowOutput(#Lasso_Window_0))
  DrawImage(ImageID(img_tmps),0,0)
  Select capture
    Case 0
      t$="no capture"
    Case 1
      t$="polygon"
    Case 2
      t$="laso"
  EndSelect
  DrawText(0,0,t$)
  StopDrawing()
 
  ; affichage le rectangle autour de l'image selectionnee
  my1 = #height - my
  ForEach mescopy()
    If mx > mescopy()\px And mx < (mescopy()\px + mescopy()\lg)
      If my1 > mescopy()\py And my1 < (mescopy()\py + mescopy()\ht) 
        StartDrawing(WindowOutput(#Lasso_Window_0))
        DrawingMode(#PB_2DDrawing_XOr)
        Line(mescopy()\px,#height - mescopy()\py,1,-mescopy()\ht)
        Line(mescopy()\px,#height - mescopy()\py,mescopy()\lg,1)
        Line(mescopy()\px + mescopy()\lg,#height - mescopy()\py,1,-mescopy()\ht)
        Line(mescopy()\px ,#height - mescopy()\py - mescopy()\ht ,mescopy()\lg , 1)
        StopDrawing()
      EndIf
    EndIf 
  Next
 
 
Until Event = #PB_Event_CloseWindow

End