Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 447
  • Last Modified:

counting a colors pixels on picturebox urgent!

Hello, I am currently counting a specific colors number of pixels in an area of a picturebox, if the number is > 175 then I add it to the listbox, however it takes a very long time to count the pixels?? is there any way I can speed the it up? It takes be about 5-10 seconds to scan 1 picture this is very slow...any ideas??

This is my function:

Public Function CountPixels(color As Long, picBox As PictureBox) As Long
   
    Dim x As Long, y As Long
    Dim handle As Long, count As Long
    Dim Hcolor As Long
    ' cache form's hDC property
    handle = picBox.hdc

    For y = 0 To Int(picBox.ScaleY(picBox.ScaleHeight, vbTwips, vbPixels) / 2)
        For x = 0 To Int(picBox.ScaleX(picBox.ScaleWidth, vbTwips, vbPixels) / 2)
           Hcolor = (GetPixel(handle, x, y))
           If Hcolor = color Then
                count = count + 1
            End If
        Next
    Next

    CountPixels = count
End Function

Thanks
0
nffvrxqgrcfqvvc
Asked:
nffvrxqgrcfqvvc
  • 4
  • 2
1 Solution
 
2AngelCommented:
Hi,

Do you have to count every pixel?
0
 
nffvrxqgrcfqvvcAuthor Commented:
Yes I am trying to calculate a specific color and get the number of pixels for the color..the above code works fine in doing that but if the image is large it takes very long...anyways I dont' know if the above coordinates are correct however I am trying to get the number of pixels in the middle area....pherhaps if i could calculate just a square area in the middle portion of the picture that would be great. but i dont know how i would do that.
0
 
BurbbleCommented:
I saw a very slight improvement (8-10ms faster) by doing this:

Public Function CountPixels(color As Long, picBox As PictureBox) As Long
   
    Dim x As Long, y As Long
    Dim handle As Long, count As Long
    Dim Hcolor As Long
    Dim Area_height As Long
    Dim Area_width As Long
    ' cache form's hDC property
    handle = picBox.hdc
    Area_height = Int(picBox.ScaleY(picBox.ScaleHeight, vbTwips, vbPixels) / 2)
    Area_width = Int(picBox.ScaleX(picBox.ScaleWidth, vbTwips, vbPixels) / 2)

    For y = 0 To Area_height
        For x = 0 To Area_width
            If GetPixel(handle, x, y) = color Then
                count = count + 1
            End If
        Next
    Next

    CountPixels = count
End Function

Overall, the average speed I get is 150ms for a 640x480 image (measured with GetTickCount).

0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
BurbbleCommented:
To get an area from the center section only, here's my whole project (has Picture1 as a picturebox and Command1 as a command button):


Private Declare Function GetTickCount Lib "kernel32" () As Long
Private Declare Function GetPixel Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long) As Long

Private Const AreaWidth = 320  'pixels
Private Const AreaHeight = 240

Public Function CountPixels(color As Long, picBox As PictureBox) As Long
   
    Dim x As Long, y As Long
    Dim handle As Long, count As Long
    Dim Hcolor As Long
    Dim X_LocationA As Long
    Dim X_LocationB As Long
    Dim Y_LocationA As Long
    Dim Y_LocationB As Long

    ' cache form's hDC property
    handle = picBox.hdc

    X_LocationA = (picBox.ScaleX(picBox.ScaleWidth, vbTwips, vbPixels) / 2) - (AreaWidth / 2)
    X_LocationB = (picBox.ScaleX(picBox.ScaleWidth, vbTwips, vbPixels) / 2) + (AreaWidth / 2)
    Y_LocationA = (picBox.ScaleX(picBox.ScaleHeight, vbTwips, vbPixels) / 2) - (AreaHeight / 2)
    Y_LocationB = (picBox.ScaleX(picBox.ScaleHeight, vbTwips, vbPixels) / 2) + (AreaHeight / 2)

    For y = Y_LocationA To Y_LocationB
        For x = X_LocationA To X_LocationB
            If GetPixel(handle, x, y) = color Then
                count = count + 1
            End If
        Next
    Next

    CountPixels = count
End Function

Private Sub Command1_Click()
    Dim lngTime As Long
    Dim lngCount As Long
    lngTime = GetTickCount()
    lngCount = CountPixels(vbWhite, Picture1)
    Me.Caption = lngCount & " pixels -- " & GetTickCount - lngTime & "ms"
End Sub



You can adjust the size of the center area by changing the two constants at the top.
0
 
BurbbleCommented:
Remember to compile the project to get faster speeds. Running it in the development environment (i.e. "play button") will result in it going slower.
0
 
nffvrxqgrcfqvvcAuthor Commented:
Ic..is there anyway I can draw a line on the picture to show me where its looking for the pixels at??

picture1.line()??

I don't deal much with graphics sorry for my lack of knowledge in this area, that seems to work alot better but I just want to be able to see where its searching the pixels
0
 
BurbbleCommented:
Add this (it's kind of sloppy-looking but it gets the job done):

    picBox.Line (15 * X_LocationA, 15 * Y_LocationA)-(15 * X_LocationB, 15 * Y_LocationA), vbBlack
    picBox.Line (15 * X_LocationA, 15 * Y_LocationB)-(15 * X_LocationB, 15 * Y_LocationB), vbBlack
    picBox.Line (15 * X_LocationA, 15 * Y_LocationA)-(15 * X_LocationA, 15 * Y_LocationB), vbBlack
    picBox.Line (15 * X_LocationB, 15 * Y_LocationA)-(15 * X_LocationB, 15 * Y_LocationB), vbBlack


So the entire thing would be:




Private Declare Function GetTickCount Lib "kernel32" () As Long
Private Declare Function GetPixel Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long) As Long

Private Const AreaWidth = 320  'pixels
Private Const AreaHeight = 240

Public Function CountPixels(color As Long, picBox As PictureBox) As Long
   
    Dim x As Long, y As Long
    Dim handle As Long, count As Long
    Dim Hcolor As Long
    Dim X_LocationA As Long
    Dim X_LocationB As Long
    Dim Y_LocationA As Long
    Dim Y_LocationB As Long

    ' cache form's hDC property
    handle = picBox.hdc

    X_LocationA = (picBox.ScaleX(picBox.ScaleWidth, vbTwips, vbPixels) / 2) - (AreaWidth / 2)
    X_LocationB = (picBox.ScaleX(picBox.ScaleWidth, vbTwips, vbPixels) / 2) + (AreaWidth / 2)
    Y_LocationA = (picBox.ScaleX(picBox.ScaleHeight, vbTwips, vbPixels) / 2) - (AreaHeight / 2)
    Y_LocationB = (picBox.ScaleX(picBox.ScaleHeight, vbTwips, vbPixels) / 2) + (AreaHeight / 2)

    picBox.Line (15 * X_LocationA, 15 * Y_LocationA)-(15 * X_LocationB, 15 * Y_LocationA), vbBlack
    picBox.Line (15 * X_LocationA, 15 * Y_LocationB)-(15 * X_LocationB, 15 * Y_LocationB), vbBlack
    picBox.Line (15 * X_LocationA, 15 * Y_LocationA)-(15 * X_LocationA, 15 * Y_LocationB), vbBlack
    picBox.Line (15 * X_LocationB, 15 * Y_LocationA)-(15 * X_LocationB, 15 * Y_LocationB), vbBlack

    For y = Y_LocationA To Y_LocationB
        For x = X_LocationA To X_LocationB
            If GetPixel(handle, x, y) = color Then
                count = count + 1
            End If
        Next
    Next

    CountPixels = count
End Function

Private Sub Command1_Click()
    Dim lngTime As Long
    Dim lngCount As Long
    lngTime = GetTickCount()
    lngCount = CountPixels(vbWhite, Picture1)
    Me.Caption = lngCount & " pixels -- " & GetTickCount - lngTime & "ms"
End Sub
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 4
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now