问题
I have a "flawless" working code for putting a part of screen into square PictureBox.
I have a "flawless" working code for drawing on the picturebox with a pen.
I totally fail to understand, why I cannot get the pen draw on the bitmap in the PictureBox - it only draws on grey background.
The solution (also as per google) is seemingly simple, but ANY way to attempt to get gg graphics from PictureBox.Image results in ("An error occurred creating the form. See Exception.InnerException for details. The error is: Value cannot be null.
Parameter name: image" and "Use the 'New' keyword to create new instance of an object...").
I think that the trouble is in the way I define the bitmap as private outside a sub, but I cannot figure out correct concept...
Private bit As New System.Drawing.Bitmap(250, 250)
Private gg As Graphics = Graphics.FromImage(Me.PictureBox1.Image)
' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
' ^^^^^^^^^^ HERE IS THE PROBLEM ^^^^^^^^^^^^^^^^^^^^^^
' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Private br As New Pen(Color.Red)
Private dwn As Boolean
Private lst As Point
Private firstrun As Boolean = True
Dim Tloustka As Integer = 10
Dim Barva As Integer
Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
'gg = Graphics.FromImage(Me.PictureBox1.Image)
dwn = True
End Sub
Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
If dwn = True Then
Dim s As Integer
Dim xy As Point
Dim br2 As New SolidBrush(Color.FromName("White"))
s = Tloustka
br.Color = Color.FromName("White")
br.Width = Tloustka
xy.X = e.X
xy.Y = e.Y
If firstrun = True Then
lst = xy
firstrun = False
End If
gg.FillEllipse(br2, xy.X - CLng(s / 2), xy.Y - CLng(s / 2), s, s)
gg.DrawLine(br, lst, xy)
lst = xy
PictureBox1.Image = bit
End If
End Sub
etc. etc. etc.
回答1:
Don't store the Graphic object. Just create it from the bitmap when you need to draw something:
Private Sub PictureBox1_MouseMove(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseMove
If dwn = True Then
Using g As Graphics = Graphics.FromImage(bit)
Dim s As Integer
Dim xy As Point
Using br2 As New SolidBrush(Color.FromName("White"))
s = Tloustka
br.Color = Color.FromName("White")
br.Width = Tloustka
xy.X = e.X
xy.Y = e.Y
If firstrun = True Then
lst = xy
firstrun = False
End If
g.FillEllipse(br2, xy.X - CLng(s / 2), xy.Y - CLng(s / 2), s, s)
g.DrawLine(br, lst, xy)
End Using
End Using
lst = xy
PictureBox1.Invalidate()
End If
End Sub
Then use the paint event of the PictureBox to show the image:
Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
e.Graphics.DrawImage(bit, Point.Empty)
End Sub
Make sure you dispose of your graphic objects.
回答2:
All codes above seems a bit too complicated. In my case the simplest way was to do as follow:
Dim bm As Bitmap With PictureBox1 bm = New Bitmap(.Width, .Height) PictureBox1.DrawToBitmap(bm, New Rectangle(0, 0, .Width, .Height)) End With
... /code for printing/
bm.Dispose
P.S.: Any control can be drawn to bitmap.
来源:https://stackoverflow.com/questions/22969196/get-bitmap-from-picturebox-new-instance-of-an-object