title: Replace Bitmap.GetPixel usage in algorithm for LockBits
body: <p>I have this function that creates a region from a <strong>Bitmap</strong>:</p>
  
  <pre><code>Public Shared Function GetRegion(ByVal sender As Bitmap, ByVal transperancyKey As Color, ByVal tolerance As Integer) As Region
  
      ' Stores all the rectangles for the region.
      Using path As New GraphicsPath()
  
          ' Scan the image
          For x As Integer = 0 To (sender.Width - 1)
              For y As Integer = 0 To (sender.Height - 1)
                  If Not ColorsMatch(sender.GetPixel(x, y), transperancyKey, tolerance) Then
                      path.AddRectangle(New Rectangle(x, y, 1, 1))
                  End If
              Next
          Next
  
          Return New Region(path)
      End Using
  
  End Function
  
  Public Shared Function ColorsMatch(ByVal color1 As Color, ByVal color2 As Color, ByVal tolerance As Integer) As Boolean
      If (tolerance &lt; 0) Then
          tolerance = 0
      End If
  
      Return Math.Abs(color1.R - color2.R) &lt;= tolerance AndAlso
             Math.Abs(color1.G - color2.G) &lt;= tolerance AndAlso
             Math.Abs(color1.B - color2.B) &lt;= tolerance
  End Function
  </code></pre>
  
  <p>I would like to improve performance using <code>Bitmap.LockBits</code> instead of <code>Bitmap.GetPixel</code>.</p>
  
  <p>What I have by the moment is this incomplete code below. I'm a little bit confused trying to iterate the pixels/colors in the same (efficient)way that the original function does.</p>
  
  <pre><code>Public Shared Function GetRegion(ByVal sender As Bitmap, ByVal transperancyKey As Color, ByVal tolerance As Integer) As Region
  
      ' Stores all the rectangles for the region.
      Using path As New GraphicsPath()
  
          ' Lock the bitmap's bits.  
          Dim rect As New Rectangle(0, 0, sender.Width, sender.Height)
          Dim bmpData As BitmapData = sender.LockBits(rect, ImageLockMode.ReadWrite, sender.PixelFormat)
  
          ' Get the address of the first line.
          Dim ptr As IntPtr = bmpData.Scan0
  
          ' Declare an array to hold the bytes of the bitmap.
          ' Assume PixelFormat.Format32bppArgb (4 bytes per pixel)
          Dim bytes As Integer = Math.Abs(bmpData.Stride) * sender.Height
          ' Note that I'm not sure whether the above is the proper calculation for that assumption.
          Dim rgbValues(bytes - 1) As Byte
  
          ' Copy the RGB values into the array.
          Marshal.Copy(ptr, rgbValues, 0, bytes)
  
          ' Scan the image
          For x As Integer = 0 To (sender.Width - 1)
              For y As Integer = 0 To (sender.Height - 1)
                  ' ...
              Next
          Next
  
          ' Unlock the bits.
          bmp.UnlockBits(bmpData)
  
          Return New Region(path)
      End Using
  
  End Function
  </code></pre>
  
  <p>How can I do it?.</p>