3
\$\begingroup\$

I am looking to speed up the search for black and white images. I have about 150,000 images that I need to check but this is taking so long. How can I speed up the code?

Private Sub BlackOrWhite()    
    Dim iPath As String = txtFile1.Text
    Dim allFiles() As String = IO.Directory.GetFiles(iPath, "*.*", IO.SearchOption.TopDirectoryOnly)
    For Each eachPic In allFiles
        Dim myImage As Bitmap = New Bitmap(eachPic, True)
        Dim myColor As Color = CalculateColorKey(myImage)
        myImage.Dispose()

        If GetRgbDelta(myColor) = 0 Then
            IO.File.Move(eachPic, iPath & "Delete\" & IO.Path.GetFileName(eachPic))
        End If
    Next
End Sub

Public Shared Function CalculateColorKey(bmp As Bitmap) As Color
    Try
        Dim keyColor As Color = Color.Empty
        Dim highestRgbDelta As Integer = 0

        For x As Integer = 0 To CInt((bmp.Width / 2))
            For y As Integer = 0 To CInt(bmp.Height / 2)
                If GetRgbDelta(bmp.GetPixel(x, y)) <= highestRgbDelta Then
                    Continue For
                End If

                highestRgbDelta = GetRgbDelta(bmp.GetPixel(x, y))
                keyColor = bmp.GetPixel(x, y)
            Next
        Next

        Return keyColor
    Catch ex As Exception
        Debug.Print("CalculateColorKey: " & ex.Message)
    End Try
End Function

Private Shared Function GetRgbDelta(color As Color) As Integer
    GetRgbDelta = 100
    Try
        Dim aaa As Integer = Math.Abs(CInt(color.R) - CInt(color.G))
        Dim bbb As Integer = Math.Abs(CInt(color.G) - CInt(color.B))
        Dim ccc As Integer = Math.Abs(CInt(color.B) - CInt(color.R))
        Return aaa + bbb + ccc
    Catch ex As Exception
        Debug.Print("GetRgbDelta: " & ex.Message)
    End Try
End Function
\$\endgroup\$
2
\$\begingroup\$

Your code should have a function IsGrayscale(bmp as Bitmap) as Boolean. It should look like this:

Function IsGrayscale(bmp as Bitmap) as Boolean
    For x As Integer = 0 To bmp.Width - 1 Do
        For y As Integer = 0 To bmp.Height - 1 Do
          If Not IsGrayscalePixel(bmp.GetPixel(x, y)) Then
              Return False
          End If
        End For
    End For
    Return True
End Function

Function IsGrayscalePixel(col as Color) as Boolean
    Return col.R = col.G and col.G = col.B
End Function

At least this is what I think your program should do, based on your description. You don't need the concept of a "color key" to check whether an image is grayscale or not.

The main point is that the function returns as soon as it has found a colored pixel, since then there is no point in checking the rest of the image.

Note that I don't know Visual Basic well, so there might be syntax errors in the above code. So focus more on the ideas than one the grammar.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.