2013-05-16 70 views
3

存在一種簡單的方法來檢查圖像是否包含某些rgb顏色?如果圖像包含特定的顏色,那麼

例如:

Dim img As Image = Image.FromFile("C:\image.png") 

If img.contains color.red(.toRGB) then... 

我想檢查這個困難的方式是通過獲取圖像的每個像素的顏色值,不包括PNG圖像的透明度......也該技術,我認爲會需要花費更長的時間來處理整個圖像...但無論如何,我也不知道該怎麼做。

UPDATE

嘗試這樣做,但它sayd我試圖從受保護的內存訪問閱讀:

' Lock the bitmap's data. 
Public Function LockBitmap(ByVal bm As Bitmap) As Byte() 
    Dim bmp = New Bitmap("C:\Users\Administrador\Desktop\PrtScr capture_3.jpg") 
    Dim bmdata As BitmapData = bmp.LockBits(New Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb) 
    Dim buffer(bmdata.Stride * bmdata.Height - 1) As Byte 
    Marshal.Copy(bmdata.Scan0, buffer, 0, buffer.Length) 
    Dim stride As Integer = bmdata.Stride 
    bmp.UnlockBits(bmdata) 

    'loop over the pixels 
    For y As Integer = 0 To bmp.Height - 1 
     For x As Integer = 0 To bmp.Width - 1 
      Dim valB As Integer = 255 - Marshal.ReadByte(bmdata.Scan0, (stride * y) + (x * 4)) 
      Dim valG As Integer = 255 - Marshal.ReadByte(bmdata.Scan0, (stride * y) + (x * 4) + 1) 
      Dim valR As Integer = 255 - Marshal.ReadByte(bmdata.Scan0, (stride * y) + (x * 4) + 2) 

      MsgBox(valR & "," & valG & "," & valB) 
     Next 
    Next 

End Function 

試過,但不能設置值:Can't set the correct value in this while loop

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 

試過一個例子,這使我的修改:http://social.msdn.microsoft.com/Forums/en-US/vblanguage/thread/1d04ef14-cffb-4ae1-83d3-3a0cd8255c95

'get a BitmapDataObject for fast processing and copy the Data of the image to an array 
    Dim bmdata As BitmapData = bmp.LockBits(New Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb) 
    Dim buffer(bmdata.Stride * bmdata.Height - 1) As Byte 
    Marshal.Copy(bmdata.Scan0, buffer, 0, buffer.Length) 
    Dim stride As Integer = bmdata.Stride 
    bmp.UnlockBits(bmdata) 

    'loop over the pixels 
    For y As Integer = 0 To bmp.Height - 1 
     For x As Integer = 0 To bmp.Width - 1 
      'Colors/Bytes stored in sequence BGRA 
      'test access of alpha channel 
      If buffer((stride * y) + (x * 4) + 3) <> 0 Then 
       'do something 
      End If 
     Next 
    Next 

' use Marshal.Copy again to put the processed data back to the image. 

花更多的時間在這裏嘗試更多的例子:http://www.vb-helper.com/howto_net_lockbits_image.html

' Title Manipulate image pixels very quickly using LockBits in VB .NET 

Public g_RowSizeBytes As Integer 
Public g_PixBytes() As Byte 

Private m_BitmapData As BitmapData 

' Lock the bitmap's data. 
Public Sub LockBitmap(ByVal bm As Bitmap) 
    ' Lock the bitmap data. 
    Dim bounds As Rectangle = New Rectangle(_ 
     0, 0, bm.Width, bm.Height) 
    m_BitmapData = bm.LockBits(bounds, _ 
     Imaging.ImageLockMode.ReadWrite, _ 
     Imaging.PixelFormat.Format24bppRgb) 
    g_RowSizeBytes = m_BitmapData.Stride 

    ' Allocate room for the data. 
    Dim total_size As Integer = m_BitmapData.Stride * _ 
     m_BitmapData.Height 
    ReDim g_PixBytes(total_size) 

    ' Copy the data into the g_PixBytes array. 
    Marshal.Copy(m_BitmapData.Scan0, g_PixBytes, _ 
     0, total_size) 
End Sub 

也也試過另一種方法:https://stackoverflow.com/questions/16598567/transparencykey-and-displayed-images-issue

我沒有必要的知識,使之。

請問,有人可以幫助我嗎?

+1

即使有一個函數/方法用於圖像是否包含特定顏色 - 該函數將不得不遍歷整個圖像以便給出正確的答案 - 是不是?我沒有看到任何其他方式。 – OneFineDay

+0

@DonA我發現你是對的我需要遍歷每個像素,但我不知道該怎麼做,謝謝你的回答。 – ElektroStudios

+0

我用很多示例和代碼更新了我的問題 - 我做出了失敗。 – ElektroStudios

回答

2

那麼,你可以很容易地通過你確定的「硬道路」,檢查每個像素,直到找到一個特定的顏色。 最糟糕的情況?循環整個圖像。

Private Function ColorInBitmap(Path As String, Target As Color) As Boolean 
    Dim B As New Bitmap(Path) 
    For x As Integer = 1 To B.Width 
     For y As Integer = 1 To B.Height 
      Dim tmpC As Color = B.GetPixel(x - 1, y - 1) 
      If tmpC.Equals(Target) Then Return True 
     Next 
    Next 
    Return False 
End Function 

花了5,6秒到2048×1536的圖像返回False,Bitmap類加載JPG前

你可以簡單地通過傳遞路徑圖像和目標顏色用它測量。

ColorInBitmap("c:\test.jpg", Color.FromArgb(109, 109, 109)) 

請注意,此Fromargb重載將alpha值設置爲最大值。

+0

感謝您的回答 – ElektroStudios

相關問題