本文介绍了替换LockBits算法中的Bitmap.GetPixel用法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我具有从位图创建区域的功能:

I have this function that creates a region from a Bitmap:

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 < 0) Then
        tolerance = 0
    End If

    Return Math.Abs(color1.R - color2.R) <= tolerance AndAlso
           Math.Abs(color1.G - color2.G) <= tolerance AndAlso
           Math.Abs(color1.B - color2.B) <= tolerance
End Function

我想使用 Bitmap.LockBits 而不是 Bitmap.GetPixel 来提高性能.

I would like to improve performance using Bitmap.LockBits instead of Bitmap.GetPixel.

目前,我所拥有的是下面这段不完整的代码.尝试以与原始函数相同的方式(有效)来迭代像素/颜色,我有些困惑.

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.

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

我该怎么办?.

推荐答案

类似的事情应该可以解决.我一次只锁定一个像素行,以避免占用大量具有大位图的内存,这使得逻辑易于理解.

Something like this should do the trick. I only lock one pixel row at a time to avoid using to much memory with large bitmaps and it makes the logic easy to follow.

Public Shared Function GetRegion(ByVal bm As Bitmap, ByVal transperancyKey As Color, ByVal tolerance As Integer) As Region
    Using path As New GraphicsPath()
        Dim rect As New Rectangle(0, 0, bm.Width, 1)    ' one row high
        Dim pixelData As Int32() = New Int32(0 To bm.Width - 1) {}
        For row As Integer = 0 To (bm.Height - 1)
            ' get the bitmap data as 32bppArgb so that we can read Int32 values
            ' this does not need to match the bm.PixelFormat
            Dim bmData As BitmapData = bm.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb)
            ' copy the pixel data for this row
            Marshal.Copy(bmData.Scan0, pixelData, 0, pixelData.Length)
            bm.UnlockBits(bmData)
            For col As Integer = 0 To (bm.Width - 1)
                Dim px As Color = Color.FromArgb(pixelData(col))
                ' do something with this pixel color
            Next col
            rect.Offset(0, 1)   ' offset to select next row
        Next row

        Return New Region(path)
    End Using
End Function

这篇关于替换LockBits算法中的Bitmap.GetPixel用法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-01 07:02