我是新来的,如果我的问题没有以正确的格式产生回复,请原谅我。如果我需要添加任何内容,请告诉我:
我目前正在家里为一家公司的同事做一个项目,该公司使用一个非常古老的遗留系统,将输出显示到屏幕上。他们拥有的系统已经过时,不再受支持(设置它的公司已经倒闭)。有人告诉我,他们需要为月度报告保留系统,但希望以更现代的方式显示其输出,这样当人们进来时,他们可以毫不尴尬地看到正在发生的事情。很难解释,但基本上我被要求从一个屏幕捕获信息并输出到另一个。
我大约完成了样本的 3/4,用 VB.Net 编写......并且发现图像比较对于使用 getpixel 进行比较所发生的变化来说太慢了。将图片保存到内存流进行比较(通过 x,y 寻找匹配)时,速度也是一个问题......所以我已经切换到 lockbits/marshal 复制到字节数组进行比较。基本上 - 显示在多个区域的数据总是与我保存的大约 20 张图像中的一张相匹配。我可以使用捕获和保存的图像比较图像(将差异放在现有保存的图像之上,输出被 100% 涂黑)。我知道我保存的图像与 g.fromimage 之前的比较方法 100% 匹配,但我使用的方法太慢了。现在我正在使用字节数组,
随着一个全新的项目打开,我已经复制了这个问题。在开始时将图像加载到图片框/始终不变 - g.copyfromscreen 到位图,然后存储到字节数组并导出到文本文件,一遍又一遍地完成是不同的。我无法弄清楚为什么会这样。这几乎就像我偶然发现了一个随机发生器哈哈。我比较的区域是 5x72,所以不是很大。现在为了简化,我将一张图片加载到一个像素盒中,然后单击一个按钮将该图片中的数据存储到一个字节数组中。然后我将图片的一个区域保存为 .png 并将同一区域的字节数组文本转换为文本文件。一遍又一遍地单击按钮会产生不同的字节数组到文本输出,但 png 文件匹配 100%。我不会移动图像,我
Module Module1
Public baGB1Small((5 * 72 - 1) * 3) As Byte ' To be populated with small image.
Public baGB2Small((5 * 72 - 1) * 3) As Byte ' To be populated with small image.
Public baGB3Small((5 * 72 - 1) * 3) As Byte ' To be populated with small image.
Public baGB4Small((5 * 72 - 1) * 3) As Byte ' To be populated with small image.
End Module
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim filename As String = DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss_fff")
'-- Below saves a chunk of the screen with the picturebox in it for comparison.
Dim BMPScrNew As New Bitmap(5, 420, Imaging.PixelFormat.Format24bppRgb)
Dim GrabRect As New Rectangle(478, 170, 5, 420)
Using g As Graphics = Graphics.FromImage(BMPScrNew)
g.CopyFromScreen(GrabRect.Location, New Point(0, 0), GrabRect.Size)
End Using
BMPScrNew.Save("C:\TestSaveLoc\SCR1-" & filename & ".png", Imaging.ImageFormat.Png)
'-- Below breaks the main saved image into chunks for comparison.
'-- Chunk 1:
Dim BMPSN As New Bitmap(5, 72)
Dim GRNew As New Rectangle(0, 7, 5, 72)
BMPSN = BMPScrNew.Clone(GRNew, Imaging.PixelFormat.Format24bppRgb)
BMPSN.Save("C:\TestSaveLoc\B1-" & filename & ".png", Imaging.ImageFormat.Png)
Dim BMD As Imaging.BitmapData = BMPSN.LockBits(New Rectangle(0, 0, BMPSN.Width, BMPSN.Height), Imaging.ImageLockMode.ReadOnly, Imaging.PixelFormat.Format24bppRgb)
Runtime.InteropServices.Marshal.Copy(BMD.Scan0, baGB1Small, 0, baGB1Small.Length)
BMPSN.UnlockBits(BMD)
'-- Chunk 2:
BMPSN = New Bitmap(5, 72)
GRNew = New Rectangle(0, 89, 5, 72)
BMPSN = BMPScrNew.Clone(GRNew, Imaging.PixelFormat.Format24bppRgb)
BMPSN.Save("C:\TestSaveLoc\B2-" & filename & ".png", Imaging.ImageFormat.Png)
BMD = BMPSN.LockBits(New Rectangle(0, 0, BMPSN.Width, BMPSN.Height), Imaging.ImageLockMode.ReadOnly, Imaging.PixelFormat.Format24bppRgb)
Runtime.InteropServices.Marshal.Copy(BMD.Scan0, baGB2Small, 0, baGB2Small.Length)
BMPSN.UnlockBits(BMD)
'-- Chunk 3:
BMPSN = New Bitmap(5, 72)
GRNew = New Rectangle(0, 171, 5, 72)
BMPSN = BMPScrNew.Clone(GRNew, Imaging.PixelFormat.Format24bppRgb)
BMPSN.Save("C:\TestSaveLoc\B3-" & filename & ".png", Imaging.ImageFormat.Png)
BMD = BMPSN.LockBits(New Rectangle(0, 0, BMPSN.Width, BMPSN.Height), Imaging.ImageLockMode.ReadOnly, Imaging.PixelFormat.Format24bppRgb)
Runtime.InteropServices.Marshal.Copy(BMD.Scan0, baGB3Small, 0, baGB3Small.Length)
BMPSN.UnlockBits(BMD)
'-- Chunk 4:
BMPSN = New Bitmap(5, 72)
GRNew = New Rectangle(0, 253, 5, 72)
BMPSN = BMPScrNew.Clone(GRNew, Imaging.PixelFormat.Format24bppRgb)
BMPSN.Save("C:\SWAutoer\TestSaveLoc\B4-" & filename & ".png", Imaging.ImageFormat.Png)
BMD = BMPSN.LockBits(New Rectangle(0, 0, BMPSN.Width, BMPSN.Height), Imaging.ImageLockMode.ReadOnly, Imaging.PixelFormat.Format24bppRgb)
Runtime.InteropServices.Marshal.Copy(BMD.Scan0, baGB4Small, 0, baGB4Small.Length)
BMPSN.UnlockBits(BMD)
BMPSN.Dispose()
BMPScrNew.Dispose()
'-- Writes output to a textbox on the screen (for testing only)
Output1.AppendText(Environment.NewLine & DateTime.Now)
Output1.AppendText(Environment.NewLine & "FirstCheck:" & CDWB3(filename))
filename = Nothing
End Sub
Public Function CDWB3(vfpath As String) As String
Dim BMPScrNew As New Bitmap(5, 420, Imaging.PixelFormat.Format24bppRgb)
Dim GrabRect As New Rectangle(478, 170, 5, 420)
Using g As Graphics = Graphics.FromImage(BMPScrNew)
g.CopyFromScreen(GrabRect.Location, New Point(0, 0), GrabRect.Size)
End Using
BMPScrNew.Save("C:\TestSaveLoc\SCR2-" & vfpath & ".png", Imaging.ImageFormat.Png)
Dim WasFound As Integer = 0
Dim FoundAtY As Integer = 0
Dim Checkst As Stopwatch = Stopwatch.StartNew
Dim StoppedAt As Integer = 169
For vNewY = 0 To 348 ' Goes down one pixel through the main scraped image to compare a chunk that is 5x72 to the saved arrays of smaller chunks.
Dim BMPSN As New Bitmap(5, 72)
Dim GRNew As New Rectangle(0, vNewY, 5, 72)
BMPSN = BMPScrNew.Clone(GRNew, Imaging.PixelFormat.Format24bppRgb)
BMPSN.Save("C:\TestSaveLoc\B1Loc-" & vfpath & ".png", Imaging.ImageFormat.Png)
Dim BMD As Imaging.BitmapData = BMPSN.LockBits(New Rectangle(0, 0, BMPSN.Width, BMPSN.Height), Imaging.ImageLockMode.ReadOnly, Imaging.PixelFormat.Format24bppRgb)
Dim vmBuffer((BMPSN.Width * BMPSN.Height - 1) * 3) As Byte
Marshal.Copy(BMD.Scan0, vmBuffer, 0, vmBuffer.Length)
BMPSN.UnlockBits(BMD)
If vNewY = 7 Then '-- THIS IS WHERE bagb1small should always match.
Dim writer1 As New IO.StreamWriter("C:\TestSaveLoc\MainBuff-" & vfpath & ".txt")
writer1.WriteLine(Convert.ToBase64String(vmBuffer))
writer1.Flush()
writer1.Close()
writer1.Dispose()
Dim writer2 As New IO.StreamWriter("C:\TestSaveLoc\bagb1small-" & vfpath & ".txt")
writer2.WriteLine(Convert.ToBase64String(bagb1small))
writer2.Flush()
writer2.Close()
writer2.Dispose()
End If
StoppedAt = StoppedAt + 1
Dim B1Found As Boolean = True
Dim B2Found As Boolean = True
Dim B3Found As Boolean = True
Dim B4Found As Boolean = True
For i = 0 To vmBuffer.Length - 1 Step 3
Dim BadCount As Integer = 0
If vmBuffer(i) <> baGB1Small(i) Then
B1Found = False
BadCount += 1
End If
If vmBuffer(i) <> baGB2Small(i) Then
B2Found = False
BadCount += 1
End If
If vmBuffer(i) <> baGB3Small(i) Then
B3Found = False
BadCount += 1
End If
If vmBuffer(i) <> baGB4Small(i) Then
B4Found = False
BadCount += 1
End If
If BadCount > 3 Then Exit For
Next
BMD = Nothing
vmBuffer = Nothing
If B1Found = True Then
WasFound = 1
Exit For
End If
If B2Found = True Then
WasFound = 2
Exit For
End If
If B3Found = True Then
WasFound = 3
Exit For
End If
If B4Found = True Then
WasFound = 4
Exit For
End If
BMPSN.Dispose()
Next
BMPScrNew.Dispose()
Checkst.Stop()
CDWB3 = WasFound.ToString & "," & StoppedAt
End Function
使用上面的代码,图片在窗体的加载事件中被加载到屏幕上设定位置的图片框中。我期望发生的是每次单击按钮都会产生相同的输出(字节数组与上次单击的字节数组匹配),因为屏幕上的图像根本没有改变。不是这种情况。
每次单击按钮时,我的图像输出(文件保存为 png)都匹配。输出到文本的字节数组不匹配。有时会找到块 1,有时会找到块 2-4(屏幕上看不到块 1),有时根本没有……这是屏幕上的静态图像,我正在从中抓取并与之进行比较-这应该并非如此。每次都应该在相同的位置找到块 1,并且每次都应该相同的字节数组。