@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)