IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PureBasic Discussion :

Flood fill (by Comtois)


Sujet :

PureBasic

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 52
    Points : 33
    Points
    33
    Par défaut Flood fill (by Comtois)
    salut

    j'ai trouvé sur le forum anglais un fillarea() personnalisable, bien plus intéressant que le fillarea() de purebasic :
    http://www.purebasic.fr/english/view...p=94566#p94566

    J'aimerai ajouter de la "tolerance", c'est à dire prendre en compte des couleurs dans une certaine gamme.
    Par exemple, si je choisis tolerance = 10, la couleur à tester serait lim=point(x,y) plus ou moins 10.

    J'ai essayé de modifier le code en conséquence, mais ça ne change rien par rapport au code original ^^ :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    ; 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 
     
    Enumeration
      #Fond
      #Souris
      #Temoin
    EndEnumeration
     
    InitSprite()
    InitKeyboard()
    InitMouse()
    screenwidth = 1024
    screenheight = 768
     
    ;Delta limite la zone de remplissage à partir de la position de la souris 
    Delta = 1000
     
    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 ?)
     
      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
     
    CreateSprite(#Fond,screenwidth*2,screenheight*2,#PB_Sprite_AlphaBlending)
    CreateSprite(#Souris,3,3)
    StartDrawing(SpriteOutput(#Souris))
    Box(0,0,3,3,RGB(255,255,255))
    StopDrawing()
     
     
    Repeat
     
      Repeat
     
        event =WaitWindowEvent(1)
     
      Until event = 0
     
     
      ExamineMouse()
      ExamineKeyboard()
     
     
      ;Efface le fond
      If KeyboardPushed(#PB_Key_F1)
        StartDrawing(SpriteOutput(#Fond))
        DrawingMode(#PB_2DDrawing_AllChannels)
        Box(0,0,SpriteWidth(#Fond),SpriteHeight(#Fond),RGBA(0,0,0,0))
        StopDrawing()
      EndIf    
     
      ;trace des formes 
      If MouseButton(1)
        If clic = 0 
          clic = 1
          startX = MouseX()        
          startY = MouseY()
        EndIf
        xx = MouseX()
        yy = MouseY()
        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 
     
      ;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)
            StopDrawing()
          EndIf
        EndIf
      Else
        clic2= 0
      EndIf  
     
      ClearScreen(RGB(120,120,120))
     
      DisplayTransparentSprite(#Fond,0,0)
      DisplaySprite(#Souris, MouseX(), MouseY())
     
      FlipBuffers()
     
    Until KeyboardPushed(#PB_Key_Escape)
    Je poste ici, car c'est un code de Comtois que j'ai modifié à la base .
    EDIT :
    Ce que j'aimerai obtenir, c'est par exemple :
    - si je clique sur une surface rouge à coté d'une surface rouge ayant dune différence de couleur RGB() de +/- 100 (si tolerance=100), alors ça colorise les deux surfaces dans la même couleur (par exemple un vert).
    - si je clique sur un surface rouge , avec de l'alpha par nuance (exemple : un rectangle avec des bords lissés), lorsque je clique sur le triangle, j'aimerai que toute la couleur devienne rouge (y compris les pixels en rouge plus ou moins transparents ayant cette couleur-là).

    Si vous avez une idée, ce serait super ^^.

  2. #2
    Responsable Purebasic

    Avatar de comtois
    Inscrit en
    Avril 2003
    Messages
    1 261
    Détails du profil
    Informations forums :
    Inscription : Avril 2003
    Messages : 1 261
    Points : 9 924
    Points
    9 924
    Billets dans le blog
    8
    Par défaut
    Réponse rapide :
    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). Utilise un quad pour être compatible en x86 et x64 (ou un integer si tu compiles en x64)
    Il faut un masque sinon les comparaisons seront faussées!
    Exemple

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    a.q = RGBA(255,255,255,255) & $FFFFFFFF
    b.q = RGBA(255,255,255,255) 
    Debug a
    Debug b
    Vous souhaitez participer à la rubrique PureBasic (tutoriels, FAQ, sources) ? Contactez-moi par MP.

Discussions similaires

  1. Algorithmes de remplissage (≠ flood fill)
    Par Luke58 dans le forum Traitement d'images
    Réponses: 1
    Dernier message: 24/11/2009, 16h40
  2. Magic Wand: Flood Fill par scanlines
    Par lcfseth dans le forum Traitement d'images
    Réponses: 6
    Dernier message: 27/03/2009, 03h10
  3. [VB6] [MDI] Signaler la fermeture d'une fille à la mère
    Par cpri1shoot dans le forum VB 6 et antérieur
    Réponses: 4
    Dernier message: 13/04/2004, 08h57
  4. [VB6] [MDI] Menus contextuels dans les filles
    Par Rosec dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 16/09/2002, 14h00
  5. icône d'une fenêtre fille
    Par bastien dans le forum C++Builder
    Réponses: 6
    Dernier message: 27/05/2002, 13h46

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo