|
|
Title | Use Microsoft's .NET Framework parallel extensions to apply an embossing filter to an image very quickly in Visual Basic 2008 |
Description | This 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. |
Keywords | parallel, multi-threading, threading, BitmapBytesRGB24, LockBits, UnlockBits, image processing, filter image, emboss, embossing filter, VB.NET |
Categories | Graphics, 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
|
|
|
|
|
|