|
|
Title | Use the BitmapBytesRGB24 class to apply an embossing filter to an image very quickly in Visual Basic 2005 |
Description | This example shows how to use the BitmapBytesRGB24 class to apply an embossing filter to an image very quickly in Visual Basic 2005. |
Keywords | BitmapBytesRGB24, LockBits, UnlockBits, image processing, filter image, emboss, embossing filter, VB.NET |
Categories | Graphics, Algorithms, VB.NET |
|
|
The BitmapBytesRGB24 class uses the Bitmap object's LockBits method to get an array of pixel values. For details, see Manipulate image pixels very quickly using LockBits wrapped in a class in VB .NET.
This version adds the following GetPixel and SetPixel methods to the class. These methods calculate a pixel's location in the array and then gets or sets the pixel's red, green, and blue byte values.
|
|
' Return a pixel's byte values.
Public Sub GetPixel(ByVal x As Integer, ByVal y As Integer, _
ByRef r As Byte, ByRef g As Byte, ByRef b As Byte)
Dim offset As Integer = y * RowSizeBytes + x * _
PixelSizeBytes
b = ImageBytes(offset)
g = ImageBytes(offset + 1)
r = ImageBytes(offset + 2)
End Sub
' Set a pixel's byte values.
Public Sub SetPixel(ByVal x As Integer, ByVal y As Integer, _
ByVal r As Byte, ByVal g As Byte, ByVal b As Byte)
Dim offset As Integer = y * RowSizeBytes + x * _
PixelSizeBytes
ImageBytes(offset) = b
ImageBytes(offset + 1) = g
ImageBytes(offset + 2) = r
End Sub
|
|
When it starts, the program uses the following code to initialize its embossing filter.
|
|
Private m_Filter(,) As Integer
Private m_Weight As Integer
' Initialize the filter.
Private Sub Form1_Load(ByVal sender As System.Object, ByVal _
e As System.EventArgs) Handles MyBase.Load
m_Filter = New Integer(,) { _
{-1, 0, 0}, _
{0, 0, 0}, _
{0, 0, 1}}
m_Weight = 1
End Sub
|
|
To apply the filter, the program considers each pixel in the image (except those on the very edges of the image). It looks at the 3x3 square of pixels surrounding the target pixel and multiplies their red, green, and blue component values by the corresponding filter value. It adds the results and divides by the filter's weight.
For an embossing filter, the program then adds 127 to make pixels with a neutral value become gray.
|
|
' Apply the filter to the image.
Private Sub ApplyFilter()
Me.Cursor = Cursors.WaitCursor
picNew.Image = Nothing
Me.Refresh()
Dim start_time As Date = Now
Dim bm1 As Bitmap = picOld.Image
Dim bm2 As New Bitmap(bm1.Width, bm1.Height)
' Make BitmapBytesRGB24 objects for the bitmaps.
Dim bm1_bytes As New BitmapBytesRGB24(bm1)
Dim bm2_bytes As New BitmapBytesRGB24(bm2)
' Lock the bitmaps' bytes.
bm1_bytes.LockBitmap()
bm2_bytes.LockBitmap()
Dim wid As Integer = bm1.Width
Dim hgt As Integer = bm1.Height
Dim new_r As Byte = 0
Dim new_g As Byte = 0
Dim new_b As Byte = 0
For x As Integer = 1 To wid - 2
For y As Integer = 1 To hgt - 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
bm1_bytes.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
bm2_bytes.SetPixel(x, y, r, g, b)
Next y
Next x
' Unlock the bitmaps.
bm1_bytes.UnlockBitmap()
bm2_bytes.UnlockBitmap()
Dim stop_time As Date = Now
Dim elapsed_time As TimeSpan = stop_time - start_time
Debug.WriteLine(elapsed_time.TotalSeconds.ToString("0.00") _
& " seconds")
picNew.Image = bm2
picNew.Refresh()
Me.Cursor = Cursors.Default
End Sub
|
|
Note that the embossing filter only has two non-zero values and that its weight is 1. You can improve performance slightly by performing the multiplications directly rather than by looping through the filter array. That makes the code a bit less general, however, so it would be harder to modify to apply other filters. For example, try changing the values in the filter array and then setting the weight to the sum of the values in the array to see what happens.
|
|
|
|
|
|