[5.40b1]Vector paint application

Partagez votre expérience de PureBasic avec les autres utilisateurs.
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

[5.40b1]Vector paint application

Message par blendman »

Salut

J'ai essayé de créer une petite application de peinture avec la nouvelle lib VectorDrawing.
Ce n'est pas très optimisé, mais ça fonctionne pas mal (sauf avec le zoom, où là, ça rame).

Si vous avez des idées pour optimiser ça, n'hésitez pas ;)
Code à Compiler avec la 5.40 :

Code : Tout sélectionner

; Exemple by blendman
; (VectorDrawing) - vector paint application
; PB 5.40b1 - september 2015

Enumeration ; Gadget
  
  #G_Canvas
  #G_BrushSize
  #G_BrushAlpha
  #G_BrushColor
  #G_BrushTexture
    
EndEnumeration

Enumeration ; menu
    
  #Menu_Clear
  #Menu_Save
  #Menu_ZoomPlus
  #Menu_ZoomLess
  #Menu_ZoomReset
  #Menu_Zoom20
  #Menu_Zoom50
  #Menu_Zoom100
  #Menu_Zoom200
  
EndEnumeration

Global z.d=1,canvasX.w,canvasY.w
Global w = 1024, h = 768

;{ Structures
Structure sBrush
  Size.w
  Alpha.a
  Color.q
  Texture.a
EndStructure
Global Brush.sbrush
Brush\Alpha = 120
Brush\Size = 20
brush\Color = RGBA(Red(color),Green(color),Blue(color),Brush\Alpha)


Structure sStroke
  Array dot.point(0)
  nbdot.i
  col.sBrush
EndStructure
Global Dim Stroke.sStroke(0)
NbStroke = -1
;}


UsePNGImageEncoder()
UsePNGImageDecoder()
UseJPEGImageDecoder()

Procedure SetZoom(zoom)
  
  If zoom = 1
    If z < 1
      z+0.1                     
    Else
      z +1
    EndIf   
  ElseIf zoom = -1
    If z > 1
      z-1 
    Else
      If z > 0.1
        z-0.1                     
      EndIf
    EndIf
  Else    
     z = zoom*0.01
  EndIf
  
  
  If StartVectorDrawing(CanvasVectorOutput(0))                   
    ; the white bg
    AddPathBox(0,0,w,h)
    VectorSourceColor(RGBA(255,255,255,255))
    FillPath()
    ; the image (layer)
    MovePathCursor(canvasX,canvasY)              
    DrawVectorImage(ImageID(1),255,w*z*2,h*z*2)                     
    StopVectorDrawing()   
  EndIf
  
EndProcedure

If OpenWindow(0, 0, 0, w, h, "Vector paint application", #PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_MaximizeGadget|#PB_Window_Maximize)
  
  ;{ Menu
  CreateMenu(0,WindowID(0))
  MenuTitle("Files")
  MenuItem(#Menu_Clear,"Clear")
  MenuItem(#Menu_Save,"Save")
  MenuTitle("Edit")
  MenuItem(#Menu_ZoomReset,"ResetZoom")  
  MenuItem(#Menu_Zoom20,"Zoom 20% ")
  MenuItem(#Menu_Zoom50,"Zoom 50% ")
  MenuItem(#Menu_Zoom100,"Zoom 100% ")
  MenuItem(#Menu_Zoom200,"Zoom 200% ")
  MenuBar()
  MenuItem(#Menu_ZoomPlus,"Zoom + ")
  MenuItem(#Menu_ZoomLess,"Zoom - ")
  ;}
  
  ;{ gadget  
  If CanvasGadget(0, 150, 0, w, h, #PB_Canvas_Keyboard) : EndIf
  y1 = 10
  If SpinGadget(#G_BrushSize,   10,y1,100,20,1,200,#PB_Spin_Numeric) 
    GadgetToolTip(#G_BrushSize,"Size of the brush")
    SetGadgetState(#G_BrushSize,brush\size)
    y1+30 
  EndIf
  If SpinGadget(#G_BrushAlpha,  10,y1,100,20,0,255,#PB_Spin_Numeric) 
    SetGadgetState(#G_BrushAlpha,brush\Alpha)
    GadgetToolTip(#G_BrushAlpha,"Alpha of the brush")
    y1+30 
  EndIf
  
  If ComboBoxGadget(#G_BrushTexture,  10,y1,100,20) 
    AddGadgetItem(#G_BrushTexture,0,"Use Color")
    AddGadgetItem(#G_BrushTexture,1,"Use Texture")
    AddGadgetItem(#G_BrushTexture,2,"Change Texture")
   y1+30 
  EndIf
  
  If ImageGadget(#G_BrushColor, 10,y1,50,50,CreateImage(2,50,50)) : y1+110 : EndIf
  
  ;}
  
  
  LoadImage(0, #PB_Compiler_Home + "examples/Sources/Data/PureBasicLogo.bmp")
  CreateImage(1,w*2,h*2,32,#PB_Image_Transparent)
  
  If StartDrawing(ImageOutput(1))
    DrawingMode(#PB_2DDrawing_AlphaBlend)
    ClearColor = RGBA(230,230,230,255)
    Box(0,0,OutputWidth(),OutputHeight(),ClearColor) ; on efface l'image
    StopDrawing()
  EndIf
   
  Repeat
    
    Event       = WaitWindowEvent()
    EventGadget = EventGadget()
    EventMenu   = EventMenu()
    
    Select event
        
      Case #PB_Event_Menu
        
        Select EventMenu
            
          Case #Menu_Zoom20
            SetZoom(20)
          Case #Menu_Zoom50
            SetZoom(50)
          Case #Menu_Zoom200
            SetZoom(200)  
          Case #Menu_Zoom100
            SetZoom(100)
          Case #Menu_ZoomReset
            CanvasX = 0
            CanvasY = 0
            SetZoom(100)            
          Case #Menu_ZoomPlus
            SetZoom(1)
          Case #Menu_ZoomLess
           SetZoom(-1)
          Case #Menu_Clear
            If StartVectorDrawing(CanvasVectorOutput(0))                   
              AddPathBox(0, 0, w,h)
              VectorSourceColor(RGBA(255,255,255,255))
              FillPath()
              StopVectorDrawing()
            EndIf
            If StartDrawing(ImageOutput(1))
              DrawingMode(#PB_2DDrawing_AlphaBlend)
              Box(0,0,OutputWidth(),OutputHeight(),ClearColor) ; on efface l'image
              StopDrawing()
            EndIf
            
          Case #Menu_Save
            SaveImage(1,"save01.png",#PB_ImagePlugin_PNG) 
            
        EndSelect
        
      Case #PB_Event_Gadget
        
        Select EventGadget
            
          Case #G_Canvas 
            
            If GetGadgetAttribute(0, #PB_Canvas_Key) = #PB_Shortcut_Space
              space = 1
            EndIf
            
            If EventType() = #PB_EventType_LeftButtonUp
              space = 0
            ElseIf EventType() = #PB_EventType_LeftButtonDown 
              startx.d = GetGadgetAttribute(0, #PB_Canvas_MouseX)/z
              starty.d = GetGadgetAttribute(0, #PB_Canvas_MouseY)/z  
              OldCanvasX = CanvasX
              OldCanvasY = CanvasY 
              
              ; create a new stroke_path
              NbStroke+1
              ReDim Stroke(NbStroke)
              stroke(NbStroke)\nbdot+1              
              n = stroke(NbStroke)\nbdot
              ReDim Stroke(NbStroke)\dot(n)
              Stroke(NbStroke)\dot(1)\x = startx-canvasX/z
              Stroke(NbStroke)\dot(1)\y = starty-canvasY/z
              Stroke(NbStroke)\col\Alpha = brush\alpha
              Stroke(NbStroke)\col\Size = brush\Size
              Stroke(NbStroke)\col\Texture = brush\Texture
              Stroke(NbStroke)\col\Color = brush\Color
              Stroke(NbStroke)\col\Color = brush\Color
                             
            ElseIf(EventType() = #PB_EventType_MouseMove And GetGadgetAttribute(0, #PB_Canvas_Buttons) & #PB_Canvas_LeftButton)
              
              If space = 1 ; we move the canvas
                canvasX = GetGadgetAttribute(0, #PB_Canvas_MouseX) - startX + OldCanvasX
                canvasY = GetGadgetAttribute(0, #PB_Canvas_MouseY) - startY + OldCanvasY
              Else ; we paint on the image
                If StartVectorDrawing(ImageVectorOutput(1))
                  x.d = GetGadgetAttribute(0, #PB_Canvas_MouseX) / z 
                  y.d = GetGadgetAttribute(0, #PB_Canvas_MouseY) / z 
                  
                  ; erase the image 
                  AddPathBox(0,0,ImageWidth(1),ImageHeight(1))
                  VectorSourceColor(ClearColor)
                  FillPath()
                  
                  ; draw all the stroke // not optimised !
                  stroke(NbStroke)\nbdot+1
                  n = stroke(NbStroke)\nbdot
                  ReDim Stroke(NbStroke)\dot(n)
                  Stroke(NbStroke)\dot(n)\x = x-canvasX/z
                  Stroke(NbStroke)\dot(n)\y = y-canvasY/z
                  
                  For j=0 To NbStroke
                    With Stroke(j)
                      For i = 2 To ArraySize(\dot())
                        MovePathCursor(\dot(i)\x,\dot(i)\y)
                        AddPathLine(\dot(i-1)\x-\dot(i)\x, \dot(i-1)\y-\dot(i)\y,#PB_Path_Relative)
                      Next i                     
                      VectorSourceColor(\col\color)
                      If \col\texture = 1
                        VectorSourceImage(ImageID(0),\col\alpha,ImageWidth(0),ImageHeight(0),#PB_VectorImage_Repeat)
                      EndIf             
                      StrokePath(\col\size ,#PB_Path_RoundEnd)
                    EndWith
                  Next 
                  StopVectorDrawing()
                EndIf
                
                StartX = Stroke(NbStroke)\dot(n)\x
                StartY = Stroke(NbStroke)\dot(n)\y
                
              EndIf
              
              ; update the canvas
              If StartVectorDrawing(CanvasVectorOutput(0))
                ; the white bg
                AddPathBox(0, 0, w,h)
                VectorSourceColor(RGBA(255,255,255,255))
                FillPath()
                ; the image (layer)
                MovePathCursor(canvasX,canvasY)              
                DrawVectorImage(ImageID(1),255,w*z*2,h*z*2)                     
                StopVectorDrawing()
              EndIf
              
            EndIf
            
          Case #G_BrushColor
            If EventType() = #PB_EventType_LeftClick
              color = ColorRequester(brush\Color)
              brush\Color = RGBA(Red(color),Green(color),Blue(color),Brush\Alpha)
              If StartDrawing(ImageOutput(2))
                Box(0,0,50,50,color)
                StopDrawing()
              EndIf 
              SetGadgetState(#G_BrushColor,ImageID(2))
            EndIf
          
          Case #G_BrushTexture  
            Select GetGadgetState(#G_BrushTexture)
              Case 0
                brush\Texture = 0
              Case 1
                brush\Texture = 1
              Case 2
                file$ = OpenFileRequester("Change texture","","Image|*.jpg;*.png;*.bmp",0)
                If file$ <> ""
                  If LoadImage(0, file$) =0
                    MessageRequester("Error","Unable To load the image")
                  EndIf
                EndIf
                
            EndSelect           
            
          Case #G_BrushAlpha, #G_BrushSize
            Brush\Alpha = GetGadgetState(#G_BrushAlpha)
            brush\Color = RGBA(Red(color),Green(color),Blue(color),Brush\Alpha)
            Brush\Size = GetGadgetState(#G_BrushSize)
            
        EndSelect
                
      Case #PB_Event_CloseWindow
        quit = 1
        
    EndSelect
    
  Until quit = 1 
  
EndIf
Avatar de l’utilisateur
microdevweb
Messages : 1798
Inscription : mer. 29/juin/2011 14:11
Localisation : Belgique

Re: [5.40b1]Vector paint application

Message par microdevweb »

Merci du partage, Blendman c'est vrai que elle va être précieuse cette lib
Windows 10 64 bits PB: 5.70 ; 5.72 LST
Work at Centre Spatial de Liège
Mesa
Messages : 1093
Inscription : mer. 14/sept./2011 16:59

Re: [5.40b1]Vector paint application

Message par Mesa »

Chez moi le zoom est instantané avec un ordi de base pour bureautique tout simple.

M.
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: [5.40b1]Vector paint application

Message par blendman »

Mesa a écrit :Chez moi le zoom est instantané avec un ordi de base pour bureautique tout simple.
Oui, le zoom est instantané, mais lorsque tu dessines, ça n'est pas plus lent qu'à 100% ?
Chez moi, c'est environ 2 fois plus lent.
Sans doute est-ce lié à l'interpolation, c'est pour ça que ce serait mieux de pouvoir gérer par nous-même l'interpolation (en la définissant comme on le souhaite).
Mesa
Messages : 1093
Inscription : mer. 14/sept./2011 16:59

Re: [5.40b1]Vector paint application

Message par Mesa »

Oui c'est plus lent.

M.
Répondre