Mit Stift auf Picturebox/Bitmap zeichnen - Ohne Unterbrechungen/Wackler (rudimentärer Paint Clon)

    • VB.NET

    Es gibt 36 Antworten in diesem Thema. Der letzte Beitrag () ist von Mono.

      Mit Stift auf Picturebox/Bitmap zeichnen - Ohne Unterbrechungen/Wackler (rudimentärer Paint Clon)

      Hi Liebe Com,

      ich habe mit ein paar Recherchen im Netz ein kleinen Paint Clon geschrieben. Funktionen sind lediglich zeichnen mit einem Stift in allen Farben und Dicken.
      Ich denke als Ansatz wie man zeichnet OHNE das bei schnellen Mausbewegungen Lücken entstehen, kann man den Code gebrauchen.
      Man braucht 1 Form(PaintForm) 1 Picturebox(PBDraw) 3 ComboBoxen(CBPenWidth,CBPenColor,CBPBBGColor)
      Am besten die PB oben andocken und unten die 3 Comboboxen hin:

      //Edit
      Neu: 2 Buttons: SaveButton & ClearButton

      VB.NET-Quellcode

      1. Public Class PaintForm
      2. Private MouseD As Boolean
      3. Private Col As Color
      4. Private NewPen As Pen
      5. Private bmp As Bitmap
      6. Private Plist As List(Of Point)
      7. Private HG_Bmp As Bitmap
      8. Private Sub PBDraw_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PBDraw.MouseDown
      9. MouseD = True
      10. Plist.Add(New Point(e.X, e.Y))
      11. End Sub
      12. Private Sub PBDraw_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PBDraw.MouseUp
      13. If MouseD Then
      14. MouseD = False
      15. Using gr = Graphics.FromImage(bmp)
      16. Draw(gr)
      17. gr.Flush()
      18. End Using
      19. Using gr = Graphics.FromImage(HG_Bmp)
      20. gr.DrawImage(bmp, 0, 0)
      21. gr.Flush()
      22. End Using
      23. Plist.Clear()
      24. PBDraw.Invalidate()
      25. End If
      26. End Sub
      27. Private Sub PBDraw_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PBDraw.MouseMove
      28. If MouseD Then
      29. Plist.Add(New Point(e.X, e.Y))
      30. PBDraw.Invalidate()
      31. End If
      32. End Sub
      33. Private Sub PBDraw_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles PBDraw.Paint
      34. If MouseD Then Draw(e.Graphics)
      35. End Sub
      36. Private Sub Draw(ByVal g As Graphics)
      37. If Plist.Count > 0 Then
      38. Dim bs As Byte() = New Byte(Plist.Count - 1) {}
      39. bs(0) = CByte(System.Drawing.Drawing2D.PathPointType.Start)
      40. For a as Integer = 1 To Plist.Count - 1
      41. bs(a) = CByte(System.Drawing.Drawing2D.PathPointType.Line)
      42. g.DrawPath(NewPen, New System.Drawing.Drawing2D.GraphicsPath(Plist.ToArray, bs))
      43. Next
      44. End If
      45. End Sub
      46. Private Function GetColors() As List(Of String)
      47. Dim colors As New List(Of String)()
      48. Dim colorNames As String() = [Enum].GetNames(GetType(KnownColor))
      49. For Each colorName As String In colorNames
      50. Dim knownColor As KnownColor = DirectCast([Enum].Parse(GetType(KnownColor), colorName), KnownColor)
      51. If knownColor > knownColor.Transparent Then
      52. colors.Add(colorName)
      53. End If
      54. Next
      55. Return colors
      56. End Function
      57. Private Sub PainForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
      58. HG_Bmp = New Bitmap(PBDraw.Width, PBDraw.Height)
      59. bmp = New Bitmap(PBDraw.Width, PBDraw.Height)
      60. Using gr As Graphics = Graphics.FromImage(bmp)
      61. gr.Clear(Color.Transparent)
      62. PBDraw.Invalidate()
      63. End Using
      64. Using gr As Graphics = Graphics.FromImage(HG_Bmp)
      65. gr.Clear(Color.White)
      66. gr.DrawImage(bmp, 0, 0)
      67. PBDraw.Invalidate()
      68. End Using
      69. PBDraw.Image = HG_Bmp
      70. Plist = New List(Of Point)
      71. Me.DoubleBuffered = True
      72. For Each c As String In GetColors()
      73. CBPenColor.Items.Add(c)
      74. CBPBBGColor.Items.Add(c)
      75. Next
      76. For a as Integer = 1 To 25
      77. CBPenWidth.Items.Add(a.ToString)
      78. Next
      79. CBPenColor.SelectedItem = CBPenColor.Items(0)
      80. CBPenWidth.SelectedItem = CBPenWidth.Items(0)
      81. End Sub
      82. Private Sub CBPenColor_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CBPenColor.SelectedIndexChanged, CBPenWidth.SelectedIndexChanged
      83. NewPen = New Pen(Color.FromName(CBPenColor.SelectedItem), CSng(CBPenWidth.SelectedItem))
      84. End Sub
      85. Private Sub CBPBBGColor_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CBPBBGColor.SelectedIndexChanged
      86. Using gr As Graphics = Graphics.FromImage(HG_Bmp)
      87. gr.Clear(Color.FromName(CBPBBGColor.SelectedItem))
      88. gr.DrawImage(bmp, 0, 0)
      89. PBDraw.Invalidate()
      90. End Using
      91. End Sub
      92. Private Sub SaveButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SaveButton.Click
      93. Dim sfd As New SaveFileDialog
      94. sfd.Filter = ".jpg|*.jpg"
      95. sfd.AddExtension = True
      96. If sfd.ShowDialog = Windows.Forms.DialogResult.OK Then
      97. HG_Bmp.Save(sfd.FileName, System.Drawing.Imaging.ImageFormat.Jpeg)
      98. End If
      99. End Sub
      100. Private Sub ClearButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ClearButton.Click
      101. Using gr As Graphics = Graphics.FromImage(bmp)
      102. gr.Clear(Color.Transparent)
      103. PBDraw.Invalidate()
      104. End Using
      105. Using gr As Graphics = Graphics.FromImage(HG_Bmp)
      106. gr.Clear(Color.White)
      107. gr.DrawImage(bmp, 0, 0)
      108. PBDraw.Invalidate()
      109. End Using
      110. End Sub
      111. End Class

      Man kann sauber zeichnen ohne Ruckeln, ohne fehlende Pixel bei schnellen Mausemoves etc.

      Ich denke dies ist SourceCodewürdig, da oft die Frage kommt, wie mach ich ein Paint Clone. Hier ist nun ein Ansatz zu finden, wie man sowas selber coden kann.

      Über Kritiken würde ich mich sehr freuen

      Gruss Mono :)


      *EDIT*

      Ich habe eine Save Button hinzugefügt.
      ACHTUNG

      Wenn man die Hintergrundfarbe ändert wird das Bild gelöscht.
      Ich weiß grad keine Lösung wie man den HG des bitmaps komplett ändert, ohne den Vordergrund zu löschen.

      *EDIT* 30.04.2010

      Ich habe nun eine 2. Ebene als Hintergrund eingebaut. damit kann man nun den Hintergrund ändern ohne den Vordergrund zu löschen.
      Ausserdem einen weiteren Button Namens ClearButton.
      Damit kann man das komplette Bild löschen.

      // Hat denn keiner weitere Kritiken daran ?
      Was könnte denn besser gemacht werden etc.. wo optimieren ? ^^
      Oder schaut es sich bloß keiner von den Pro's an

      Wie auch immer. Vll hilfts ja dem einen oder anderen Anfänger.


      Gruß Mono

      //EDIT

      For a Zu FOR A AS INTEGER geändert..
      Das ist meine Signatur und sie wird wunderbar sein!

      Dieser Beitrag wurde bereits 8 mal editiert, zuletzt von „Mono“ ()

      Wenn du den Hintergrund änderst, wird das Bild quasi gelöscht.

      VB.NET-Quellcode

      1. Using gr As Graphics = Graphics.FromImage(bmp)
      2. gr.Clear(Color.White)
      3. PBDraw.Invalidate()
      4. End Using


      so für komplettes bitmap 'clearen' und hg auf weiß setzen.

      Wie gesagt, es ist hier nur ein Ansatz
      Das ist meine Signatur und sie wird wunderbar sein!

      Phthmaster99 schrieb:


      HI,
      bei mir funktionierts net. Ich benutze Visual Basic 2008 Express Edition... Kannst du eventuell mal den sourcecode als downloadlink reinstellen?


      MFG

      PhThmaster99


      Der komplette Code steht doch da...was funktioniert denn nicht ?
      Das ist meine Signatur und sie wird wunderbar sein!

      Phthmaster99 schrieb:


      ich meine die .vbproject oder wie auch immer dateien...

      Wieso brauchst du die ?
      Was bekommst du denn nicht hin ?
      Der komplette Code PLUS benötigte Steuerelemente stehen doch da....
      Das ist meine Signatur und sie wird wunderbar sein!
      Sry, das ich so spät antworte..

      Folgender Error kommt:
      "Name 'a' is not declared"
      "Name 'a' is not declared"
      "Name 'a' is not declared"

      "Name 'a' is not declared"


      4 mal kommt die gleiche errormeldung.. -.-

      Kann jemand helfen?

      ich teste mahl selbst!

      man mier reicht der ganze müll hier, ich werde eventuell die Project Mappe Posten und dan ist gut, der gesamte koode ist sehr Flüßig und einwandfrei geschrieben was wolt ihr den, und chekt eure verwise den die sind dass Problem nummer 1 wen etwas nicht gefunden wird!
      bei mier gibt es 4 Error dass a nicht Declariert ist, wo bei ich den Rest ja schon gut hinbekommen habe, zugegeben ich habe einige buttopn gegen Andere Steuerelemente ersetzt aber dass hat mit a nichts zu tuhen


      VB.NET-Quellcode

      1. For a = 1 To Plist.Count - 1bs(a) = CByte(System.Drawing.Drawing2D.PathPointType.Line)
      2. g.DrawPath(NewPen, New System.Drawing.Drawing2D.GraphicsPath(Plist.ToArray, bs))Next