Selection et contour
Re: Selection et contour
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....
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
Version de PB : 6.00LTS - 64 bits
Re: Selection et contour
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...)


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
Version de PB : 6.00LTS - 64 bits
Re: Selection et contour
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 ?

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
Merci d'avoir pris la peine de répondre, Djes.
Je ne sais pas où est passé Blendman, probablement sur la plage...
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 (??)
Je ne sais pas où est passé Blendman, probablement sur la plage...

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
Version de PB : 6.00LTS - 64 bits
Re: Selection et contour
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
Sur que non ou alors je n'ai pas compris ce que j'ai codé...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 ?


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...





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
Version de PB : 6.00LTS - 64 bits
Re: Selection et contour
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....
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
@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 ^^).
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)
http://blendman.blogspot.com/
Forum PB fr : http://www.purebasic.fr/french - Forum PB Eng : http://www.purebasic.fr/english
Forum PB fr : http://www.purebasic.fr/french - Forum PB Eng : http://www.purebasic.fr/english
Re: Selection et contour
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...
Elles ne sont effectivement pas vraiment un problème quand l'algo est codé correctement.
C'est un peu rageant pour moi là.
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...
Dobro> Malheureusement les apis ne permettent pas d'accéder à la liste des points sélectionnés pour les utiliser ultérieurement.

Elles ne sont effectivement pas vraiment un problème quand l'algo est codé correctement.

C'est un peu rageant pour moi là.

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...

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
Version de PB : 6.00LTS - 64 bits
Re: Selection et contour
Un grand musicien qui a gagné un tel doigté qu'il peut maintenant faire le signe de ralliement vulcain. 

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
Version de PB : 6.00LTS - 64 bits
Re: Selection et contour
Erreur, maintenant FillArea() le permet.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()
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.
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.