【问题标题】:If Image contains specific color then如果图像包含特定颜色,则
【发布时间】:2013-05-11 23:50:48
【问题描述】:

是否有一种简单的方法来检查图像是否包含某种 rgb 颜色?

例如:

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

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

我认为检查这一点的困难方法是获取图像每个像素的颜色值,不包括 png 的透明度......而且我认为该技术需要更长的时间来处理整个图像...但无论如何我也不知道该怎么做。

更新

试过这个,但它说我正在尝试从受保护的内存访问中读取:

' 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

我没有必要的知识来制作它。

请问有人可以帮帮我吗?

【问题讨论】:

  • 即使有一个函数/方法来判断图像是否包含特定颜色——该函数必须迭代整个图像才能给你正确的答案——不是吗?我没有看到任何其他方式。
  • @DonA 我发现你是对的我需要遍历每个像素,但我不知道该怎么做,谢谢你的回答。
  • 我用我做的很多例子和代码失败更新了我的问题。

标签: .net vb.net image colors pixel


【解决方案1】:

好吧,您可以通过您确定的“硬方式”轻松完成,检查每个像素,直到找到特定颜色。 最坏的情况是?循环整个图像。

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

在 2048x1536 图像上返回 False 需要 5.6 秒,在 Bitmap 类加载 JPG 之前测量

您可以简单地通过传递图像的路径和目标颜色来使用它。

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

请注意,此 Fromargb 重载会将 alpha 值设置为最大值。

【讨论】:

    猜你喜欢
    • 2012-08-12
    • 1970-01-01
    • 1970-01-01
    • 2022-01-06
    • 2021-04-06
    • 2019-01-28
    • 1970-01-01
    • 2021-04-28
    • 1970-01-01
    相关资源
    最近更新 更多