【问题标题】:Using LockBits to determine pixel colors (slow)使用 LockBits 确定像素颜色(慢)
【发布时间】:2015-01-31 22:26:53
【问题描述】:

我正在尝试使用 Lockbits 来确定图像中每个像素的颜色。特别是黑色与白色与其他。我最初是用 GetPixel 写的,但它太慢了;但是,使用 Lockbits 也同样慢。它在几秒钟内飞过前 200 个像素,然后减速得非常厉害(大约 1 个像素/秒)。是否存在实施错误、疏忽或更好的解决方案?

    Dim bmp As Bitmap = New Bitmap("path") 
    Dim rect As New Rectangle(0, 0, bmp.Width, bmp.Height)
    Dim bmpData As System.Drawing.Imaging.BitmapData = bmp.LockBits _
            (rect, Drawing.Imaging.ImageLockMode.ReadWrite, _
            Imaging.PixelFormat.Format24bppRgb)
    Dim ptr As IntPtr = bmpData.Scan0
    Dim bytes As Integer = Math.Abs(bmpData.Stride) * bmp.Height
    Dim rgbValues(bytes - 1) As Byte
    System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes)
    pbStatus.Maximum = bmp.Width * bmp.Height
    ' Retrieve RGB values
    Dim RedValue As Int32
    Dim GreenValue As Int32
    Dim BlueValue As Int32
    Dim l As Integer = 0        
    Dim progress As Integer = 0          
    For x = 0 To bmp.Width - 1 
        For y = 0 To bmp.Height - 1
            Application.DoEvents()
            l = ((bmp.Width * 3 * y) + (x * 3))
            RedValue = rgbValues(l)
            GreenValue = rgbValues(l + 1)
            BlueValue = rgbValues(l + 2)
            If RedValue & GreenValue & BlueValue = "000" Then
                txtTX.Text = txtTX.Text + "Black, "
            ElseIf RedValue & GreenValue & BlueValue = "255255255" Then
                txtTX.Text = txtTX.Text + "White, "
            Else
                txtTX.Text = txtTX.Text + "Neither, "
            End If
            progress = progress + 1
            lblProgress.text = progress
        Next
    Next
    bmp.UnlockBits(bmpData)

【问题讨论】:

  • 删除代码的日志部分(If-Statement)后,速度明显加快。寻找更快的方法来记录数据。
  • 1) 使用 StringBuilder 来表示文本,2) 只做 DoEvents/lblProgress.text = 偶尔一次,说每扫描线一次。

标签: vb.net performance image-processing


【解决方案1】:

您过于频繁地调用 Application.DoEvents,如果您需要更新 UI 线程上的控件,请执行以下操作:

Dim bmp As Bitmap = New Bitmap("path") 
Dim rect As New Rectangle(0, 0, bmp.Width, bmp.Height)
Dim bmpData As System.Drawing.Imaging.BitmapData = bmp.LockBits _
        (rect, Drawing.Imaging.ImageLockMode.ReadWrite, _
        Imaging.PixelFormat.Format24bppRgb)
Dim ptr As IntPtr = bmpData.Scan0
Dim bytes As Integer = Math.Abs(bmpData.Stride) * bmp.Height
Dim rgbValues(bytes - 1) As Byte
System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes)
pbStatus.Maximum = bmp.Width * bmp.Height
' Retrieve RGB values
Dim RedValue As Int32
Dim GreenValue As Int32
Dim BlueValue As Int32
Dim l As Integer = 0        
Dim progress As Integer = 0          
DIM BreatheUI as integer = 0

For x = 0 To bmp.Width - 1 
    For y = 0 To bmp.Height - 1

        ' Update the UI every 500 cycles
        BreatheUI += 1 
        IF BreatheUI = 500 Then Application.DoEvents(): BreatheUI = 0

        l = ((bmp.Width * 3 * y) + (x * 3))
        RedValue = rgbValues(l)
        GreenValue = rgbValues(l + 1)
        BlueValue = rgbValues(l + 2)
        If RedValue & GreenValue & BlueValue = "000" Then
            txtTX.Text = txtTX.Text + "Black, "
        ElseIf RedValue & GreenValue & BlueValue = "255255255" Then
            txtTX.Text = txtTX.Text + "White, "
        Else
            txtTX.Text = txtTX.Text + "Neither, "
        End If
        progress = progress + 1
        lblProgress.text = progress
    Next
Next
bmp.UnlockBits(bmpData)

【讨论】:

    猜你喜欢
    • 2016-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-12
    • 2021-09-05
    • 1970-01-01
    • 2012-04-24
    • 1970-01-01
    相关资源
    最近更新 更多