Page 1 of 1

WET PAINT Program, Multicolor Streaks, Drag Colors, Smudge, waterMark Rate Topic: -----

#1 ricardosms  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 73
  • View blog
  • Posts: 301
  • Joined: 02-April 10

Posted 20 March 2012 - 02:57 PM

WET PAINT Program, Multicolor Streaks, Drag Colors, Smudge, waterMark

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:


Attached Image




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)



Is This A Good Question/Topic? 3
  • +

Replies To: WET PAINT Program, Multicolor Streaks, Drag Colors, Smudge, waterMark

#2 ricardosms  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 73
  • View blog
  • Posts: 301
  • Joined: 02-April 10

Posted 01 April 2012 - 10:06 AM

Some of you may be intersted on this other tutorial:

http://www.dreaminco...1&#entry1567328

please take a look.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1