Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
203 views
in Technique[技术] by (71.8m points)

.net - Can't set the correct value in this while loop

I have translated this code to VB.NET which is a function to check if a image is grayscale.

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;
    }
}

The C# code is working but is not doing what I need so I did a little modifications trying to make a function which checks if a image has certain RGB color but the most important part is not working:

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

Exception:

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

Here is the translated code:

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:UsersAdministradorDesktopPrtScr capture_3.jpg")
        MsgBox(ImageHasColor(bmp, 240, 240, 240))
    End Sub

End Class

UPDATE:

Those codes works only for the first time, if I use it more than one time I get this error:

Attempted to read or write protected memory

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

UPDATE:

This code seems to be working

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
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Try declaring pt as an IntPtr and using the Marshal and BitConverter classes to read the integer there.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...