Page 2 sur 2

Re: Selection et contour

Publié : sam. 25/juil./2015 22:21
par Fig
J'ai implémenté un algo de remplissage (floodfill non récurcif) type scanline. C'est sensé être le plus rapide...

J'ai modifié le code en remplaçant les startdrawing/point/stopdrawing par des accès mémoires directs.
On gagne pas mal en rapidité mais je pense qu'il faudrait passer en assembleur pour mettre tout ça dans l'vent....

Re: Selection et contour

Publié : dim. 26/juil./2015 20:41
par Fig
Une selection sur une image assez granuleuse avec une tolérance de 3... (c'est finalement assez rapide comparativement à un autre code en Pb que j'ai vu...)
Image

Re: Selection et contour

Publié : lun. 27/juil./2015 9:07
par djes
Ca marche pas mal, même si c'est lent ! Merci pour le partage :)

La lenteur vient peut-être de l'utilisation de listes chaînées, trop lourdes par rapport au besoin (mais c'est tellement pratique, j'aurais fait pareil). Je me demande aussi pourquoi tu n'utilises pas le check(), plutôt que de créer une autre liste sélection ?

Re: Selection et contour

Publié : lun. 27/juil./2015 18:43
par Fig
Merci d'avoir pris la peine de répondre, Djes.
Je ne sais pas où est passé Blendman, probablement sur la plage... 8)

Concernant les listes chainées, ça ne semble pas être la raison de la lenteur du truc: sur un carré uni par exemple, un seul élement de liste est créé par ligne (ce qui est bien peu en comparaison avec le nombre de pixel explorés). Et c'est lent quand même...
A cause de cette observation, je ne prend pas la peine de créer un pool mémoire pour remplacer la liste chainée explore() - qui contient les "seeds" en fait-.

La cause de la lenteur c'est les accès à la mémoire vidéo je pense. Mais je ne suis pas capable de faire mieux pour le moment (??)

Re: Selection et contour

Publié : lun. 27/juil./2015 19:00
par djes
Blendman doit se dorer la pilule quelque part, l'heureux homme. J'ai hâte de le rejoindre ! Pour la liste, es-tu sûr, j'ai plutôt l'impression qu'un élément est créé par pixel, avec deux limites horizontales, non ? Je n'ai pas vraiment testé, aussi. Peut-être qu'avec le nouvel outil de test de vitesse intégré à pb, on pourrait mieux cerner le problème. Si c'est vraiment sur la lecture pixel, l'utilisation d'images serait peut-être plus rapide. De toutes façons, à terme, blendman devra travailler sur des images en mémoire, voire des portions avec gestion de mémoire virtuelle, comme photoshop.

Re: Selection et contour

Publié : lun. 27/juil./2015 19:34
par Fig
djes a écrit :Pour la liste, es-tu sûr, j'ai plutôt l'impression qu'un élément est créé par pixel, avec deux limites horizontales, non ?
Sur que non ou alors je n'ai pas compris ce que j'ai codé... :wink:

Image
Le point de départ est le pixel bleu et blanc.
1- On élargit à gauche et à droite du pixel jusqu’à ce qu'on trouve les limites. On colorie les pixels un à un dans le tableau pixel(x,y)=1. Quand on a trouvé les deux limites, on les met dans la liste chainée selection(). (un élément donc par segment)
2- On parcours les lignes en haut et en bas du segment précédent et on note les points qui comportent un "obstacle" (1,2,3 sur le dessin). Je mets ces points en liste chainé explore(), donc 3 éléments dans cet exemple (mais pour un carré uni, 2 puis un seul pour les lignes suivantes)
3- On recommence en étape 1 avec un des 3 points en liste explore() dans l'exemple le point 3. Etc...
Image
Image
Image
Image
Image
Bon, pour être rigoureux, je n'ai pas utilisé les pixels 1,2,3,4 en fin de ligne blanche,mais en début, ça simplifie le code mais ça ne change rien.

En ce qui concerne les utilitaire pb pour optimiser le code, je trouve que ca manque cruellement de tutoriel pour leur utilisation...

Re: Selection et contour

Publié : mar. 28/juil./2015 11:03
par djes
Tiens, j'ai modifié un peu ton algo pour réduire l'utilisation de la liste chaînée. Il y a bel et bien une différence de vitesse : les listes chaînées sont assez lentes et gourmandes en mémoire, c'est d'ailleurs sans doute les allocations mémoire qui réduisent leur vitesse. En fait, en mettant une ligne debug pour surveiller son utilisation, je me suis rendu compte du souci, et qu'on pouvait facilement y remédier. Je pense qu'on pourrait assez facilement ne pas utiliser de liste chaînée, mais bon, c'est pratique...

Sinon, le nouvel outil s'appelle le profileur. Tu lances ton programme en mode debug, tu le mets en pause, tu vas dans le menu débogueur, tu lances le profileur. Là, tu effaces les données existantes, tu démarres, tu retournes dans ton programme et tu fais un remplissage, tu reviens dans le profileur, tu arrêtes, et le temps pris par chaque ligne est indiqué. Et effectivement, la majorité du temps est perdu dans le point() et le hue(). Faudrait voir avec une image plutôt qu'avec un accès écran....

Code : Tout sélectionner

;Filling by Fig http://www.purebasic.fr/french/viewtopic.php?p=173728#p173728
;Little optimisation by djes

UseJPEGImageDecoder()
;mettre le nom d'une image BMP 1024x768 à charger ici
Image.s=OpenFileRequester("Choisissez un fichier à charger", FichierParDefaut$, Filtre$, Filtre)

If InitSprite() = 0 Or InitKeyboard()=0 Or InitMouse()=0:MessageRequester("Error","Error DirectX",0):EndIf
If OpenWindow(0,0,0,1024,768, "baguette magique ", #PB_Window_SystemMenu|#PB_Window_MinimizeGadget)
  If OpenWindowedScreen(WindowID(0),0,0,1024,768,0,0,0,#PB_Screen_NoSynchronization)=0
    MessageRequester("Erreur", "Impossible d'ouvrir un écran dans la fenêtre!", 0)
    End
  EndIf
EndIf
Structure selection
  x1.i
  x2.i
  y.i
EndStructure
Structure pixel
  pixel.l
EndStructure
Global NewList selection.selection()
StartDrawing(ScreenOutput())
Global Buffer      = DrawingBuffer()             ; Adresse de la mémoire vidéo
Global Pitch       = DrawingBufferPitch()        ; longueur d'une ligne horizontale en octets
Global PixelFormat = DrawingBufferPixelFormat()  ; format du pixel
StopDrawing()
Tolerance.i=1
;créer le sprite de la souris
CreateSprite(0,10,10)
StartDrawing(SpriteOutput(0))
Box(0,0,10,10,#Yellow)
Box(2,2,10,10,#Black)
StopDrawing()
;fond d'ecran 1024x768 à charger...
If image<>""
  LoadSprite(1,image)
EndIf
;calque de remplissage
CreateSprite(2,1024,768)

Procedure Max(A,B)
  If A>B:ProcedureReturn A:EndIf
  ProcedureReturn B
EndProcedure

Procedure Min(A,B)
  If A<B:ProcedureReturn A:EndIf
  ProcedureReturn B
EndProcedure

Procedure.f Hue(RGB)
  Protected R, G, B, nImax, nImin, Hue.f
  If RGB < = $FFFFFF Or RGB > = 0
    R = Red(RGB)
    G = Green(RGB)
    B = Blue(RGB)
    nImax = Max(Max(r,b),g)
    nImin = Min(Min(r,b),g)
    If nImax = r   
      Hue=60*(g-b)/(nImax-nImin)
    ElseIf nImax = g
      Hue=60*(b-r)/(nImax-nImin)+120
    ElseIf nImax = b
      Hue=60*(r-g)/(nImax-nImin)+240
    EndIf
    If Hue<0
      Hue = 360 + Hue
    EndIf
  EndIf
  ProcedureReturn Hue
EndProcedure

Procedure PointFast(x.i,y.i,color.i,tolerance.i)
  *Line.Pixel = Buffer+Pitch*y+x*4
  couleur.l=*line\pixel
  If PixelFormat <> #PB_PixelFormat_32Bits_RGB
    couleur=RGB(Blue(couleur),Green(couleur),Red(couleur))
  EndIf
  couleur=hue(couleur)
  If couleur<hue(color)+tolerance And couleur>hue(color)-tolerance:ProcedureReturn 1:EndIf
  ProcedureReturn 0
EndProcedure

Procedure Baguette_Magique(x.i,y.i,tolerance.i)
  Protected NewList explore.point()
  Protected Dim check.i(1024,768)
  ClearList(selection())
  StartDrawing(ScreenOutput())
  color.i=Point(x,y)
  StopDrawing()
  AddElement(explore())
  explore()\x=x
  explore()\y=y
  check(x,y)=1
  time = ElapsedMilliseconds()
  Repeat
    x=Explore()\x
    y=Explore()\y
    DeleteElement(explore())
    xi=x  
    xj=x
    ;agrandit vers la gauche
    While xi>0 And PointFast(xi,y,color,tolerance)
      check(xi,y)=1
      xi-1
    Wend
    xi+1
    AddElement(selection())
    selection()\x1=xi
    selection()\y=y
    ;Agrandit vers la droite
    While xj<1023 And PointFast(xj,y,color,tolerance)
      check(xj,y)=1
      xj+1
    Wend
    xj-1     
    selection()\x2=xj     
    ;nord
    flag=0     
    yy=y-1     
    If yy>0
     ; SectionFound = #False         
      For i=xi To xj
        If check(i,yy):Continue:EndIf
        If PointFast(i,yy,color,tolerance)
          If Not SectionFound
            AddElement(Explore())
            Explore()\x=i
            Explore()\y=yy
            SectionFound = #True
          EndIf
        Else
          SectionFound = #False         
        EndIf
      Next i
    EndIf
    ;sud
    flag=0
    yy+2
    If yy<767
      SectionFound = #False
      For i=xi To xj
        If check(i,yy):Continue:EndIf
        If PointFast(i,yy,color,tolerance)
          If Not SectionFound
            AddElement(Explore())
            Explore()\x=i
            Explore()\y=yy
            SectionFound = #True
          EndIf
        Else
          SectionFound = #False         
        EndIf
      Next i
    EndIf    
  ;Debug ListSize(explore())  
  Until ListSize(explore())=0
  MessageRequester("Temps", Str((ElapsedMilliseconds()-time)))
EndProcedure

Repeat
  WaitWindowEvent(5)
  FlipBuffers()
  ClearScreen(#Black)
  ExamineMouse()
  ExamineKeyboard()
  
  If image<>"":DisplaySprite(1,0,0):EndIf
  ;affiche des figures géométriques bidons...
  StartDrawing(ScreenOutput())
  Box(600,300,100,100,#Blue)
  Circle(640,275,50,RGB(130,100,30))
  Box(650,320,30,30,#Green)
  DrawText(0,0,"Modifiez la tolérance avec la roulette de la souris. Lancez la selection avec [Espace]. Quittez avce [Escape]")
  DrawText(0,20,"Tolérance : "+Str(tolerance))
  StopDrawing()
  
  If KeyboardReleased(#PB_Key_Space)
    Baguette_Magique(MouseX(),MouseY(),tolerance)
  EndIf
  If tolerance+MouseWheel()>=0:Tolerance+MouseWheel():EndIf  
  
  ;affiche la selection en rouge
  If ListSize(selection())
    StartDrawing(SpriteOutput(2))
    Box(0,0,1024,768,#Black)
    ForEach selection()
      LineXY(selection()\x1,selection()\y,selection()\x2,selection()\y,#Red)
    Next  
    StopDrawing()
    ClearList(selection())  
  EndIf
  DisplayTransparentSprite(2,0,0)
  ;affiche la souris
  DisplayTransparentSprite(0,MouseX(),MouseY())
Until KeyboardPushed(#PB_Key_Escape)

Re: Selection et contour

Publié : mar. 28/juil./2015 11:45
par blendman
@Fig : merci pour ton code, ça marche pas mal du tout.
j'ai eu quelques soucis avec mon PC dernièrement, je viens de récupérer le net ^^. Je n'étais pas du tout parti en avance puisque je ne pars jamais en vacance ^^ (impossible physiquement).

@Djes : merci pour le nouveau code, j'ai testé ça et c'est vraiment bien maintenant. Effectivement, je vais pouvoir utiliser ça pour la baguette magique :).



Comme indiqué dans mon 1er message, Comtois avait réalisé un floofill très rapide (qui fonctionne mieux que le fillarea() interne, j'ai l'impression).
Je pense qu'il est possible de partir de sa procedure remplissage() pour obtenir un système de sélection.
J'ai essayé d'ajouter de la tolérance pour déjà dessiner sur plus de pixels que la couleur sélectionnée, mais ça ne marche pas (pas encore ^^).

Code : Tout sélectionner

; Comtois
; 02/07/05

; La fonction FillArea() est un peu limitée , elle impose de connaitre à l'avance la couleur de bord.
; Dans ce programme, la couleur du tracé est aléatoire,donc impossible d'utiliser FillArea,du moins pas à ma connaissance .
 
; La fonction Remplissage() est lente pour des grandes zones à remplir
; Pour tester faites des petites formes fermées (cercles ou autres) avec la souris en maintenant le bouton gauche de la souris
; Et utilisez le bouton droit de la souris pour remplir une zone d'une couleur aléatoire.
; [F1] pour effacer l'écran
; Delta limite la zone de remplissage à partir de la position de la souris 

; nouveau (07/2015) : 
; O : pour ouvrir une image
; molette : pour changer la tolérance.

Enumeration
  #Fond
  #Souris
  #Sp_text
  #Temoin
EndEnumeration
UsePNGImageDecoder()
UseJPEGImageDecoder()
InitSprite()
InitKeyboard()
InitMouse()
screenwidth = 1024
screenheight = 768
 
;Delta limite la zone de remplissage à partir de la position de la souris 
Delta = 1000
Procedure UpdateText(Tolerance)
  If StartDrawing(SpriteOutput(#sp_text))  
    DrawText(0,0,"Tolerance : "+Str(Tolerance))
    StopDrawing()
  EndIf  
EndProcedure
Procedure InSpriteArea(x,y,w,h)  
  If x>0 And y>0 And x<=W-1 And y<=H-1
    ProcedureReturn 1
  EndIf
  ProcedureReturn 0
EndProcedure
Procedure remplissage(xx, yy, MinX, MinY, MaxX, MaxY, c=0, tolerance=0)
 
  ; By comtois 2005
  ; légère modification by blendman, to verify if we are in the area (2015)+ajout tolerance
 
  ; Toutes les options de remplissage sont envisageables en modifiant légèrement ce code
 
  ; La version originale de ce code se trouve ici (ainsi que les explications)
  ; http://raphaello.univ-fcomte.fr/IG/Algorithme/Algorithmique.htm#remplissage
 
  ; Remarque : j'ai ajouté les paramètres Min et Max ,
  ; parce qu'une personne sur le forum anglais m'a demandé comment faire pour limiter la zone de remplissage.
 
  ; c = color
  ; tolerance = pixel plus ou moins proche (luminence ou hue ?)
  
  ; note de comtois 2015 : 
  ; Pour tester une valeur alpha il faut ouvrir un canal alpha avec la commande DrawingMode().
  ; Dans ce cas , attention au type des variables utilisées pour contenir la couleur (les nombres sont signés). Utiliser un quad pour être compatible en x86 et x64 (ou un integer si on compile en x64)
  ; Il faut un masque sinon les comparaisons seront faussées! 
  ; a.q = RGBA(255,255,255,255) & $FFFFFFFF
  
  FrontColor(RGBA(Red(c),Green(c),Blue(c),255)) 
  sp = #Fond
 
  w_1 = SpriteWidth(sp)
  h_1 = SpriteHeight(sp)
 
  If InSpriteArea(xx,yy,w_1,h_1)
 
    Psp = 1
    Dim Px(w_1)
    Dim Py(h_1)
    Px(0) = xx
    Py(0) = yy
 
    lim = Point(xx, yy)
 
    If (RGB(Red(lim),Green(lim),Blue(lim)) <> (RGB(Red(c),Green(c),Blue(c)))) ; Or tolerance >0
 
      If MinX < 0 : MinX = 0 : EndIf
      If MinY < 0 : MinY = 0 : EndIf
      If MaxX > w_1 : MaxX = w_1 : EndIf
      If MaxY > h_1 : MaxY = h_1 : EndIf
 
      While Psp <> 0
 
        xi = Px(Psp - 1)
        xf = Px(Psp - 1)
        x  = Px(Psp - 1)
        y  = Py(Psp - 1)
 
        x + 1
        If InSpriteArea(x,y,w_1,h_1)
          cp = Point(x, y)
        EndIf
        ;While (cp=lim) And x > MinX
        While (cp>=lim-tolerance And cp<=lim+tolerance) And x>MinX
          xf = x
          x + 1
          If InSpriteArea(x,y,w_1,h_1)
            cp = Point(x,y)
          EndIf            
        Wend
 
        x = Px(Psp - 1) - 1
        If InSpriteArea(x,y,w_1,h_1)
          cp = Point(x, y)
        EndIf
        ;While (cp=lim) And x > MinX
        While (cp>=lim-tolerance And cp<=lim+tolerance) And x>MinX
          xi = x
          x - 1
          If InSpriteArea(x,y,w_1,h_1)
            cp = Point(x, y)
          EndIf            
        Wend
 
        LineXY(xi, y, xf, y)
        Psp - 1
 
        x = xf
        While x>=xi And y<MaxY
          If InSpriteArea(x,y+1,w_1,h_1)
            cp = Point(x, y + 1)
          EndIf
          ;While ((cp<>lim) Or (cp=c)) And (x>=xi)
          While ((cp<lim-Tolerance Or cp>lim+tolerance) Or (cp=c)) And (x>=xi)
            x - 1
            If InSpriteArea(x,y+1,w_1,h_1)          
              cp = Point(x, y + 1)
            EndIf
          Wend
 
          If ((x>=xi) And (cp>=lim-tolerance And cp<=lim+tolerance) And (cp<>c))
          ;If ((x >= xi) And (cp=lim) And (cp<>c))
            If Psp < ArraySize(px())
              Px(Psp) = x
              Py(Psp) = y + 1
              Psp + 1
            Else 
              psp = 0
            EndIf 
          EndIf
          If InSpriteArea(x,y+1,w_1,h_1)                
            cp = Point(x, y + 1)
          EndIf
          ;While ((cp=lim) And (x>=xi))
          While (cp>=lim-tolerance And cp<=lim+tolerance) And (x>=xi)
            x - 1
            If InSpriteArea(x,y+1,w_1,h_1)                  
              cp = Point(x,y+1)
            EndIf
          Wend
        Wend
 
        x = xf
        While x >= xi And y > MinY
          If InSpriteArea(x,y-1,w_1,h_1)
            cp = Point(x, y-1)
          EndIf
          ;While (((cp<>lim) Or (cp=c)) And (x >= xi))
          While (((cp<lim-tolerance Or cp>lim+tolerance) Or (cp=c)) And (x>=xi))
            x - 1
            If InSpriteArea(x,y-1,w_1,h_1)          
              cp = Point(x, y - 1)
            EndIf
          Wend
          ;If ((x >= xi) And (cp=lim) And (cp<>c))
          If ((x>=xi) And (cp>=lim-tolerance And cp<=lim+tolerance) And (cp<>c))
            If Psp < ArraySize(px())
              Px(Psp) = x
              Py(Psp) = y - 1
              Psp + 1
            Else 
              psp = 0
            EndIf            
          EndIf
          If InSpriteArea(x,y-1,w_1,h_1)
            cp = Point(x, y-1)
          EndIf
          ;While ((cp=lim) And ( x >= xi ))
          While ((cp>=lim-tolerance And cp<=lim+tolerance) And (x>=xi))
            x - 1
            If InSpriteArea(x,y-1,w_1,h_1)
              cp = Point(x,y-1)
            EndIf
          Wend
        Wend
 
      Wend
 
    EndIf
 
  EndIf
 
 
EndProcedure
 
OpenWindow(0, 0, 0, screenwidth, screenheight, "Fillarea", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
If OpenWindowedScreen(WindowID(0),0,0,screenwidth, screenheight)=0
  MessageRequester("Error", "Can't Open Screen!", 0)
  End
EndIf
 
If CreateSprite(#Fond,screenwidth*2,screenheight*2,#PB_Sprite_AlphaBlending) : EndIf
If CreateSprite(#Souris,3,3) : EndIf
If CreateSprite(#sp_text,200,30) : EndIf
UpdateText(Tolerance)
If StartDrawing(SpriteOutput(#Souris))
  Box(0,0,3,3,RGB(255,255,255))
  StopDrawing()
EndIf
If StartDrawing(SpriteOutput(#Fond))
  DrawingMode(#PB_2DDrawing_AllChannels)
  Box(0,0,SpriteWidth(#Fond),SpriteHeight(#Fond),RGBA(0,0,0,0))
  StopDrawing()
EndIf


Tolerance =1

Repeat
 
  Repeat
 
    event=WindowEvent()
 
  Until event = 0
 
 
  ExamineMouse()
  ExamineKeyboard()
 
 
  ;Efface le fond
  If KeyboardPushed(#PB_Key_F1)
    If StartDrawing(SpriteOutput(#Fond))
    DrawingMode(#PB_2DDrawing_AllChannels)
    Box(0,0,SpriteWidth(#Fond),SpriteHeight(#Fond),RGBA(0,0,0,0))
    If image = 1
      DrawAlphaImage(ImageID(0),0,0)
    EndIf    
    StopDrawing()
    EndIf
  ElseIf KeyboardPushed(#PB_Key_O) ; open image
    file$ =OpenFileRequester("Image","","image|*png;*.jpg;*.bmp",0)
    If file$ <> ""
      If LoadImage(0,file$)
        image = 1
        If StartDrawing(SpriteOutput(#Fond))
          DrawingMode(#PB_2DDrawing_AllChannels)
          Box(0,0,SpriteWidth(#Fond),SpriteHeight(#Fond),RGBA(0,0,0,0))
          DrawAlphaImage(ImageID(0),0,0)
          StopDrawing()
        EndIf       
      EndIf      
    EndIf
    
  EndIf    
 
  ;trace des formes 
  If MouseButton(1)
    If clic = 0 
      clic = 1
      startX = WindowMouseX(0)        
      startY = WindowMouseY(0)
    EndIf
    xx = WindowMouseX(0)
    yy = WindowMouseY(0)
    If StartDrawing(SpriteOutput(#Fond))
      DrawingMode(#PB_2DDrawing_AlphaBlend)
      Line(xx,yy,startX-xx,StartY-yy, Couleur)
      StartX= xx
      StartY= yy
      StopDrawing()
    EndIf
  Else
    Couleur = Random($FFFFFF)
    couleur = RGBA(Red(couleur),Green(couleur),Blue(couleur),255)
    clic = 0
  EndIf 
  
  If Tolerance+MouseWheel()>=0:Tolerance+MouseWheel():UpdateText(Tolerance):EndIf 

  ;Remplissage
  If MouseButton(2)
    If clic2 = 0
      clic2=1
      If StartDrawing(SpriteOutput(#Fond))
        DrawingMode(#PB_2DDrawing_AlphaBlend)
        color = Random($FFFFFF)
        color = RGBA(Red(color),Green(color),Blue(color),255)
        remplissage(MouseX(), MouseY(),MouseX() - Delta, MouseY() - Delta, MouseX() + Delta, MouseY() + Delta, color,Tolerance)
        StopDrawing()
      EndIf
    EndIf
  Else
    clic2= 0
  EndIf  
 
  ClearScreen(RGB(120,120,120))
 
  DisplayTransparentSprite(#Fond,0,0)
  DisplayTransparentSprite(#Sp_text,0,0)
  
  DisplaySprite(#Souris, MouseX(), MouseY())
  
  FlipBuffers()
 
Until KeyboardPushed(#PB_Key_Escape)

Re: Selection et contour

Publié : mar. 28/juil./2015 17:28
par Fig
Djes> Merci beaucoup !! En fait ce n'est pas une optimisation que tu fais, tu répare une erreur que j'ai faite ! je suis passé à travers et je n'ai pas vu que je rajoutais un point à chaque pixel et non à chaque debut de ligne. Ce qui était effectivement le cas dans ma tête et c'est la raison pour laquelle je ne voyais pas en quoi les listes étaient un problème... :wink:
Elles ne sont effectivement pas vraiment un problème quand l'algo est codé correctement. :lol:
C'est un peu rageant pour moi là. :roll:

Blendman> Je pense que tu devrais te servir du code que Djes a posté parce qu'il est (nettement) plus rapide que le code de Comtois, si je peux me permettre... (les codes de Comtois ont toujours une forte valeur éducative ajouté, néanmoins). Mais c'est vous qui voyez... :mrgreen:

Dobro> Malheureusement les apis ne permettent pas d'accéder à la liste des points sélectionnés pour les utiliser ultérieurement.

Re: Selection et contour

Publié : mar. 28/juil./2015 19:17
par Fig
Un grand musicien qui a gagné un tel doigté qu'il peut maintenant faire le signe de ralliement vulcain. :mrgreen:

Re: Selection et contour

Publié : mer. 29/juil./2015 10:17
par comtois
Spock a écrit :je repondais juste au probleme soulevé par Comtois a l'epoque
remplir sans connaitre la couleur de bords ... ce que ne fait toujours pas FillArea()
Erreur, maintenant FillArea() le permet.

FillArea(x, y, CouleurBord [, Couleur])

CouleurBord :
Le remplissage s'arrête quand il rencontre la couleur 'CouleurBord'.
Si défini avec la valeur -1 alors la zone est remplie avec la couleur trouvée en 'x,y' jusqu'à ce qu'une couleur différente soit rencontrée.
Sur les images en 32-bit, le canal alpha est ignoré pour savoir si un pixel fait office de bordure ou non.

Mais ça ne résout pas le problème de blendman :)