无法在此while循环中设置正确的值

时间:2013-05-17 08:59:09

标签: .net vb.net colors while-loop

我已将此代码翻译成VB.NET,这是检查图像是否为灰度的功能。

private static unsafe bool IsGrayScale(Image image)
{
    using (var bmp = new Bitmap(image.Width, image.Height, PixelFormat.Format32bppArgb))
    {
        using (var g = Graphics.FromImage(bmp))
        {
            g.DrawImage(image, 0, 0);
        }

        var data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, bmp.PixelFormat);

        var pt = (int*)data.Scan0;
        var res = true;

        for (var i = 0; i < data.Height * data.Width; i++)
        {
            var color = Color.FromArgb(pt[i]);

            if (color.A != 0 && (color.R != color.G || color.G != color.B))
            {
                res = false;
                break;
            }
        }

        bmp.UnlockBits(data);

        return res;
    }
}

C#代码正在运行,但没有做我需要的所以我做了一些修改试图制作一个功能,检查图像是否有某种RGB颜色,但最重要的部分不起作用:

Dim color__1 = Color.FromArgb(pt(i))

例外:

Error   1   Expression is not an array or a method, and cannot have an argument list.   C:\Visual Studio Projects\WindowsApplication9\WindowsApplication9\Form1.vb  21  47  WindowsApplication9

以下是翻译代码:

Imports System.Drawing.Imaging

Public Class Form1

    Private Shared Function ImageHasColor(ByVal image As Image, ByVal R As Int32, ByVal G As Int32, ByVal B As Int32) As Boolean

        Using bmp = New Bitmap(image.Width, image.Height, PixelFormat.Format32bppArgb)

            Using graph = Graphics.FromImage(bmp)
                graph.DrawImage(image, 0, 0)
            End Using

            Dim data = bmp.LockBits(New Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.[ReadOnly], bmp.PixelFormat)

            Dim pt = CType(data.Scan0, Integer)
            MsgBox(pt)
            Dim res As Boolean

            Dim i = 0
            While i < data.Height * data.Width
                Dim color__1 = Color.FromArgb(pt(i))

                If color__1.A <> 0 AndAlso color__1.R = R AndAlso color__1.G = G AndAlso color__1.B = B Then
                    res = True
                    Exit While
                End If

                System.Math.Max(System.Threading.Interlocked.Increment(i), i - 1)
            End While

            bmp.UnlockBits(data)

            Return res
        End Using
    End Function


    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim bmp = New Bitmap("C:\Users\Administrador\Desktop\PrtScr capture_3.jpg")
        MsgBox(ImageHasColor(bmp, 240, 240, 240))
    End Sub

End Class
  

更新:

这些代码仅适用于第一次,如果我多次使用它,我会收到此错误:

尝试读取或写入受保护的内存

1

Private Shared Function ImageHasColor(ByVal image As Image, ByVal R As Int32, ByVal G As Int32, ByVal B As Int32) As Boolean

    Using bmp = New Bitmap(image.Width, image.Height, PixelFormat.Format32bppArgb)

        Using graph = Graphics.FromImage(bmp)
            graph.DrawImage(image, 0, 0)
        End Using
        Dim color__1 As Color
        Dim byt
        Dim data = bmp.LockBits(New Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.[ReadOnly], bmp.PixelFormat)

        Dim pt = CType(data.Scan0, Integer)

        Dim res As Boolean

        For i = 0 To data.Height * data.Width - 1

            color__1 = Color.FromArgb(Marshal.ReadInt32(pt, i * 4))

            If color__1.A <> 0 AndAlso color__1.R = R AndAlso color__1.G = G AndAlso color__1.B = B Then
                res = True
                Exit For
            End If

            'System.Math.Max(System.Threading.Interlocked.Increment(i), i - 1)
        Next

        bmp.UnlockBits(data)

        Return res
    End Using
End Function

2

Private Shared Function ImageHasColor(ByVal image As Image, ByVal R As Int32, ByVal G As Int32, ByVal B As Int32) As Boolean

    Using bmp = New Bitmap(image.Width, image.Height, PixelFormat.Format32bppArgb)

        Using graph = Graphics.FromImage(bmp)
            graph.DrawImage(image, 0, 0)
        End Using
        Dim color__1 As Color
        Dim byt
        Dim data = bmp.LockBits(New Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.[ReadOnly], bmp.PixelFormat)

        Dim pt = CType(data.Scan0, Integer)

        Dim res As Boolean

        Dim i = 0
        While i < data.Height * data.Width


            color__1 = Color.FromArgb(Marshal.ReadInt32(pt, i * 4))

            If color__1.A <> 0 AndAlso color__1.R = R AndAlso color__1.G = G AndAlso color__1.B = B Then
                res = True
                Exit While
            End If

            System.Math.Max(System.Threading.Interlocked.Increment(i), i - 1)
        End While

        bmp.UnlockBits(data)

        Return res
    End Using
End Function
  

更新:

此代码似乎正在运作

Private Shared Function ImageHasColor(ByVal image As Image, ByVal R As Int32, ByVal G As Int32, ByVal B As Int32) As Boolean

    Try
        Using bmp = New Bitmap(image.Width, image.Height, PixelFormat.Format32bppArgb)

            Using graph = Graphics.FromImage(bmp) : graph.DrawImage(image, 0, 0) : End Using

            Dim Pixel_Color As Color

            Dim Ditmap_Data = bmp.LockBits(New Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.[ReadOnly], bmp.PixelFormat)

            Dim pt As IntPtr = CType(Ditmap_Data.Scan0, IntPtr)

            For i = 0 To Ditmap_Data.Height * Ditmap_Data.Width - 1

                Pixel_Color = Color.FromArgb(Marshal.ReadInt32(pt, i * 4))

                If Pixel_Color.A <> 0 AndAlso Pixel_Color.R = R AndAlso Pixel_Color.G = G AndAlso Pixel_Color.B = B Then
                    bmp.UnlockBits(Ditmap_Data)
                    Return True
                End If

            Next

            bmp.UnlockBits(Ditmap_Data)
            Return False

        End Using
    Catch ex As Exception
        MsgBox(ex.Message)
        Return Nothing
    End Try

End Function

2 个答案:

答案 0 :(得分:2)

尝试将pt声明为IntPtr并使用MarshalBitConverter类来读取整数。

答案 1 :(得分:1)

现在你只是逆势而上。为什么这些UnlockBits在循环中?你在原始代码中看到它们吗?立即删除它们。

Private Shared Function HasColor(ByVal image As Image, ByVal toFind As Color) As Boolean

    Using bmp = New Bitmap(image.Width, image.Height, PixelFormat.Format32bppArgb)

        Using graph = Graphics.FromImage(bmp)
            graph.DrawImage(image, 0, 0)
        End Using

        Dim data = bmp.LockBits(New Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.[ReadOnly], bmp.PixelFormat)

        Dim pt = data.Scan0 'Since we can't use a pointer in VB.Net, we'll stick to IntPtr for now
        Dim res As Boolean = False

        For i=0 To data.Height * data.Width - 1
            Dim foundColor as Int32 = Marshal.ReadInt32(pt, i*4)

            If (foundColor and &HFF000000) <> 0 AndAlso ( (foundColor and &H00FFFFFF) = (toFind.ToArgb() and &H00FFFFFF) ) Then
                res = True
                Exit For
            End If

        Next

        bmp.UnlockBits(data)

        Return res
    End Using
End Function


Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    Dim bmp = New Bitmap("C:\Users\Administrador\Desktop\PrtScr capture_3.jpg")
    MsgBox(ImageHasColor(bmp, Color.FromArgb(240, 240, 240)))
End Sub

结束班