Page 1 sur 1

[5.20LTS]Image et fillarea

Publié : lun. 23/sept./2013 12:22
par blendman
salut

J'ai essayé d'utiliser le FillArea avec une image, mais je n'ai pas réussi.
Quelque chose doit m'échapper (ou y aurait-il une sorte de bug) ?

Testé sous windows8, quand j'utilise le fillarea, ça me remplit toute l'image, qu'il y ait ou des traits dans l'image d'une autre couleur.
ça marche avec une image sans couche alpha transparente créée avec CreateImage(#IMAGE_Draw, 380, 380, 32), mais j'ai besoin d'une couche alpha pour gérer la transparence.

Code tiré de l'exemple du canvasgadget, modifié pour s'utiliser avec une image et un canvas gadget (pour l'affichage)

Code : Tout sélectionner

Enumeration
  #IMAGE_Color
  #IMAGE_Draw
EndEnumeration

Enumeration
  #GADGET_Canvas
  #GADGET_Color 
  #GADGET_Brush
  #GADGET_Fill
  #GADGET_Clear 
EndEnumeration

Global CurrentColor, CurrentMode

Procedure DrawAction(x, y, EventType)
  
  If StartDrawing(ImageOutput(#IMAGE_Draw))
    
    DrawingMode(#PB_2DDrawing_AlphaBlend)
    
    Select CurrentMode
        
      Case #GADGET_Brush
        If EventType = #PB_EventType_LeftButtonDown Or EventType = #PB_EventType_MouseMove
          Circle(x, y, 5, CurrentColor)
        EndIf
        
        
      Case #GADGET_Fill
        If EventType = #PB_EventType_LeftButtonDown
          ;  DrawingMode(#PB_2DDrawing_Default) ; si je dé-commente, ça ressemble à #PB_2DDrawing_Alphaclip
          FillArea(x, y, -1, CurrentColor) ; si je change l'alpha de currentcolor, ça ne fait que changer l'alpha global
        EndIf
        
    EndSelect
    
    StopDrawing()
  EndIf
  
  If StartDrawing(CanvasOutput(#GADGET_Canvas)) 
    DrawingMode(#PB_2DDrawing_AlphaBlend)
    DrawAlphaImage(ImageID(#IMAGE_Draw),0,0)
    StopDrawing()
  EndIf
  
  
EndProcedure


CurrentColor = $000000
CurrentColor = RGBA(Red(CurrentColor),Green(CurrentColor),Blue(CurrentColor), 255)
CurrentMode  = #GADGET_Brush

If CreateImage(#IMAGE_Color, 35, 35, 24) = 0 : End : EndIf
If CreateImage(#IMAGE_Draw, 380, 380, 32, #PB_Image_Transparent) = 0 : End :  EndIf

If OpenWindow(0, 0, 0, 460, 400, "CanvasGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  
  CanvasGadget(#GADGET_Canvas, 10, 10, 380, 380)
  
  ButtonImageGadget(#GADGET_Color, 400, 10, 50, 50, ImageID(#IMAGE_Color))  
  ButtonGadget(#GADGET_Brush,  400, 100, 50, 25, "Brush",  #PB_Button_Toggle)
  ButtonGadget(#GADGET_Fill,   400, 130, 50, 25, "Fill",   #PB_Button_Toggle)
  ButtonGadget(#GADGET_Clear,  400, 180, 50, 25, "Clear")
  
  SetGadgetState(#GADGET_Brush, 1)
  SetGadgetAttribute(#GADGET_Canvas, #PB_Canvas_Cursor, #PB_Cursor_Cross)
  
  
  Repeat
    Event = WaitWindowEvent()
    
    If Event = #PB_Event_Gadget
      
      Select EventGadget()
          
        Case #GADGET_Canvas
          X = GetGadgetAttribute(#GADGET_Canvas, #PB_Canvas_MouseX)
          Y = GetGadgetAttribute(#GADGET_Canvas, #PB_Canvas_MouseY)
          Type = EventType()
          
          Select EventType()
              
            Case #PB_EventType_LeftButtonDown
              DrawAction(X, Y, EventType())
                            
            Case #PB_EventType_LeftButtonUp
              DrawAction(X, Y, EventType())                        
              
            Case #PB_EventType_MouseMove
              If GetGadgetAttribute(#GADGET_Canvas, #PB_Canvas_Buttons) & #PB_Canvas_LeftButton
                DrawAction(X, Y, EventType())            
              EndIf
              
          EndSelect
          
        Case #GADGET_Color
          CurrentColor = ColorRequester(CurrentColor)
          CurrentColor = RGBA(Red(CurrentColor),Green(CurrentColor),Blue(CurrentColor), 255)
          If StartDrawing(ImageOutput(#IMAGE_Color))
            Box(0, 0, 35, 35, CurrentColor)
            StopDrawing()
            SetGadgetAttribute(#GADGET_Color, #PB_Button_Image, ImageID(#IMAGE_Color))
          EndIf
          
        Case #GADGET_Brush, #GADGET_Fill
          EventGadget = EventGadget()
          For Gadget = #GADGET_Brush To #GADGET_Fill
            If Gadget = EventGadget
              SetGadgetState(Gadget, 1) 
            Else
              SetGadgetState(Gadget, 0) ; unset the state of all other gadgets
            EndIf
          Next Gadget          
          CurrentMode = EventGadget             
          
        Case #GADGET_Clear
          
          If StartDrawing(CanvasOutput(#GADGET_Canvas))           
            Box(0, 0, 380,380, RGB(255,255,255)) 
            StopDrawing()
          EndIf
          
          If StartDrawing(ImageOutput(#IMAGE_Draw))           
            DrawingMode(#PB_2DDrawing_AlphaBlend)
            Box(0, 0, 380,380, RGBA(0,0,0,255))   
            DrawingMode(#PB_2DDrawing_AlphaChannel)
            Box(0, 0, 380,380, RGBA(0,0,0,0))
            StopDrawing()
          EndIf
          
      EndSelect
      
    EndIf
    
  Until Event = #PB_Event_CloseWindow
  
EndIf
Merci :)

Re: [5.20LTS]Image et fillarea

Publié : lun. 23/sept./2013 14:23
par Mesa
Idem.

Ça ressemble à une bug en effet.

M.

Re: [5.20LTS]Image et fillarea

Publié : lun. 23/sept./2013 15:15
par Eric
Idem, chez moi.

@+

Re: [5.20LTS]Image et fillarea

Publié : lun. 23/sept./2013 16:53
par falsam
Petit test sans rien toucher à ton code.
-Il n'aime pas les contours noir alpha : Essaye un contour mauve par exemple et rempli le avec le meme mauve ou une autre couleur. ça fonctionne. Reste à savoir pourquoi ça ne fonctionne pas avec les contours noirs.

-Deux EventGadgets() et deux EventType() dans ta boucles événementielle : Faut arranger ça Monsieur :)

maintenant je vais chercher un peu avec toi.

Re: [5.20LTS]Image et fillarea

Publié : lun. 23/sept./2013 17:04
par graph100
ce n'est pas un soucis d'avoir 2 eventGadget() dans une même bouche.
Cette fonction retourne la même chose durant le traitement d'un seul et même event.

En revanche ce qu'il ne faut absolument pas, c'est d'avoir plusieurs commande EventWindow() ou waiteventwindow() à la suite !
Car là, cette fonction dépile les events...

Re: [5.20LTS]Image et fillarea

Publié : lun. 23/sept./2013 22:45
par falsam
Comme je l'ai dit plus haut, les contours noirs posent problème du moins quand il s'agit d'une image dans un canvasgadget.

Si on dessine un contour noir et que par la suite on utilise la fonction FillArea() en tenant compte de la couche alpha, il n'y a pas de probléme comme le montre le code ci-dessous.

Code : Tout sélectionner

If OpenWindow(0, 0, 0, 300, 300, "FillArea", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  If CreateImage(0, 300, 300) And StartDrawing(ImageOutput(0))
    DrawingMode(#PB_2DDrawing_AlphaBlend)
    Box(0, 0, 300, 300, RGBA(255, 255, 255, 255))
    DrawingMode(#PB_2DDrawing_Outlined)
    Circle(150, 150, 125 ,RGBA(0, 0, 0, 255))
    DrawingMode(#PB_2DDrawing_AllChannels)
    FillArea(150, 150, -1, RGBA(255, 127, 80, 255)) ; Remplacez -1 par $00FF00 et comparez le résultat.

    StopDrawing() 
    ImageGadget(0, 0, 0, 300, 300, ImageID(0))  
  EndIf
    
  Repeat
    Event = WaitWindowEvent()  
  Until Event = #PB_Event_CloseWindow  
EndIf
Avec ton code, tu dessines dans une image et ensuite tu transferts cette image dans un canvasgadget. On constate que la fonction FillArea ne prend pas en compte les contours noir.

En attendant mieux, un peu de BugWare : Éliminer le noir profond en remplaçant RGBA(0,0,0,255) par RGBA(1, 1, 1, 253)

Code : Tout sélectionner

EnableExplicit

Enumeration Forms
  #Mainform
EndEnumeration

Enumeration Gadgets
  #Canvas
  
  #Color
  #Brush
  #Paint
  #Clear 
EndEnumeration

Enumeration Image
  #IMAGE_Color
  #IMAGE_Draw
EndEnumeration

Define.l Event, WEvent, MEvent, GEvent, TEvent

Global WindowStyle.i=#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_ScreenCentered
Global X, Y, CurrentColor

Procedure Open_MainForm()
  UsePNGImageEncoder()
  
  If Not CreateImage(#IMAGE_Color, 80, 22, 24) : End : EndIf
    
  CurrentColor = RGBA(1, 1, 1, 253)
  OpenWindow(#Mainform, 0, 0, 500, 400, "Paint", WindowStyle)
  CanvasGadget(#Canvas, 5, 5, 380, 380)
  
  ButtonImageGadget(#Color, 410, 5, 80, 22, ImageID(#IMAGE_Color))
  ButtonGadget(#Brush, 410, 35, 80, 22, "Brush", #PB_Button_Toggle)
  ButtonGadget(#Paint, 410, 65, 80, 22, "Fill", #PB_Button_Toggle)
  ButtonGadget(#Clear, 410, 95, 80, 22, "Clear")
  
  SetGadgetData(#Canvas, 10)
EndProcedure

Procedure ImageClear()
  CreateImage(#IMAGE_Draw, 380, 380, 32, #PB_Image_Transparent)
  If StartDrawing(CanvasOutput(#Canvas))
    Box(0, 0, 380, 380, RGB(255, 255, 255))
    DrawingMode(#PB_2DDrawing_AlphaBlend)
    DrawAlphaImage(ImageID(#IMAGE_Draw), 0, 0)
    StopDrawing()
    
    SetGadgetState(#Paint, 0)
    SetGadgetState(#Brush, 1)
    SetGadgetData(#Canvas, 10) ;Mode Brush
  EndIf
  
EndProcedure

Procedure CanvasUpdate()
  If StartDrawing(CanvasOutput(#Canvas)) 
    DrawingMode(#PB_2DDrawing_AlphaBlend)
    DrawAlphaImage(ImageID(#IMAGE_Draw), 0, 0)
    StopDrawing()
    SaveImage(#IMAGE_Draw, GetHomeDirectory()+"desktop\dummy.png", #PB_ImagePlugin_PNG)
  EndIf
EndProcedure


Open_MainForm()
ImageClear()
CanvasUpdate()

Repeat
  Event  = WaitWindowEvent()
  WEvent = EventWindow()
  MEvent = EventMenu()
  GEvent = EventGadget()
  TEvent = EventType()
  
  Select Event
    Case #PB_Event_Gadget
      Select GEvent
        Case #Canvas
          X = GetGadgetAttribute(#Canvas, #PB_Canvas_MouseX)
          Y = GetGadgetAttribute(#Canvas, #PB_Canvas_MouseY)
          
          Select TEvent
            Case #PB_EventType_LeftButtonUp
              SetGadgetAttribute(#Canvas, #PB_Canvas_Cursor, #PB_Cursor_Default)
              SetGadgetData(#Canvas, GetGadgetData(#Canvas) - 1) 
              
            Case #PB_EventType_LeftButtonDown
              SetGadgetAttribute(#Canvas, #PB_Canvas_Cursor, #PB_Cursor_Cross)
              SetGadgetData(#Canvas, GetGadgetData(#Canvas) + 1) 
              
              If GetGadgetData(#Canvas) = 21
                StartDrawing(ImageOutput(#IMAGE_Draw))
                DrawingMode(#PB_2DDrawing_AlphaBlend)
                FillArea(X, Y, -1, CurrentColor)
                StopDrawing()
                CanvasUpdate()
              EndIf
                              
            Case #PB_EventType_MouseMove
              If GetGadgetData(#Canvas) = 11
                StartDrawing(ImageOutput(#IMAGE_Draw))
                DrawingMode(#PB_2DDrawing_AllChannels)
                Circle(x, y, 5, CurrentColor)
                StopDrawing()
                CanvasUpdate()
              EndIf                
          EndSelect
          
        Case #Color
          CurrentColor = ColorRequester(CurrentColor)
          CurrentColor = RGBA(Red(CurrentColor),Green(CurrentColor),Blue(CurrentColor), 255)
          If GetGadgetData(#Canvas) = 10 And CurrentColor = RGBA(0, 0, 0, 255)
            CurrentColor = RGBA(1, 1, 1, 253)
          EndIf          
          
          CurrentColor = RGBA(Red(CurrentColor),Green(CurrentColor),Blue(CurrentColor), 255)
          If StartDrawing(ImageOutput(#IMAGE_Color))
            Box(0, 0, 80, 22, CurrentColor)
            StopDrawing()
            SetGadgetAttribute(#Color, #PB_Button_Image, ImageID(#IMAGE_Color))
          EndIf

        Case #Brush
          SetGadgetData(#Canvas, 10)
          SetGadgetState(#Brush, 1)
          SetGadgetState(#Paint, 0)
          
        Case #Paint
          SetGadgetData(#Canvas, 20)
          SetGadgetState(#Brush, 0)
          SetGadgetState(#Paint, 1)
          
        Case #Clear
          ImageClear()
          CanvasUpdate()
      EndSelect
        
    Case #PB_Event_CloseWindow
      End
      
  EndSelect
ForEver
j'allais oublier, l'image est sauvegardée au fur et à mesure sur le bureau.