Page 1 sur 1

Fonction remplissage (FillArea)

Publié : sam. 02/juil./2005 8:34
par comtois

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 
; Mettre 800 pour prendre en compte la totalité de l'écran
; ou changez les paramètres de remplissage() de cette façon remplissage(MouseX(), MouseY(), 0, 0, 800, 600, Random($FFFFFF))


InitSprite()
InitKeyboard()
InitMouse()
OpenScreen(800,600,32,"Remplissage")

Enumeration
    #Fond
    #Souris
    #Temoin
EndEnumeration
   
CreateSprite(#Fond,800,600)
CreateSprite(#Souris,3,3)
StartDrawing(SpriteOutput(#Souris))
Box(0,0,3,3,RGB(255,255,255))
StopDrawing()

;Delta limite la zone de remplissage à partir de la position de la souris 
Delta = 100 

Procedure remplissage(xx, yy, MinX, MinY, MaxX, MaxY, c)
    ;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.
    
    Psp = 1
    Dim Px(1000)
    Dim Py(1000)
    Px(0) = xx
    Py(0) = yy
    FrontColor(Red(c), Green(c), Blue(c))
    
    lim = Point(xx, yy)
    If MinX < 0 : MinX = 0 : EndIf
    If MinY < 0 : MinY = 0 : EndIf
    If MaxX > SpriteWidth(#Fond)  : MaxX = SpriteWidth(#Fond)  : EndIf
    If MaxY > SpriteHeight(#Fond) : MaxY = SpriteHeight(#Fond) : EndIf
    
    While Psp <> 0
        xi = Px(Psp - 1)
        xf = Px(Psp - 1)
        x  = Px(Psp - 1)
        y  = Py(Psp - 1)
        
        x + 1
        cp = Point(x, y)
        While cp = lim And x < MaxX
            xf = x
            x + 1
            cp = Point(x,y)
        Wend
        
        x = Px(Psp - 1) - 1
        cp = Point(x, y)
        
        While cp = lim And x > MinX
            xi = x
            x - 1
            cp = Point(x, y)
        Wend
        
        LineXY(xi, y, xf, y)
        Psp - 1
        
        ; Y + 1
        x = xf
        While x >= xi And y < MaxY
            cp = Point(x, y + 1)
            While (((cp <> lim) Or (cp = c)) And (x >= xi))
                x - 1
                cp = Point(x, y + 1)
            Wend
            If ((x >= xi) And (cp = lim) And (cp <> c))
                Px(Psp) = x
                Py(Psp) = y + 1
                Psp + 1
            EndIf
            cp = Point(x, y + 1)
            While (( cp = lim ) And ( x >= xi ))
                x - 1
                cp = Point(x,y+1)
            Wend
        Wend
        
        ; Y - 1
        x = xf
        While x >= xi And y > MinY
            cp = Point(x, y - 1)
            While (((cp <> lim) Or (cp = c)) And (x >= xi))
                x - 1
                cp = Point(x, y - 1)
            Wend
            If ((x >= xi) And (cp = lim) And (cp <> c))
                Px(Psp) = x
                Py(Psp) = y - 1
                Psp + 1
            EndIf
            cp = Point(x, y - 1)
            While (( cp = lim ) And ( x >= xi ))
                x - 1
                cp = Point(x, y - 1)
            Wend
        Wend
    Wend
EndProcedure


Repeat
    FlipBuffers()
    ExamineMouse()
    ExamineKeyboard()
    DisplaySprite(#Fond,0,0)
    DisplaySprite(#Souris, MouseX(), MouseY())
    
    ;Efface le fond
    If KeyboardPushed(#PB_Key_F1)
        StartDrawing(SpriteOutput(#Fond))
        Box(0,0,SpriteWidth(#Fond) ,SpriteHeight(#Fond) , 0)
        StopDrawing()
    EndIf    
    
    ;trace des formes 
    If MouseButton(1)
        StartDrawing(SpriteOutput(#Fond))
        Line(MouseX(),MouseY(),-MouseDeltaX(),-MouseDeltaY(), Couleur)
        StopDrawing()
    Else
        Couleur = Random($FFFFFF)
    EndIf 
    
    ;Remplissage
    If MouseButton(2)
        StartDrawing(SpriteOutput(#Fond))
        remplissage(MouseX(), MouseY(),MouseX() - Delta, MouseY() - Delta, MouseX() + Delta, MouseY() + Delta, Random($FFFFFF))
        StopDrawing()
    EndIf   
    
Until KeyboardPushed(#PB_Key_Escape) 

Publié : sam. 02/juil./2005 19:10
par Jacobus
Tout simplement excellent, mérite d'être poussé dans les fonctionnalités.
Merci pour ce bel exemple ! :D

Publié : dim. 23/oct./2005 18:50
par Backup
la meme chose !

Code : Tout sélectionner

Procedure remplis(*hdc,x,y,couleur_remplissage)
  pinceau=CreateSolidBrush_(couleur_remplissage)
  SelectObject_(*hdc,pinceau)
  ExtFloodFill_(*hdc,x,y,GetPixel_(*hdc,x,y),#FLOODFILLSURFACE)
  DeleteObject_(pinceau)
  ReleaseDC_(WindowID(),*hdc)
EndProcedure
on appel ainsi :

Code : Tout sélectionner

  *dc=StartDrawing(ScreenOutput())   
       remplis(*dc,x,y,RGB(rouge,vert,bleu) )  
  StopDrawing()


:D

Publié : dim. 23/oct./2005 19:19
par Anonyme2
Dobro,

je pense que la procedure est mieux comme ceci

Code : Tout sélectionner

Procedure remplis(*hdc,x,y,couleur_remplissage)
  pinceau=CreateSolidBrush_(couleur_remplissage)
  If pinceau
     AncienneBrush = SelectObject_(*hdc,pinceau)
     If AncienneBrush
        ExtFloodFill_(*hdc,x,y,GetPixel_(*hdc,x,y),#FLOODFILLSURFACE)
        SelectObject_(*hdc,AncienneBrush)
     EndIf
     DeleteObject_(pinceau)
  EndIf
EndProcedure
si tu utilises SelectObject_, tu vas changer soit la brush, soit le pen soit la police du hdc

Dès que ton opération est terminée, il faut remettre dans le hdc l'ancien objet

Je pense que ReleaseDc est inutile les commandes Startdrawing() et StopDrawing() se charge de libérer correctement le hdc

Publié : dim. 23/oct./2005 22:07
par Backup
ok ! :D

Publié : mer. 21/févr./2007 17:25
par Thyphoon
Désolé de remonté ce vieux topic.

J'utilise le code de comtois (le premier) pour analyser le contenue d'une piece dans une map fait de tile. ça marche plutôt bien sauf que dans certain cas le "remplissage" passe en diagonal. Vous voyez ce que je veux dire ?
Quelqu'un sait comment je peux corriver ce petite bug ?