0

The following code works well for what I am doing. However, it is taking longer than I need it to. The problem is that it iterates over each greater than/less than function and that takes time. I've done some research but can't figure out how to slim it all down so that it runs faster.

The pixel RGB values have to run through the following tests- (1) If one value is greater than 250, the others have to be less than 5 (2) If one value is less than 5, the others have to be greater than 250 (3) If one value equals zero, the others have to be greater than 0 (4) The difference between any 2 values have to be less than 15 (or any other threshold I set) (5) See if two values equal zero

Also, will doing 'Exit For' after each of these functions help?

    ' Create new bitmap from filepath in TextBox1
    Dim bmp As New Bitmap(TextBox1.Text)

    ' Lock the bitmap's pixels
    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)

    ' Get the address of the first line
    Dim ptr As IntPtr = bmpData.Scan0

    ' Declare an array to hold the bytes of the bitmap
    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)

    ' Retrieve RGB values
    Dim RedValue As Int32
    Dim GreenValue As Int32
    Dim BlueValue As Int32
    Dim l As Integer = 0                   
    For x = 0 To bmp.Width  
        For y = 0 To bmp.Height - 1
            l = ((bmp.Width * 3 * y) + (x * 3))
            RedValue = rgbValues(l)
            GreenValue = rgbValues(l + 1)
            BlueValue = rgbValues(l + 2)

            If RedValue < 5 AndAlso GreenValue < 5 AndAlso BlueValue > 250 Then
            ElseIf RedValue < 5 AndAlso GreenValue > 250 AndAlso BlueValue < 5 Then
            ElseIf RedValue > 250 AndAlso GreenValue < 5 AndAlso BlueValue < 5 Then
            ElseIf RedValue > 250 AndAlso GreenValue > 250 AndAlso BlueValue < 5 Then
            ElseIf RedValue > 250 AndAlso GreenValue < 5 AndAlso BlueValue > 250 Then
            ElseIf RedValue < 5 AndAlso GreenValue > 250 AndAlso BlueValue > 250 Then
            ElseIf RedValue > 0 AndAlso GreenValue > 0 AndAlso BlueValue.Equals(0) Then
            ElseIf RedValue > 0 AndAlso GreenValue.Equals(0) AndAlso BlueValue > 0 Then
            ElseIf RedValue.Equals(0) AndAlso GreenValue > 0 AndAlso BlueValue > 0 Then
            ElseIf (RedValue - GreenValue) < 15 AndAlso (RedValue - BlueValue) < 15 AndAlso _
                (GreenValue - RedValue) < 15 AndAlso (GreenValue - BlueValue) < 15 AndAlso _
                (BlueValue - RedValue) < 15 AndAlso (BlueValue - GreenValue) < 15 Then
            ElseIf RedValue.Equals(GreenValue) Then
            ElseIf RedValue.Equals(BlueValue) Then
            ElseIf GreenValue.Equals(BlueValue) Then
            ElseIf RedValue.Equals(BlueValue) AndAlso RedValue.Equals(GreenValue) _
                AndAlso BlueValue.Equals(GreenValue) Then
            Else
                MsgBox("Image is color.")
                Exit Sub
            End If
        Next
    Next
    MsgBox("Image is grayscale.")

    ' Unlock the bitmap
    bmp.UnlockBits(bmpData)
  • I'm confused by your logic. If (1) is true, then (2) can never be true. And if (1) or (2) are true, then (4) cannot ever be true. Is this a sequence of checks, or does every RGB value have to conform to all rules? If it is a sequence, then nested Ifs may give you slightly better performance – APrough Jul 10 '12 at 19:18
  • It's a sequence of checks so each test is exclusive. I don't expect each RGB value to conform to each test. I just want to make sure I weed out every pixel that I would consider not color, including weeding out extreme differences for purposes of accuracy (255:255:0, 0:0:255, etc.). I'll try to nest a couple Ifs and see if it helps. Didn't think of that. Thanks. –  Jul 10 '12 at 22:54
  • @Jerry Are these two accounts linked? (Jerry Horak and you). If so, let us know so we can merge your accounts. – George Stocker Jul 11 '12 at 00:56

1 Answers1

0

Grayscale colors have always this specification ( R=G=B ). eg. #cccccc = [R:204 G:204 B:204]

If Not R = G And G = B Then
 MsgBox("colored")
 Exit Sub
End If
Jon Taylor
  • 7,865
  • 5
  • 30
  • 55