Selection et contour

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
Fig
Messages : 1176
Inscription : jeu. 14/oct./2004 19:48

Re: Selection et contour

Message 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....
Il y a deux méthodes pour écrire des programmes sans erreurs. Mais il n’y a que la troisième qui marche.
Version de PB : 6.00LTS - 64 bits
Avatar de l’utilisateur
Fig
Messages : 1176
Inscription : jeu. 14/oct./2004 19:48

Re: Selection et contour

Message 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
Il y a deux méthodes pour écrire des programmes sans erreurs. Mais il n’y a que la troisième qui marche.
Version de PB : 6.00LTS - 64 bits
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Selection et contour

Message 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 ?
Avatar de l’utilisateur
Fig
Messages : 1176
Inscription : jeu. 14/oct./2004 19:48

Re: Selection et contour

Message 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 (??)
Il y a deux méthodes pour écrire des programmes sans erreurs. Mais il n’y a que la troisième qui marche.
Version de PB : 6.00LTS - 64 bits
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Selection et contour

Message 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.
Avatar de l’utilisateur
Fig
Messages : 1176
Inscription : jeu. 14/oct./2004 19:48

Re: Selection et contour

Message 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...
Il y a deux méthodes pour écrire des programmes sans erreurs. Mais il n’y a que la troisième qui marche.
Version de PB : 6.00LTS - 64 bits
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Selection et contour

Message 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)
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: Selection et contour

Message 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)
Avatar de l’utilisateur
Fig
Messages : 1176
Inscription : jeu. 14/oct./2004 19:48

Re: Selection et contour

Message 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.
Il y a deux méthodes pour écrire des programmes sans erreurs. Mais il n’y a que la troisième qui marche.
Version de PB : 6.00LTS - 64 bits
Avatar de l’utilisateur
Fig
Messages : 1176
Inscription : jeu. 14/oct./2004 19:48

Re: Selection et contour

Message par Fig »

Un grand musicien qui a gagné un tel doigté qu'il peut maintenant faire le signe de ralliement vulcain. :mrgreen:
Il y a deux méthodes pour écrire des programmes sans erreurs. Mais il n’y a que la troisième qui marche.
Version de PB : 6.00LTS - 64 bits
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Re: Selection et contour

Message 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 :)
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Répondre