Hello Everybody:
I have submitted another small project that looks somehow like this one, It is called "Magnet", but this one is a lot different and uses some techniques I have developed.
The excuse is a paint program "Wet Paint", but here I have been experimenting with multiple line tracing, color assignment and picking and watermarking. I called it Wet Paint because when you touch it it sticks to your fingers.(And I am using a hand as cursor).
Here is a view of the screen:

It works with 18 different points, 9 starting points and the other 9 finish points. Here I am tracing 9 lines from an initial point to the corresponding final point, but the points change with the mouse moving, so the final points become the starting and new finishing points are created. So when we draw the straight lines, they go from point to point, but because they are very close together, we can have curved lines traced on the canvas.
The initial choice is the "Ribbon", so, when you click and drag the mouse you get a multicolor streak painted, and if you make a curved trace you will have some somehow parallel streaks resembling "peppermint candy".
On this operation the selected 9 points are arranged like a "Cross", shown on the small panel to the left of the picturebox, one vertical line bisecting an horizontal line, so when you drag, whatever direction, you have about the same thickness of trace. This thickness is selected from the combobox on top of the desktop. The default is 3 and it can go from 1 to 5. This is the thickness of the individual lines, but the total will add on the adjacent lines, so it will be thicker. Using more points won't have sense because one trace will be on top of the other; better results could come from the thickness of the lines.
If you select "FlatV" or "FlatH", some dots are hidden and deselected, so you have a vertical or an horizontal line and the trace will be narrow in one direction and wide on the other.
When you are using the ribbon drawing, you are using the initial colors or the ones that may remain from some other operation or choices, but you can select colors from the color picker. These will assign a new color to one point for each click, in the following order:
1. Center
2. Far Left
3. Far Right
4. Far Top
5. Far Bottom
6. Mid Left
7. Mid Top
8. Mid Bottom
9. Mid Right
An important note here:
If you have some dots hidden, you still have to click to get that color assigned, but you won't see it happening , so just keep clicking.
OK! Now the trace will be done with your selected colors.
If you select "Drag Color" the initial 9 colors will be kept. If you happen to click where there are colors, you will have continuous lines of the picked colors until you release the mouse button.
If instead, you select "smudge", the colors will change so often as you trace over existing image, so the colors will be dragged a short distance and new colors picked. So you kind of smudge the image, especially if you go back and forth as on a zigzag movement. The effect is different according to the thickness selection on the combobox.
When selecting "Erase" the operation is the same as "Drag Colors", but the color is set to white, and the thickness of the trace is not affected by the combobox selection.
When you select "stamp", we are on a completely different operation. Here we will apply an small image, with different transparencies on top of the canvas. The position where it will appear is at the last "mouseup" position. So if you want the image to appear around the middle top, you will click there,(X and Y position of left-top corner of small image) and then click on one of the icons besides the color picker. The default size is set to 50 pixels, but you can change it with the trackbar at top. The thumbnail applied is not a very good quality because is generated with the built in thumbnail function of the framework, but for this example is good enough.
These images and the traced lines become part of the image, so it can be saved to disk.
Another note here: The images on the combobox are loaded from an imagelist and the tooltips give you some information. Because we are working with pixels around the mouse pointer, we may go past the edge of the image, so we just catch and ignore the error on a "try-catch-end try" structure.
Ok! Here is the code:
'Global values
Imports System.Drawing
Imports System.Drawing.Drawing2D
Public Class Form1
#Region "Global"
'This image is a white picture and is used to clear everything on the screen, so you can start fresh
Dim Reload As Image
'We will be using this bitmap to draw on during the program
Dim bmx As Bitmap
'This is a new size for the watermarks that we would apply to the image
Dim resized As Bitmap
' We will trace a thick white line (same color as the canvas) to erase anything on its path
Dim ErasePen As New Pen(Color.White, 4)
'Drawing graphics object.
Dim gr As Graphics
For drawing we need two objects a bitmap object and a graphics object. The graphics object is like a transparent sheet of plastic on top of a table, if you spill coffee or pop, you will see the puddle, but you wipe it off and the table is intact. The same happens with the graphics object, you are drawing with crayons on the plastic, you can see them, but it is not permanent, as soon as the windows goes out of view the image disappears. To have permanent changes on an image you need to resort to a bitmap. When you draw on it, it is changed and the alteration fuses as a part of the image.
"this is a control to keep track of entering more than once to a routine. It helps on the decision of what to do.
Dim FirstTime As Boolean = True
'Color variables to use for the different path tracings
Dim Color1, Color2, Color3, Color4, Color5, Color6, Color7, Color8, Color9 As Color
Dim Color1a, Color2a, Color3a, Color4a, Color5a, Color6a, Color7a, Color8a, Color9a As Color
' Multi function variable, related to position of pixels and width of lines
Dim SmudgeWidth As Integer = 3
'arrays of points; here we keep the initial and final points of 9 line segments
Private ThePts1(2), ThePts2(2), ThePts3(2), ThePts4(2), ThePts5(2), ThePts6(2), ThePts7(2), ThePts8(2), ThePts9(2) As Point
#End Region
The next block sets the initial values of the variables that we will use and some of the display gadgets: We have on this project an image list that was loaded with 5 small bitmaps. These bitmaps(pictures) are to be displayed on the combobox instead of text. So, when you click on the combobox, you can select by image, the thickness of the lines you will trace and how far apart the pixels for reading and applying color should be. These images need to be drawn on the combobox control; you can't load them directly.
Here also we assign a copy of the image to "Reload", so we don't change it and we can load it again if we need to. and assign some initial colors to the variables, so when we start, we won't just draw a white trace on top of white. Also we assign background color to the small dots(labels) on the visual display of pixel, you will see a "cross" shape with several colors on it. We set which checkbox is the default to start and create the tooltips as help.
#Region "Initial Values"
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim items(Me.ImageList1.Images.Count - 1) As String
For i As Int32 = 0 To Me.ImageList1.Images.Count - 1
items(i) = "Item " & i.ToString
Next
ComboBox1.Items.AddRange(items)
ComboBox1.DropDownStyle = ComboBoxStyle.DropDownList
ComboBox1.DrawMode = DrawMode.OwnerDrawVariable
ComboBox1.ItemHeight = Me.ImageList1.ImageSize.Height
ComboBox1.Width = Me.ImageList1.ImageSize.Width + 18
ComboBox1.MaxDropDownItems = Me.ImageList1.Images.Count
ComboBox1.SelectedIndex = 2
Reload = Work.Image.Clone
'Initial Colors, so it will trace when moving on picturebox
Color1a = Color.Black
Color2a = Color.Olive
Color3a = Color.Purple
Color4a = Color.Teal
Color5a = Color.LawnGreen
Color6a = Color.LightCoral
Color7a = Color.Red
Color8a = Color.DodgerBlue
Color9a = Color.Firebrick
Label1.BackColor = Color1a
Label2.BackColor = Color2a
Label3.BackColor = Color3a
Label4.BackColor = Color4a
Label5.BackColor = Color5a
Label6.BackColor = Color6a
Label7.BackColor = Color7a
Label8.BackColor = Color8a
Label9.BackColor = Color9a
Rb5.Checked = True
ToolTip1.SetToolTip(pbPicker, "Pick Individual Colors For Ribbon Streaks" & vbNewLine & "You May Pick 9 Of Them")
ToolTip1.SetToolTip(Rb1, "If You Click And Drag Where there Are Colors" & vbNewLine & "Will Drag The Colors")
ToolTip1.SetToolTip(Rb2, "Will Smudge Area")
ToolTip1.SetToolTip(Rb3, "Will Apply Selected Image From Chart" & vbNewLine & "At Last Mouse Up Position")
ToolTip1.SetToolTip(Rb4, "Will Erase Area Around Mouse Path")
ToolTip1.SetToolTip(Rb5, "Will Draw Multicolor Streak, Cross, Vertical Or Horizontal")
ToolTip1.SetToolTip(Panel2, "Indicates Color And position Of Colors On Streak")
End Sub
The following routines do the painting of the images on the combobox. This is to use as a kitchen recipe.
#Region "Paint Images On ComboBox"
Private Sub ComboBox1_DrawItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawItemEventArgs) Handles ComboBox1.DrawItem
If e.Index <> -1 Then
e.Graphics.DrawImage(Me.ImageList1.Images(e.Index), e.Bounds.Left, e.Bounds.Top)
End If
End Sub
Private Sub ComboBox1_DrawItem1(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawItemEventArgs) 'Handles
ComboBox1.DrawItem
If e.Index <> -1 Then
e.Graphics.DrawImage(Me.ImageList1.Images(e.Index), e.Bounds.Left, e.Bounds.Top)
e.Graphics.DrawString(ComboBox1.Items(e.Index).ToString(), ComboBox1.Font, _
System.Drawing.Brushes.Black, _
New RectangleF(e.Bounds.X + 15, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height))
e.DrawFocusRectangle()
End If
End Sub
Private Sub ComboBox1_MeasureItem(ByVal sender As Object, ByVal e As System.Windows.Forms.MeasureItemEventArgs) Handles
ComboBox1.MeasureItem
e.ItemHeight = Me.ImageList1.ImageSize.Height
e.ItemWidth = Me.ImageList1.ImageSize.Width
End Sub
#End Region
#End Region
Ok, after starting the program and looking at the screen we have few options, start drawing or changing settings. I would start drawing.
Experimenting won't spoil anything, and you see how the program behaves. Anyway., if before changing anything you click on the picturebox and drag the mouse around, you will see a trailing multicolor streak. These are the initial colors that are dragged and drawn on the graphics object. How is it done? Ok, that is simple: you trace a small line from one point to the next and repeat it for all nine sets of points. Each segment has its color.
The points where to draw the straight line are set by clicking and moving the mouse. I will follow only one line, but the others will be similar, except that the points are displaced around a central one. It has its implications, but we will see that later. For now, the first point is gotten with the mousedown event handler. We create a bitmap from the existing image, and when clicking, there is a parameter "e" that tell us where the mouse is on the bitmap. This is a point and it has two coordinates "X" and "Y", measured from the top and the left of the image. So we have the coordinates of a point and will we save it in one of our point variables.
What is next? Ok, to draw a line we need two points, an origin and a destination. Now we have the first one. The second one is created in a second routine handler, the mouse move. This handler routine also has a parameter "e", that tells where the mouse is when is changing position. Here is important to mention that the mouse move won't detect the mouseclick or mousedown initial points, only the one where it is if it is moving. This parameter also has a "X' and a "Y" values that we save on the second element of the array, remember that the pts variables are arrays. Having these two points we can draw our line segment.
When the mouse goes down we save 9 initial points and 9 colors and when we go up, we save 9 final points and 9 final colors(depending on the operation).
Where are these points? Look at the small cross. And check above at the description of the program.
Here we have a situation as I have mentioned before: the mouse can move all around the surface of the image and out of it. If we are moving very close to the limits or at the limits, some of the calculated positions for the pixels are outside the image. They don't exist. So, what do we do? Ignore the error (exception) and keep drawing as nothing has happened. No message, no delay, just smooth drawing going out of the image and in again> Pretty neat!
#Region "First Points"
Private Sub Work_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Work.MouseDown
'Initial points and initial Colors
bmx = New Bitmap(Work.Image)
ThePts1(0).X = e.X
ThePts4(0).X = e.X
ThePts5(0).X = e.X
ThePts7(0).X = e.X
ThePts8(0).X = e.X
' Save the new points
If e.X < 4 Then
ThePts2(0).X = e.X
Else
ThePts2(0).X = e.X - 2 * SmudgeWidth
End If
If e.X < 2 Then
ThePts6(0).X = e.X
Else
ThePts6(0).X = e.X - SmudgeWidth
End If
If e.X > Work.Width - 2 * SmudgeWidth Then
ThePts3(0).X = e.X
Else
ThePts3(0).X = e.X + 2 * SmudgeWidth
End If
If e.X > Work.Width - SmudgeWidth Then
ThePts9(0).X = e.X
Else
ThePts9(0).X = e.X + SmudgeWidth
End If
ThePts1(0).Y = e.Y
ThePts2(0).Y = e.Y
ThePts3(0).Y = e.Y
ThePts6(0).Y = e.Y
ThePts9(0).Y = e.Y
If e.Y < 4 Then
ThePts4(0).Y = e.Y
Else
ThePts4(0).Y = e.Y - 2 * SmudgeWidth
End If
If e.Y < 2 Then
ThePts7(0).Y = e.Y
Else
ThePts7(0).Y = e.Y - SmudgeWidth
End If
If e.Y > Work.Height - 2 * SmudgeWidth Then
ThePts5(0).Y = e.Y
Else
ThePts5(0).Y = e.Y + 2 * SmudgeWidth
End If
If e.Y > Work.Height - 2 * SmudgeWidth Then
ThePts8(0).Y = e.Y
Else
ThePts8(0).Y = e.Y + SmudgeWidth
End If
Try
If Rb5.Checked = False Then
Color1a = bmx.GetPixel(ThePts1(0).X, ThePts1(0).Y)
Color2a = bmx.GetPixel(ThePts2(0).X, ThePts2(0).Y)
Color3a = bmx.GetPixel(ThePts3(0).X, ThePts3(0).Y)
Color4a = bmx.GetPixel(ThePts4(0).X, ThePts4(0).Y)
Color5a = bmx.GetPixel(ThePts5(0).X, ThePts5(0).Y)
Color6a = bmx.GetPixel(ThePts6(0).X, ThePts6(0).Y)
Color7a = bmx.GetPixel(ThePts7(0).X, ThePts7(0).Y)
Color8a = bmx.GetPixel(ThePts8(0).X, ThePts8(0).Y)
Color9a = bmx.GetPixel(ThePts9(0).X, ThePts9(0).Y)
End If
Color1 = Color1a
Color2 = Color2a
Color3 = Color3a
Color4 = Color4a
Color5 = Color5a
Color6 = Color6a
Color7 = Color7a
Color8 = Color8a
Color9 = Color9a
Catch
End Try 'Here we ignore the exception
End Sub
#End Region
On mousemove we change points and colors. We are moving along on the image, and having fun, but behind the scenes we have lots of things going on. We are not just moving from one point to the next and stopping. We keep moving, but we update our points and colors. When we move to the third point, the first one disappears and the second takes its place, so we have new origin and new destination all the time until we release the mouse button. I have few if controls to assign values when we are near the edge of the image, they are not really needed because we are ignoring the errors, but I thought that is was better to program for that too.
#Region "While Moving"
#Region "Operation"
Private Sub Rb5_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Rb5.CheckedChanged
If Rb5.Checked = True Then
CheckBox1.Enabled = True
CheckBox2.Enabled = True
CheckBox3.Enabled = True
Else
CheckBox1.Enabled = False
CheckBox2.Enabled = False
CheckBox3.Enabled = False
End If
If FirstTime = True Then "Different operation for first time and subsequent entries
Label1.BackColor = Color1a
Label2.BackColor = Color2a
Label3.BackColor = Color3a
Label4.BackColor = Color4a
Label5.BackColor = Color5a
Label6.BackColor = Color6a
Label7.BackColor = Color7a
Label8.BackColor = Color8a
Label9.BackColor = Color9a
Else
Label1.BackColor = Color1
Label2.BackColor = Color2
Label3.BackColor = Color3
Label4.BackColor = Color4
Label5.BackColor = Color5
Label6.BackColor = Color6
Label7.BackColor = Color7
Label8.BackColor = Color8
Label9.BackColor = Color9
End If
Refresh()
FirstTime = False
End Sub
Private Sub ClearToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Clear.Click
Work.Image = Reload.Clone
End Sub
#End Region
Everything here happens on similar manner for the different choices. The initial operation is the ribbon tracing, but we can select other operations. These selections or settings are done with the checkboxes and radiobuttons that branch the program on if-then-else-end if controls. The sub-selections of the ribbon choice are "FlatV" and "FlatH" . Same operation, but less points arranged on a vertical or horizontal pattern, so the trace is narrower on one direction and wider on the other.
#Region "Drawing"
Private Sub Work_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Work.MouseMove
Dim bmx As New Bitmap(Work.Image)
If (e.Button = MouseButtons.Left) Then
' Do nothing if we're not selecting a region.
If ThePts1 Is Nothing Then Exit Sub
Try
ThePts1(1).X = e.X
ThePts4(1).X = e.X
ThePts5(1).X = e.X
ThePts7(1).X = e.X
ThePts8(1).X = e.X
' Save the new points
If e.X < 4 Then
ThePts2(1).X = e.X
Else
ThePts2(1).X = e.X - 2 * SmudgeWidth
End If
If e.X < 2 Then
ThePts6(1).X = e.X
Else
ThePts6(1).X = e.X - SmudgeWidth
End If
If e.X > Work.Width - 2 * SmudgeWidth Then
ThePts3(1).X = e.X
Else
ThePts3(1).X = e.X + 2 * SmudgeWidth
End If
If e.X > Work.Width - SmudgeWidth Then
ThePts9(1).X = e.X
Else
ThePts9(1).X = e.X + SmudgeWidth
End If
ThePts1(1).Y = e.Y
ThePts2(1).Y = e.Y
ThePts3(1).Y = e.Y
ThePts6(1).Y = e.Y
ThePts9(1).Y = e.Y
If e.Y < 4 Then
ThePts4(1).Y = e.Y
Else
ThePts4(1).Y = e.Y - 2 * SmudgeWidth
End If
If e.Y < 2 Then
ThePts7(1).Y = e.Y
Else
ThePts7(1).Y = e.Y - SmudgeWidth
End If
If e.Y > Work.Height - 2 * SmudgeWidth Then
ThePts5(1).Y = e.Y
Else
ThePts5(1).Y = e.Y + 2 * SmudgeWidth
End If
If e.Y > Work.Height - 2 * SmudgeWidth Then
ThePts8(1).Y = e.Y
Else
ThePts8(1).Y = e.Y + SmudgeWidth
End If
When we are tracing on a paper we need a crayon, a pencil, a brush ... or a pen. Here we will use a pen, but we need to create it. It is an object with properties, like color and thickness. But because we want more than one color of crayons, we need more than one pen, we need 9. They are created on the following segment of code. If We have done other selections like smudging, erasing or dragging color, we need to assign new values to the color variables, so we use "GetPixel()".
'create 9 pen objects to draw the lines
Dim MyPen1 As New Pen(Color1, SmudgeWidth)
Dim MyPen2 As New Pen(Color2, SmudgeWidth)
Dim MyPen3 As New Pen(Color3, SmudgeWidth)
Dim MyPen4 As New Pen(Color4, SmudgeWidth)
Dim MyPen5 As New Pen(Color5, SmudgeWidth)
Dim MyPen6 As New Pen(Color6, SmudgeWidth)
Dim MyPen7 As New Pen(Color7, SmudgeWidth)
Dim MyPen8 As New Pen(Color8, SmudgeWidth)
Dim MyPen9 As New Pen(Color9, SmudgeWidth)
'Draw last line increments and pick new colors
Dim g As Graphics = Graphics.FromImage(bmx)
If Rb2.Checked = True Then
Color1a = bmx.GetPixel(ThePts1(1).X, ThePts1(1).Y)
Color2a = bmx.GetPixel(ThePts2(1).X, ThePts2(1).Y)
Color3a = bmx.GetPixel(ThePts3(1).X, ThePts3(1).Y)
Color4a = bmx.GetPixel(ThePts4(1).X, ThePts4(1).Y)
Color5a = bmx.GetPixel(ThePts5(1).X, ThePts5(1).Y)
Color6a = bmx.GetPixel(ThePts6(1).X, ThePts6(1).Y)
Color7a = bmx.GetPixel(ThePts7(1).X, ThePts7(1).Y)
Color8a = bmx.GetPixel(ThePts8(1).X, ThePts8(1).Y)
Color9a = bmx.GetPixel(ThePts9(1).X, ThePts9(1).Y)
Else
'Keep or assign new colors for drawing
Color1a = Color1
Color2a = Color2
Color3a = Color3
Color4a = Color4
Color5a = Color5
Color6a = Color6
Color7a = Color7
Color8a = Color8
Color9a = Color9
End If
'How many lines, and which points, depending on configuration
If Rb5.Checked = True Then
If CheckBox1.Checked = True Then
g.DrawLine(MyPen1, ThePts1(0).X, ThePts1(0).Y, ThePts1(1).X, ThePts1(1).Y)
g.DrawLine(MyPen2, ThePts2(0).X, ThePts2(0).Y, ThePts2(1).X, ThePts2(1).Y)
g.DrawLine(MyPen3, ThePts3(0).X, ThePts3(0).Y, ThePts3(1).X, ThePts3(1).Y)
g.DrawLine(MyPen4, ThePts4(0).X, ThePts4(0).Y, ThePts4(1).X, ThePts4(1).Y)
g.DrawLine(MyPen5, ThePts5(0).X, ThePts5(0).Y, ThePts5(1).X, ThePts5(1).Y)
g.DrawLine(MyPen6, ThePts6(0).X, ThePts6(0).Y, ThePts6(1).X, ThePts6(1).Y)
g.DrawLine(MyPen7, ThePts7(0).X, ThePts7(0).Y, ThePts7(1).X, ThePts7(1).Y)
g.DrawLine(MyPen8, ThePts8(0).X, ThePts8(0).Y, ThePts8(1).X, ThePts8(1).Y)
g.DrawLine(MyPen9, ThePts9(0).X, ThePts9(0).Y, ThePts9(1).X, ThePts9(1).Y)
ElseIf CheckBox2.Checked = True Then
g.DrawLine(MyPen1, ThePts1(0).X, ThePts1(0).Y, ThePts1(1).X, ThePts1(1).Y)
g.DrawLine(MyPen4, ThePts4(0).X, ThePts4(0).Y, ThePts4(1).X, ThePts4(1).Y)
g.DrawLine(MyPen5, ThePts5(0).X, ThePts5(0).Y, ThePts5(1).X, ThePts5(1).Y)
g.DrawLine(MyPen7, ThePts7(0).X, ThePts7(0).Y, ThePts7(1).X, ThePts7(1).Y)
g.DrawLine(MyPen8, ThePts8(0).X, ThePts8(0).Y, ThePts8(1).X, ThePts8(1).Y)
ElseIf CheckBox3.Checked = True Then
g.DrawLine(MyPen1, ThePts1(0).X, ThePts1(0).Y, ThePts1(1).X, ThePts1(1).Y)
g.DrawLine(MyPen2, ThePts2(0).X, ThePts2(0).Y, ThePts2(1).X, ThePts2(1).Y)
g.DrawLine(MyPen3, ThePts3(0).X, ThePts3(0).Y, ThePts3(1).X, ThePts3(1).Y)
g.DrawLine(MyPen6, ThePts6(0).X, ThePts6(0).Y, ThePts6(1).X, ThePts6(1).Y)
g.DrawLine(MyPen9, ThePts9(0).X, ThePts9(0).Y, ThePts9(1).X, ThePts9(1).Y)
End If
'Erase painting on white
ElseIf Rb4.Checked = True Then
g.DrawLine(ErasePen, ThePts1(0).X, ThePts1(0).Y, ThePts1(1).X, ThePts1(1).Y)
g.DrawLine(ErasePen, ThePts2(0).X, ThePts2(0).Y, ThePts2(1).X, ThePts2(1).Y)
g.DrawLine(ErasePen, ThePts3(0).X, ThePts3(0).Y, ThePts3(1).X, ThePts3(1).Y)
g.DrawLine(ErasePen, ThePts4(0).X, ThePts4(0).Y, ThePts4(1).X, ThePts4(1).Y)
g.DrawLine(ErasePen, ThePts5(0).X, ThePts5(0).Y, ThePts5(1).X, ThePts5(1).Y)
g.DrawLine(ErasePen, ThePts6(0).X, ThePts6(0).Y, ThePts6(1).X, ThePts6(1).Y)
g.DrawLine(ErasePen, ThePts7(0).X, ThePts7(0).Y, ThePts7(1).X, ThePts7(1).Y)
g.DrawLine(ErasePen, ThePts8(0).X, ThePts8(0).Y, ThePts8(1).X, ThePts8(1).Y)
g.DrawLine(ErasePen, ThePts9(0).X, ThePts9(0).Y, ThePts9(1).X, ThePts9(1).Y)
Else
g.DrawLine(MyPen1, ThePts1(0).X, ThePts1(0).Y, ThePts1(1).X, ThePts1(1).Y)
g.DrawLine(MyPen2, ThePts2(0).X, ThePts2(0).Y, ThePts2(1).X, ThePts2(1).Y)
g.DrawLine(MyPen3, ThePts3(0).X, ThePts3(0).Y, ThePts3(1).X, ThePts3(1).Y)
g.DrawLine(MyPen4, ThePts4(0).X, ThePts4(0).Y, ThePts4(1).X, ThePts4(1).Y)
g.DrawLine(MyPen5, ThePts5(0).X, ThePts5(0).Y, ThePts5(1).X, ThePts5(1).Y)
g.DrawLine(MyPen6, ThePts6(0).X, ThePts6(0).Y, ThePts6(1).X, ThePts6(1).Y)
g.DrawLine(MyPen7, ThePts7(0).X, ThePts7(0).Y, ThePts7(1).X, ThePts7(1).Y)
g.DrawLine(MyPen8, ThePts8(0).X, ThePts8(0).Y, ThePts8(1).X, ThePts8(1).Y)
g.DrawLine(MyPen9, ThePts9(0).X, ThePts9(0).Y, ThePts9(1).X, ThePts9(1).Y)
End If
'Make Changes permanent
Work.Image = bmx.Clone
'Make 2nd points first points, transfer to prepare for next mousemove
ThePts1(0) = ThePts1(1)
ThePts2(0) = ThePts2(1)
ThePts3(0) = ThePts3(1)
ThePts4(0) = ThePts4(1)
ThePts5(0) = ThePts5(1)
ThePts6(0) = ThePts6(1)
ThePts7(0) = ThePts7(1)
ThePts8(0) = ThePts8(1)
ThePts9(0) = ThePts9(1)
Color1 = Color1a
Color2 = Color2a
Color3 = Color3a
Color4 = Color4a
Color5 = Color5a
Color6 = Color6a
Color7 = Color7a
Color8 = Color8a
Color9 = Color9a
Catch
' If we go outside the edge of the image we are manipulating pixels that don't exist , so ignore
End Try
End If
End Sub
#End Region
#End Region
Visual part and feedback: Here we see our settings, the small cross becomes a line, the assigned colors are shown on a set of small labels arranged there. Some of them become invisible. And the thickness of the trace is shown on the combobox window.
#Region "Visual Settings"
Private Sub CheckBox1_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox1.CheckedChanged
If CheckBox1.Checked = True Then
CheckBox2.Checked = False
CheckBox3.Checked = False
Label1.Visible = True
Label2.Visible = True
Label3.Visible = True
Label4.Visible = True
Label5.Visible = True
Label6.Visible = True
Label7.Visible = True
Label8.Visible = True
Label9.Visible = True
End If
End Sub
Private Sub CheckBox2_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox2.CheckedChanged
If CheckBox2.Checked = True Then
CheckBox1.Checked = False
CheckBox3.Checked = False
Label1.Visible = True
Label2.Visible = False
Label3.Visible = False
Label4.Visible = True
Label5.Visible = True
Label6.Visible = False
Label7.Visible = True
Label8.Visible = True
Label9.Visible = False
End If
End Sub
Private Sub CheckBox3_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox3.CheckedChanged
If CheckBox3.Checked = True Then
CheckBox1.Checked = False
CheckBox2.Checked = False
Label1.Visible = True
Label2.Visible = True
Label3.Visible = True
Label4.Visible = False
Label5.Visible = False
Label6.Visible = True
Label7.Visible = False
Label8.Visible = False
Label9.Visible = True
End If
End Sub
Private Sub StreakThickness(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tbThickness.Scroll
Label11.Text = tbThickness.Value.ToString & " Pixels"
End Sub
#End Region
Adjust or change settings: As we have seen, we have some choices, set on the controls on the form. We can change the thickness of the trace and we can manually assign colors to the different lines by clicking on the color picker image. The other choices were already
explained.
#Region "Change Settings"
Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
ComboBox1.SelectedIndexChanged
Select Case ComboBox1.SelectedIndex
Case 0
SmudgeWidth = 1
Case 1
SmudgeWidth = 2
Case 2
SmudgeWidth = 3
Case 3
SmudgeWidth = 4
Case 4
SmudgeWidth = 5
End Select
End Sub
Next we use "Getpixel()" to get the colors from the colorpicker and assign the background color of our guide labels.
Private Sub pbPicker_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles pbPicker.MouseClick
Static times As Integer = 0
Try
Dim bmx1 As Bitmap
bmx1 = New Bitmap(pbPicker.Image)
Select Case times Mod 9
Case 0
Color1a = bmx1.GetPixel(e.X, e.Y)
Case 1
Color2a = bmx1.GetPixel(e.X, e.Y)
Case 2
Color3a = bmx1.GetPixel(e.X, e.Y)
Case 3
Color4a = bmx1.GetPixel(e.X, e.Y)
Case 4
Color5a = bmx1.GetPixel(e.X, e.Y)
Case 5
Color6a = bmx1.GetPixel(e.X, e.Y)
Case 6
Color7a = bmx1.GetPixel(e.X, e.Y)
Case 7
Color8a = bmx1.GetPixel(e.X, e.Y)
Case 8
Color9a = bmx1.GetPixel(e.X, e.Y)
End Select
Label1.BackColor = Color1a
Label2.BackColor = Color2a
Label3.BackColor = Color3a
Label4.BackColor = Color4a
Label5.BackColor = Color5a
Label6.BackColor = Color6a
Label7.BackColor = Color7a
Label8.BackColor = Color8a
Label9.BackColor = Color9a
times += 1
Catch
End Try
End Sub
#End Region
Apply watermark image. This is a different operation here, we won't trace a line, we will draw an image on top of the other image. This image (thumbnail) is selected from a chart besides the color picker. It can be enlarged and it's transparency set. so you could apply it to the other image with a couple of clicks. It could be opaque (Not Translucent) or complete transparent(invisible) and all the gamma in between. This is set with the trackbar controls on top of the screen and done with a graphics object and a bitmap, so it becomes permanent part of the image.
#Region "Stamp WaterMark"
Private Sub Transparent(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tbTransparency.Scroll
Label13.Text = tbThickness.Value.ToString
End Sub
Function generateThumbnail(ByVal bmp As Bitmap, ByVal newWidth As Integer) As Image
Dim newHeight As Integer
newHeight = (newWidth / bmp.Width) * bmp.Height
resized = New Bitmap(newWidth, newHeight)
Dim gx As Graphics = Graphics.FromImage(resized)
gx.SmoothingMode = SmoothingMode.HighQuality
gx.CompositingQuality = CompositingQuality.HighQuality
gx.InterpolationMode = InterpolationMode.High
gx.DrawImage(bmp, New Rectangle(0, 0, resized.Width, resized.Height), 0, 0, bmp.Width, bmp.Height, GraphicsUnit.Pixel)
gx.Dispose()
Return resized
' bmp.Dispose()
End Function
' Copy the watermark image over the result image.
Private Sub DrawWatermark(ByVal watermark_bm As Bitmap, _
ByVal result_bm As Bitmap, ByVal x As Integer, ByVal y As Integer)
Dim ALPHA As Byte = tbTransparency.Value '255 '150
' Set the watermark's pixels' Alpha components.
Dim clr As Color
For py As Integer = 0 To watermark_bm.Height - 1
For px As Integer = 0 To watermark_bm.Width - 1
clr = watermark_bm.GetPixel(px, py)
watermark_bm.SetPixel(px, py, Color.FromArgb(ALPHA, clr.R, clr.G, clr.B)/>)
Next px
Next py
' watermark_bm.MakeTransparent(watermark_bm.GetPixel(2, 2))
' Copy onto the result image.
Dim gr As Graphics = Graphics.FromImage(result_bm)
gr.DrawImage(watermark_bm, x, y)
End Sub
The following block gives us a chance to see the parameter "Sender" that accompanies the "e" parameter on most event handler routines.
This variable contains the object that is producing the event, and simplifies a lot the code. One routine will supply for a lot of similar routines that we had if we were not using it. You see the "handles" clause below. If I click button1 my routine "knows" that button1 was clicked. If you have two buttons on the routine you can select two different branches of code depending on what button was clicked.
Moreover, you can program different kinds of events in the same routine like this:
Public Sub MySub(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Me.Resize, Button3.click, Combobox1.SelecteditemChanged, HscrllBar1.ValueChanged
Check below.
Private Sub P1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles _
P1.Click, P2.Click, P3.Click, P4.Click, P5.Click, P6.Click, P7.Click, P8.Click, _
P9.Click, P10.Click, P11.Click, P12.Click, P13.Click, P14.Click, P15.Click, P16.Click
If Rb3.Checked = False Then Exit Sub
Dim imgx As Image
imgx = generateThumbnail(sender.image, tbThickness.Value)
DrawWatermark(imgx, Work.Image, ThePts1(0).X, ThePts1(0).Y)
Refresh()
End Sub
#End Region
Other operations from the menu: rotating and saving the image. The code is shown below. These and other methods allow to flip and rotate the image.
#Region "Rotate"
Private Sub FlipRotate(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FlipHorizontal.Click, FlipVertical.Click,
Rotate90R.Click, Rotate90L.Click
' resulting bitmap.
Dim bmrotate As New Bitmap(Work.Image)
If sender Is FlipHorizontal Then bmrotate.RotateFlip(RotateFlipType.RotateNoneFlipX)
If sender Is FlipVertical Then bmrotate.RotateFlip(RotateFlipType.RotateNoneFlipY)
If sender Is Rotate90R Then bmrotate.RotateFlip(RotateFlipType.Rotate90FlipNone)
If sender Is Rotate90L Then bmrotate.RotateFlip(RotateFlipType.Rotate270FlipNone)
Work.Image = bmrotate
End Sub
#End Region
I opted for saving any file without the "SaveFile" dialog, generating a name and checking the program directory for a file using that name; if the name is in use we generate the next name in sequence and check again until we find one that is available and use that name for our file. This routine will count to 1000, but it tells us when we have more than 900 files, in case we get crazy clicking the save button and we have too many files that we don't need.
#Region "Save Drawing"
Private Sub ToolStripMenuItem1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripMenuItem1.Click
Dim i As Integer
Dim str As String
For i = 1 To 1000
If i < 10 Then str = "Drawing_00" & i.ToString & ".jpg"
If i > 9 And i < 100 Then str = "Picture_0" & i.ToString & ".jpg"
If i > 99 Then str = "Picture_" & i.ToString & ".jpg"
If i > 900 Then MsgBox("You Have Over 900 Pictures, Please Check And Delete Unnecessary Ones")
If Not System.IO.File.Exists(str) Then
Try
Work.Image.Save(str, System.Drawing.Imaging.ImageFormat.Jpeg) 'Whole
Catch Ex As Exception
MsgBox("Could Not Write To Location")
End Try
Exit For
End If
Next
End Sub
#End Region
End Class
Thank you for reading. Please see the enclosed project.
cheers,
ricardosms.
Attached File(s)
-
WetPaint.zip (115.74K)
Number of downloads: 424





MultiQuote



|