Click here to Skip to main content
15,672,129 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
hello !

so i got this project , to make a paint like application . The Application must load and image and one must be able to draw on that image .

This loads the image and preps it for editing :
PictureBox4.Image = Image.FromFile(str)
PictureBox4.SizeMode = PictureBoxSizeMode.Zoom
Me.WindowState = FormWindowState.Maximized
Drawbitmap = New Bitmap(PictureBox4.Image)
Drawgraphics = Graphics.FromImage(Drawbitmap)
PictureBox4.Image = Drawbitmap
Drawing = False

This enables drawing on the picturebox :

Private Sub PictureBox4_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox4.MouseDown

Drawing = True

End Sub

This disables the drawing on the picturebox :

Private Sub PictureBox4_MouseUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox4.MouseUp

Drawing = False

End Sub

And this does the drawing

Private Sub PictureBox4_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox4.MouseMove
If Drawing Then
xStart = e.X
yStart = e.Y

End If
xEnd = e.X
yEnd = e.Y

End Sub

This is the drawMyine function :

Private Sub drawMyline()

PictureBox4.Image = Drawbitmap
Drawgraphics.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
Drawgraphics.DrawLine(p, xStart, yStart, xEnd, yEnd)
p.StartCap = LineCap.Round
p.EndCap = LineCap.Round

End Sub

My problem is the following : Everything works great except when i draw , the drawing does not start where the cursor is ,if i change
PictureBox4.SizeMode = PictureBoxSizeMode.Normal
the drawing start where it's supposed to (at the cursor position) but if i use
and if the image i'm loading it's bigger than the picturebox4 width and heigh it looks cropped .I could use
but the image should not have any scrollbars visible so that why i must use zoomed because it fits the image inside the picturebox. Can someone help me figure out how to draw properly on zoomed images ? Thank you !

P.S. if there is something you did not understand please let me know .

Don't ever draw anything on a PictureBox. This is one of the common mistakes of many beginners confused by this almost useless class, only designed to simplify the most basic graphic chores, like presenting a static image. Even though manipulating with PictureBox is possible, it will give you absolutely nothing but extra trouble, waste of development time and extra resources. In all more complex cases, you should forget it like a nightmare and render graphics directly on some custom control or even some control serving as a drawing pad, such as Panel.

I'll explain what to do. Please see my past answers:
Append a picture within picturebox[^],
draw a rectangle in C#[^],
How do I clear a panel from old drawing[^],
What kind of playful method is Paint? (DataGridViewImageCell.Paint(...))[^],
capture the drawing on a panel[^] (explains how it works),
Drawing Lines between mdi child forms[^],
How to speed up my application?[^],
Zoom image in C# .net mouse wheel[^] (this one is specifically on Zoom).

Share this answer
DamithSL 5-Jun-14 13:14pm    
Sergey Alexandrovich Kryukov 5-Jun-14 13:26pm    
Thank you, Damith.
Not that you actually voted... probably you forgot it... :-)
DamithSL 5-Jun-14 21:28pm    
Done! :-)
DrGrim 5-Jun-14 18:19pm    
thank you for your reply , i tried using a panel for this but i have the same issue , i can't find a way to fit the image in the panel or picturebox and draw on it properly , the only thing that makes the image fit in the control is if i use zoom but like i said , when i draw on the image the drawing does not start from where the cursor is , it's a bit off.
Sergey Alexandrovich Kryukov 6-Jun-14 0:28am    
Yes, you can zoom it. Why not? Do you know the algorithm of zooming? If you cannot fit the image, could you create a highly simplified code sample to demonstrate the problem?

Actually, what kind of image is that? If it is highly geometrical, you can make it a vector image which is particularly easy to zoom (using the transform Matrix). The vector image can be composed of graphic primitives.

i found out how to do this right

this is the url from which i got the code[^]

NOTE !! This will scale the image to "fit" the picturebox so if you decide to save the image it will save it using the scaled bitmap's resolution (if you load into your picturebox an image that has 1920x1080 you will save in a different resolution a lower one since it was scaled). To save the image with the same resolution do this :

lets say you want to load an image on form_load but before anything declare two variables like below
Dim defaultHeight As Integer
Dim defaultWidth As Integer

Now in form_load event add this

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim PicBoxHeight As Integer
Dim PicBoxWidth As Integer
Dim ImageHeight As Integer
Dim ImageWidth As Integer
Dim TempImage As Image
Dim scale_factor As Single
PictureBox1.SizeMode = PictureBoxSizeMode.Normal
' Get control size
PicBoxHeight = PictureBox1.Height
PicBoxWidth = PictureBox1.Width
' Load the image. Change Image.FromFile() to match your code
TempImage = Image.FromFile(str)
defaultWidth = TempImage.Width 'is the width of your selected image (unscaled)
defaultHeight = TempImage.Height 'is the height of your selected image (unscaled)
' Get image size
ImageHeight = TempImage.Height
ImageWidth = TempImage.Width
' Calculate scale_factor
scale_factor = 1.0 ' No scaling by default i.e. image fits in the Box
' 1) Height
If ImageHeight > PicBoxHeight Then
' Reduce height first
scale_factor = CSng(PicBoxHeight / ImageHeight)
End If
' 2) Width. Notice, we do know now how much we have to scale down the height
' and the scale_factor affects width too
If (ImageWidth * scale_factor) > PicBoxWidth Then
' Scaled width exceeds Box's width, recalculate scale_factor
scale_factor = CSng(PicBoxWidth / ImageWidth)
End If
' Move image to control for resizing
PictureBox1.Image = TempImage
' Get the source bitmap.
Dim bm_source As New Bitmap(PictureBox1.Image)
' Make a bitmap for the result.
Dim bm_dest As New Bitmap( _
CInt(bm_source.Width * scale_factor), _
CInt(bm_source.Height * scale_factor))
' Make a Graphics object for the result Bitmap.
Dim gr_dest As Graphics = Graphics.FromImage(bm_dest)
' Copy the source image into the destination bitmap.
gr_dest.DrawImage(bm_source, 0, 0, _
bm_dest.Width + 1, _
bm_dest.Height + 1)
' Display the result.
PictureBox1.Image = bm_dest
Drawbitmap = New Bitmap(PictureBox1.Image)
PictureBox1.Height = Drawbitmap.Height
Drawgraphics = Graphics.FromImage(Drawbitmap)
End Sub

Picturebox1 is just an example replace it with your picturebox
Now when you click the save button in my case it's another picturebox (you could use a button) add this to the click event

Private Sub PictureBox9_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PictureBox9.Click
Dim bmp As New Bitmap(PictureBox1.Image, defaultWidth, defaultHeight) ' this will take the bitmap from your Picturebox1.image and scale it to it's original width and hight
MessageBox.Show("Saved !")
End Sub

I hope there will be no misunderstandings when reading this . Enjoy and thank you for your replies once again.
Share this answer

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900