This is a greatly simplified version of a graphics processing program I am working on, but is set to show some concepts that were hard for me to grasp and that I had to research and in certain instances figure out by myself.
This program prepares a picture for processing using image attributes and a colormatrix,
Dim TB3 As Single = TrackBar1.Value / 200
Dim cm As ColorMatrix = New ColorMatrix(New Single()() _
{ _
New Single() {TB3, 0, 0, 0.0, 0.0}, _
New Single() {0, TB3, 0, 0.0, 0.0}, _
New Single() {0, 0, TB3, 0.0, 0.0}, _
New Single() {0, 0, 0, 1.0, 0.0}, _
New Single() {0.01, 0.01, 0.01, 0.0, 1.0}})
.
.
.
image_attr.SetColorMatrix(cm)
.
but not convolution filters to find edges (sharp changes on intensity or colors), and then replaces a section of it with a saved portion.
I process it with getpixel and setpixel methods, slow, but less complicated than Lockbits. I am not really excluding anything like the "isvisible" method for regions and paths.
There is a trackbar provided for variations on the colormatrix values; but I didn't include the variations on the color components as were set on my program.
The desktop has 4 picture boxes, one actual size, the others stretched, and one of them a shrunk image(picturebox3).
Picturebox1 has the original image and will show the resulting image, wich can be saved in sequence, sent to clipboard or printed.
Picturebox2 has a reduced view of the original.
Picturebox3 has a thumbnail modified image after aplying the image attributes and
Picturebox4 shows a preview resulting from processing the image on Picturebox3.
Here is a view:

The difference between "preview" and "border" that gives the final resuls is on the comparation of suroundind pixels, so it happens quicklier.
A checkbox allows you to select or not a region to exclude. Yo could also stop the process for larger pictures to view partial results.
OK!, Let's go to the code:
The first thing you do is to load an image to process, create the different images that will be needed and save some attributes of them:
Private Sub OpenToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OpenToolStripMenuItem.Click
Dim f As New OpenFileDialog
Try
With f
.Filter = "Image Files|*.bmp;*.gif;*.jpg;*.png;*.tif"
If .ShowDialog = DialogResult.OK Then
PictureBox1.Image = Image.FromFile(.FileName)
' MessageBox.Show("Pixel format: " & PictureBox1.Image.PixelFormat.ToString())
PictureBox2.Image = Image.FromFile(.FileName)
PictureBox1.Tag = Image.FromFile(.FileName)
W = GetImageWidth(.FileName)
H = GetImageHeight(.FileName)
Ratio = CSng(W / H)
NewWidth = CInt(220 * Ratio)
NewHeight = 220
PictureBox2.Height = 220
PictureBox2.Width = NewWidth
PictureBox3.Height = 220
PictureBox3.Width = NewWidth
PictureBox4.Height = 220
PictureBox4.Width = NewWidth
PictureBox4.Visible = True
JustBefore()
PictureBox4.Image = Preview(ShrinkImage(PictureBox3.Image))
Try
selected_path.Reset()
gr_visible.Dispose()
gr_result.Dispose()
bm_result.Dispose()
Catch
End Try
End If
End With
Catch ex As Exception
MsgBox(ex.ToString)
Finally
If Not f Is Nothing Then
f.Dispose()
f = Nothing
End If
End Try
End Sub
Private Function GetImageHeight(ByRef file As String) As Integer
Using image As System.Drawing.Image = System.Drawing.Image.FromFile(file)
Return image.Height
End Using
End Function
Private Function GetImageWidth(ByRef file As String) As Integer
Using image As System.Drawing.Image = System.Drawing.Image.FromFile(file)
Return image.Width
End Using
End Function
We have set the images on the pictureboxes and saved the dimensions of the original picture for future use.
The subroutine "JustBefore" sets the image attributes according to the colormatrix created and also produces a shunken image for picturebox3 calling the function shrinkimage:
Private Sub JustBefore()
Dim TB3 As Single = TrackBar1.Value / 200
Dim cm As ColorMatrix = New ColorMatrix(New Single()() _
{ _
New Single() {TB3, 0, 0, 0.0, 0.0}, _
New Single() {0, TB3, 0, 0.0, 0.0}, _
New Single() {0, 0, TB3, 0.0, 0.0}, _
New Single() {0, 0, 0, 1.0, 0.0}, _
New Single() {0.01, 0.01, 0.01, 0.0, 1.0}})
Try
Dim rect As Rectangle = Rectangle.Round(PictureBox2.Image.GetBounds(GraphicsUnit.Pixel))
Dim wid As Integer = PictureBox2.Image.Width
Dim hgt As Integer = PictureBox2.Image.Height
Dim img As New Bitmap(wid, hgt)
Dim gr As Graphics = Graphics.FromImage(img)
image_attr.SetColorMatrix(cm) '0
gr.DrawImage(PictureBox2.Image, rect, 0, 0, wid, hgt, GraphicsUnit.Pixel, image_attr)
WorkImg = img
PictureBox3.Image = ShrinkImage(img)
Catch
End Try
PictureBox3.Refresh()
End Sub
Private Function ShrinkImage(ByVal from_pic As Image, Optional ByVal anti_alias As _
Boolean = False) As Image
' Get the source Bitmap.
Dim from_bm As New Bitmap(from_pic)
' Make the destination Bitmap.
Dim wid As Integer = CInt(PictureBox1.Width * 220 / PictureBox1.Height) 'from_pic.Width / 2
Dim hgt As Integer = 220 'from_pic.Height / 2
Dim to_bm As New Bitmap(wid, hgt)
' Copy the image.
Dim gr As Graphics = Graphics.FromImage(to_bm)
If anti_alias Then gr.InterpolationMode = _
Drawing2D.InterpolationMode.HighQualityBilinear
gr.DrawImage(from_bm, 0, 0, wid - 1, hgt - 1)
' Display the result.
' to_pic.Image = to_bm
gr.Dispose()
Return to_bm
End Function
The preview function shows you approximately how the image will come after processing the pixels. This will be on picturebox4
Private Function Preview(ByVal Thumb As Image) As Image
' Dim bm As New Bitmap(PictureBox1.Image)
Dim X As Integer
Dim Y As Integer
Dim Rx, Gx, Bx As Integer
Dim Ry, Gy, By As Integer
Dim Brig1, Brig2 As Integer
Cursor = Cursors.WaitCursor
Try
Dim rect As Rectangle = Rectangle.Round(PictureBox4.Image.GetBounds(GraphicsUnit.Pixel))
Dim pt As New Point(0, 0)
Dim sz As New Size(NewWidth, 220)
Dim rect1 As New Rectangle(pt, sz)
Dim img As New Bitmap(NewWidth, 220)
Dim gr As Graphics = Graphics.FromImage(img)
gr.DrawImage(Thumb, rect1, 0, 0, NewWidth, 220, GraphicsUnit.Pixel)
For X = 0 To img.Width - 2
For Y = 0 To img.Height - 2
Rx = CInt(img.GetPixel(X, Y).R)
Gx = CInt(img.GetPixel(X, Y).G)
Bx = CInt(img.GetPixel(X, Y).B)/>
Brig1 = (Rx + Gx + Bx)
Ry = CInt(img.GetPixel(X + 1, Y).R)
Gy = CInt(img.GetPixel(X + 1, Y).G)
By = CInt(img.GetPixel(X + 1, Y).B)/>
Brig2 = (Ry + Gy + By)
If Math.Abs(2 * (Brig1 - Brig2)) > 20 Then
img.SetPixel(X, Y, Color.Black)
Else
img.SetPixel(X, Y, Color.White)
End If
Next Y
' Application.DoEvents()
Progress.Value = CInt((100 * X) / img.Width)
Next X
Progress.Value = 0
Progress.Refresh()
Cursor = Cursors.Default
Return img
Catch ex As Exception
Cursor = Cursors.Default
Progress.Value = 0
Progress.Refresh()
Return Thumb
End Try
End Function
You casn process the image and gt the results similar to the preview, but if you check the "Exclude Region" checkbox, you can click and drag on picturebox1 to create a graphics path and an enclosed region that will be saved when the mouseup event happens. Here are the MouseDown, MouseMove and MouseUp Handlers:
Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
selected_path.Reset()
If CheckBox1.Checked = True Then
' Erase any previous drawing.
' Save the starting point.
m_MaxPoint = 0
ReDim m_Points(m_MaxPoint)
m_Points(m_MaxPoint).X = e.X
m_Points(m_MaxPoint).Y = e.Y
End If
End Sub
Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
If CheckBox1.Checked = True And (e.Button = MouseButtons.Left) Then
' Do nothing if we're not selecting a region.
If m_Points Is Nothing Then Exit Sub
' Save the new point.
m_MaxPoint += 1
ReDim Preserve m_Points(m_MaxPoint)
m_Points(m_MaxPoint).X = e.X
m_Points(m_MaxPoint).Y = e.Y
' Draw the latest line.
Dim gr As Graphics = PictureBox1.CreateGraphics
'gr.DrawLine(Pens.Yellow, _
gr.DrawLine(Pens.White, _
m_Points(m_MaxPoint).X, _
m_Points(m_MaxPoint).Y, _
m_Points(m_MaxPoint - 1).X, _
m_Points(m_MaxPoint - 1).Y)
End If
End Sub
Private Sub PictureBox1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseUp
If CheckBox1.Checked = True Then
' Do nothing if we're not selecting a region.
If m_Points Is Nothing Then Exit Sub
' Close the region.
If (m_Points(0).X <> m_Points(m_MaxPoint).X) Or _
(m_Points(0).Y <> m_Points(m_MaxPoint).Y) _
Then
' Save the new point.
m_MaxPoint += 1
ReDim Preserve m_Points(m_MaxPoint)
m_Points(m_MaxPoint).X = m_Points(0).X
m_Points(m_MaxPoint).Y = m_Points(0).Y
End If
' Make the points into a Path.
selected_path.AddLines(m_Points)
' Make the drawing permanent.
Dim bm_visible As New Bitmap(PictureBox1.Image.Width, PictureBox1.Image.Height)
'bm_visible = DirectCast(PictureBox1.Image.Clone, Bitmap)
bm_visible = DirectCast(PictureBox1.Image, Bitmap)
Try
gr_visible = Graphics.FromImage(bm_visible)
gr_visible.DrawPath(Pens.White, selected_path)
PictureBox1.Image = bm_visible
' Copy the picture onto picResult,
' restricting it to the selected region.
bm_result = DirectCast(PictureBox1.Image.Clone, Bitmap)
gr_result = Graphics.FromImage(bm_result)
gr_result.SetClip(selected_path, CombineMode.Exclude)
' We're no longer selecting a region.
m_Points = Nothing
GC.Collect()
Catch
MessageBox.Show("Can't Exclude Section: Pixel format: " & bm_visible.PixelFormat.ToString())
m_Points = Nothing
CheckBox1.Checked = False
Exit Sub
End Try
End If
End Sub
When you press "Process" , the image will be processed and then the saved region pasted on top of the resulting image.
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Border()
If CheckBox1.Checked = True Then
' Create parallelogram for drawing image.
Dim ulCorner As New Point(0, 0)
Dim urCorner As New Point(PictureBox1.Width, 0)
Dim llCorner As New Point(0, PictureBox1.Height)
Dim destPara As Point() = {ulCorner, urCorner, llCorner}
' Create rectangle for source image.
Dim srcRect As New Rectangle(0, 0, PictureBox1.Width, PictureBox1.Height)
Dim units As GraphicsUnit = GraphicsUnit.Pixel
Try
' Draw image to screen.
gr_result.DrawImage(PictureBox1.Image, destPara, srcRect, units)
PictureBox1.Image = bm_result
Catch
If bm_result IsNot Nothing Then bm_result.Dispose()
End Try
End If
GC.Collect()
End Sub

The attachment contains the code, that also include the clipboard,save and print routines.
The save routine is a two part one, one for setting the name and the other to save the file:
Private Sub SaveToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SaveToolStripMenuItem.Click
Dim i As Integer
Dim str As String
For i = 1 To 1000
If i < 10 Then str = "Picture_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 Unnecesary Ones")
If Not System.IO.File.Exists(str) Then
Try
PictureBox1.Image.Save(str, System.Drawing.Imaging.ImageFormat.Jpeg) 'Cropped
'PictureBox1.Image.Save(str, System.Drawing.Imaging.ImageFormat.Png)
Catch Ex As Exception
MsgBox("Could Not Write To Location")
End Try
Exit For
End If
Next
End Sub
Private Sub save()
Dim i As Integer
Dim str As String
For i = 1 To 1000
If i < 10 Then str = "Picture_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 Unnecesary Ones")
If Not System.IO.File.Exists(str) Then
Try
PictureBox1.Image.Save(str, System.Drawing.Imaging.ImageFormat.Jpeg) 'Cropped
'PictureBox1.Image.Save(str, System.Drawing.Imaging.ImageFormat.Png)
Catch Ex As Exception
MsgBox("Could Not Write To Location")
End Try
Exit For
End If
Next
End Sub
Please comment.
Thank you
ricardosms
Exclude image Section At Processing.zip (254.31K)
Number of downloads: 419





MultiQuote






|