Home
Search
 
What's New
Index
Books
Links
Q & A
Newsletter
Banners
 
Feedback
Tip Jar
 
C# Helper...
 
XML RSS Feed
Follow VBHelper on Twitter
 
 
 
MSDN Visual Basic Community
 
 
 
 
 
TitleUse Microsoft's .NET Framework parallel extensions to apply an embossing filter to an image very quickly in Visual Basic 2008
DescriptionThis example shows how to use Microsoft's .NET Framework parallel extensions to apply an embossing filter to an image very quickly in Visual Basic 2008.
Keywordsparallel, multi-threading, threading, BitmapBytesRGB24, LockBits, UnlockBits, image processing, filter image, emboss, embossing filter, VB.NET
CategoriesGraphics, Algorithms, VB.NET, Software Engineering
 
The BitmapBytesRGB24 class uses the Bitmap object's LockBits method to get an array of pixel values. This program uses that class to very quickly apply an embossing filter to an image. For details about the BitmapBytesRGB24 class, see Manipulate image pixels very quickly using LockBits wrapped in a class in VB .NET. For information about using that class to apply an embossing filter, see Use the BitmapBytesRGB24 class to apply an embossing filter to an image very quickly in Visual Basic 2005.

This program uses Visual Studio parallel extensions to allow you to use multiple CPUs while applying the filter. If you have a dual-core system, that speeds up the process considerably.

The DoFilterLockBitsParallel subroutine starts the process. It makes two BitmapBytesRGB24 objects and locks their bits. It fills the m_X0 and m_X1 arrays to give the starting and ending X coordinates for the parallel tasks that the program will run. Each task applies the filter to the image's vertical strip between those coordinates.

The code then uses Parallel.For to launch several copies of the DoFilterStrip subroutine in parallel. When those calls have finished, the program unlocks the images' bits to apply the changes to the output bitmap.

 
' Apply the filter in parallel.
Private Const NUM_TASKS As Integer = 10
Private m_X0(NUM_TASKS - 1) As Integer
Private m_X1(NUM_TASKS - 1) As Integer
Private m_Height As Integer
Private m_Bm1Bytes As BitmapBytesRGB24
Private m_Bm2Bytes As BitmapBytesRGB24

Private Sub DoFilterLockBitsParallel()
    ' Get the bitmaps.
    Dim bm1 As Bitmap = picOld.Image
    Dim bm2 As Bitmap = picNew.Image

    ' Make BitmapBytesRGB24 objects for the bitmaps.
    m_Bm1Bytes = New BitmapBytesRGB24(bm1)
    m_Bm2Bytes = New BitmapBytesRGB24(bm2)

    ' Lock the bitmaps' bytes.
    m_Bm1Bytes.LockBitmap()
    m_Bm2Bytes.LockBitmap()

    ' Calculate the start and end X values for the strips.
    Dim wid As Integer = bm1.Width \ NUM_TASKS
    Dim x0 As Integer = 1
    For task_num As Integer = 0 To NUM_TASKS - 1
        m_X0(task_num) = x0
        m_X1(task_num) = x0 + wid - 1
        x0 += wid
    Next task_num
    m_X1(NUM_TASKS - 1) = bm1.Width - 2
    m_Height = bm1.Height

    ' Process the image in strips.
#Const DO_PARALLEL = True 'False
#If DO_PARALLEL Then
    Parallel.For(0, NUM_TASKS, AddressOf DoFilterStrip)
#Else
    For task_num As Integer = 0 To NUM_TASKS - 1
        DoFilterStrip(task_num)
    Next task_num
#End If

    ' Unlock the bitmaps' bytes.
    m_Bm1Bytes.UnlockBitmap()
    m_Bm2Bytes.UnlockBitmap()
End Sub
 
Parallel call number task_num to subroutine DoFilterStrip applies the filter to the pixels in a vertical strip between m_X0(task_num) <= X <= m_X1(task_num).
 
' Process pixels for a strip.
Private Sub DoFilterStrip(ByVal task_num As Integer)
    Dim new_r As Byte = 0
    Dim new_g As Byte = 0
    Dim new_b As Byte = 0
    For x As Integer = m_X0(task_num) To m_X1(task_num)
        For y As Integer = 1 To m_Height - 2
            Dim r As Integer = 0
            Dim g As Integer = 0
            Dim b As Integer = 0
            For dx As Integer = 0 To 2
                For dy As Integer = 0 To 2
                    m_Bm1Bytes.GetPixel(x + dx - 1, y + dy _
                        - 1, new_r, new_g, new_b)
                    r += new_r * m_Filter(dx, dy)
                    g += new_g * m_Filter(dx, dy)
                    b += new_b * m_Filter(dx, dy)
                Next dy
            Next dx

            r = CInt(127 + r / m_Weight)
            g = CInt(127 + g / m_Weight)
            b = CInt(127 + b / m_Weight)
            If r < 0 Then r = 0
            If g < 0 Then g = 0
            If b < 0 Then b = 0
            If r > 255 Then r = 255
            If g > 255 Then g = 255
            If b > 255 Then b = 255
            m_Bm2Bytes.SetPixel(x, y, r, g, b)
        Next y
    Next x
End Sub
 
 
Copyright © 1997-2010 Rocky Mountain Computer Consulting, Inc.   All rights reserved.
  Updated