标题:用picture控件取像素值进行图像对比,窗体最小化运行后就不能正常提取图片像 ...
只看楼主
yjz2022
Rank: 1
等 级:新手上路
威 望:1
帖 子:17
专家分:0
注 册:2022-4-27
结帖率:50%
已结贴  问题点数:20 回复次数:9 
用picture控件取像素值进行图像对比,窗体最小化运行后就不能正常提取图片像素数据
做一个工程要监控电脑屏幕的文字变化,当发现出现某个特定文字时就电脑串口输出一个控制信号,用两个picture控件,一个存放屏幕截图的带有特定字符的标准图片,另一个不断刷屏截图并和标准图片比对,目前功能正常,但就是不能把窗体最小化,最小化后,就不能进行比对,必须两个picture控件都可见才运行正常,麻烦高手指导下,有什么解决方案,谢谢!
搜索更多相关主题的帖子: picture 图片 运行 最小化 控件 
2022-04-27 08:47
yjz2022
Rank: 1
等 级:新手上路
威 望:1
帖 子:17
专家分:0
注 册:2022-4-27
得分:0 
是不是要把标准图片和截屏的待比对图片都要存为文件,然后对两个文件进行比对才可以?
2022-04-27 09:10
风吹过b
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:364
帖 子:4912
专家分:29900
注 册:2008-10-15
得分:0 
猜测是 系统检测到这个窗体被最小化了,然后不更新窗体上显示资源导致的。

这样测试一下,增加一个窗体,这个窗体永不最小化,并且在任务栏上不显示。程序运行时,把这个窗体移动可显示区域外,如
form2.move -form2.width,-form2.height
标准图片和截图后的图片,都放到这个窗体上,看看程序能正常运行吗?

授人于鱼,不如授人于渔
早已停用QQ了
2022-04-27 12:56
jklqwe111
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:35
帖 子:335
专家分:1125
注 册:2014-4-13
得分:5 
我认为实现屏幕监测,是应该把屏幕截图与标准图片存为文件比较好,这样可以让程序运行在后台,另外还可以把屏幕截图与标准图片复制为内存位图进行比对,这样速度会很快。
2022-04-27 13:55
yjz2022
Rank: 1
等 级:新手上路
威 望:1
帖 子:17
专家分:0
注 册:2022-4-27
得分:0 
回复 4楼 jklqwe111
请教下怎么从位图文件(.bmp)读出图片对应像素点的RGB数据,比如一个400*300的BMP文件,怎么读出(100,50)像素得点的R,G,B数据,非常感谢。
2022-04-27 18:26
yjz2022
Rank: 1
等 级:新手上路
威 望:1
帖 子:17
专家分:0
注 册:2022-4-27
得分:0 
回复 3楼 风吹过b
您好,感谢你的回复,现在的情况是,手动拖动窗体,只要比对的图像区域在显示区外就不行。
2022-04-27 18:31
风吹过b
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:364
帖 子:4912
专家分:29900
注 册:2008-10-15
得分:15 
以下是引用yjz2022在2022-4-27 18:26:45的发言:

请教下怎么从位图文件(.bmp)读出图片对应像素点的RGB数据,比如一个400*300的BMP文件,怎么读出(100,50)像素得点的R,G,B数据,非常感谢。



https://bbs.bccn.net/thread-481230-1-1.html
你看一下这个贴子,我在里面有 BMP 文件解析方法,特别是找坐标的方法,虽然是从 内存复制数据解析。
你主要看的是 找坐标的方法 。

BMP 的文件结构你可以百度一下,
注意的是: 位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右,扫描行之间是从下到上。

从文件解析,具体看下面的代码。
---------BAS,只处理非压缩的BMP----------
程序代码:
Option Explicit

'Bmp公用函数


'BMP压缩类型,
Public Const BI_RGB = 0     '非压缩
Public Const BI_RLE8 = 1
Public Const BI_RLE4 = 2

Public Enum BMP文件结构各部分偏移量
    文件类型标识 = 0
    文件长度 = 2
    保留字1 = 6
    保留字2 = 8
    数据起始位置 = 10
    
    本结构长度 = 14
    图像宽 = 18
    图像高 = 22
    目标设备级别 = 26
    色彩位数 = 28
    压缩 = 30
    位图大小 = 34
    位图水平分辨率 = 38
    位图垂直分辨率 = 42
    使用的颜色数 = 46
    重要的颜色数 = 50
End Enum

Public Type BMP文件头结构类型
    文件类型标识 As String * 2      '二字节长,只能为BM
    文件长度 As Long                '文件长度,4字节
    保留字1 As Integer              '系统保留,2字节,只能为0
    保留字2 As Integer              '系统保留,2字节,只能为0
    数据起始位置 As Long            '数据起始位置,相对数据头
End Type
    
    
Public Type BMP文件颜色表类型
    蓝 As Byte
    绿 As ByteAs Byte
    保留 As Byte
End Type
    
Public Type BMP文件位图信息头类型
    本结构长度 As Long              '本结构的长度,包含颜色表的
    图像宽 As Long                  '图像宽
    图像高 As Long                  '图像高
    目标设备级别 As Integer         '目标设备级别,只能为1
    色彩位数 As Integer             '每像素色彩位数,只能为1(双色),4(16色),8(256色),24(真彩) 四种
    压缩 As Long                    '是否是压缩的,必须是 0(不压缩), 1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一
    位图大小 As Long                '位图数据区的大小
    位图水平分辨率 As Long          '位图水平分辨率,每米像素数,好像可以为零
    位图垂直分辨率 As Long          '位图垂直分辨率,每米像素数,好像可以为零
    使用的颜色数 As Long            '位图实际使用的颜色表中的颜色数
    重要的颜色数 As Long            '位图显示过程中重要的颜色数
End Type

Public Type BMP扫描行类型
    X() As Byte
    空() As Byte
End Type

Public Type BMP文件类型
    文件标识 As BMP文件头结构类型
    位图信息 As BMP文件位图信息头类型
    颜色表() As BMP文件颜色表类型   '颜色表,=色彩位数^2 ,色彩位数为24时,无颜色表
    数据() As BMP扫描行类型         '位图数据,合并为每个像素一个long值
End Type


'当biBitCount=1时,8个像素占1个字节;
'当biBitCount=4时,2个像素占1个字节;
'当biBitCount=8时,1个像素占1个字节;
'当biBitCount=24时,1个像素占3个字节;
'Windows规定一个扫描行所占的字节数必须是
'4的倍数(即以long为单位),不足的以0填充,
'一个扫描行所占的字节数计算方法:
'DataSizePerLine= (biWidth* biBitCount+31)/8;
'// 一个扫描行所占的字节数
'DataSizePerLine= DataSizePerLine/4*4; // 字节数必须是4的倍数
'位图数据的大小(不压缩情况下):
'DataSize= DataSizePerLine* biHeight;


Public Function openbmp(Bmpfile As String, ByRef BMP文件 As BMP文件类型) As Integer
'打开BMP文件,读取数据
If Dir(Bmpfile) <> "" Then
Dim fj As Long
Dim i As Long
Dim colortmp() As Long
Dim 扫描行 As Long, 保留 As Long


With BMP文件
    fj = FreeFile()
    Open Bmpfile For Binary As #fj
        Get #fj, , .文件标识        '读文件标识
        If .文件标识.文件类型标识 = "BM" Then   '是BMP文件否
            Get #fj, , .位图信息
                ReDim .数据(.位图信息.图像高 - 1)
                
                扫描行 = (.位图信息.图像宽 * .位图信息.色彩位数) / 8
                保留 = 4 - (扫描行 Mod 4)
                For i = 0 To .位图信息.图像高 - 1
                    ReDim .数据(i).X(扫描行 - 1)
                    If 保留 > 0 And 保留 < 4 Then
                        ReDim .数据(i).空(保留 - 1)
                    End If
                Next i
            
                Select Case .位图信息.色彩位数
                    Case 1                  '2色图片
                        ReDim .颜色表(1)        '初始化颜色表数据
                        Get #fj, , .颜色表      '读颜色表
                        For i = 0 To .位图信息.图像高 - 1
                            Get #fj, , .数据(i).X
                            Get #fj, , .数据(i).空
                        Next i
                    Case 4                  '16色图片
                        ReDim .颜色表(15)       '初始化颜色表数据
                        Get #fj, , .颜色表      '读颜色表
                        For i = 0 To .位图信息.图像高 - 1
                            Get #fj, , .数据(i).X
                            Get #fj, , .数据(i).空
                        Next i
                    Case 8                  '256色图片
                        ReDim .颜色表(255)      '初始化颜色表数据
                        Get #fj, , .颜色表      '读颜色表
                        
                        For i = 0 To .位图信息.图像高 - 1
                            Get #fj, , .数据(i).X
                            Get #fj, , .数据(i).空
                        Next i
                        
                    Case 24                  '真彩图片,无颜色表
                        'i = (.位图信息.图像宽 - 1) * (.位图信息.图像高 - 1)
                        'ReDim .数据(i)
                        'ReDim .数据(.位图信息.图像宽, .位图信息.图像高, 2)
                        For i = 0 To .位图信息.图像高 - 1
                            Get #fj, , .数据(i).X
                            Get #fj, , .数据(i).空
                        Next i
                End Select
            
        Else        '文件标识不对,打开失败
            openbmp = -2
        End If
    Close #fj
End With
Else    '文件不存在,打开失败
    openbmp = -1
End If
End Function

Public Function viewbmp(BMP文件 As BMP文件类型, PIC As PictureBox) As Integer

Dim i As Long, j As Long, k As Long, n As Byte
Dim i1 As Integer, i2 As Integer
Dim ycon() As Long


With BMP文件
PIC.Cls
If .位图信息.色彩位数 < 24 Then
    i1 = .位图信息.色彩位数 ^ 2
    ReDim ycon(i1)
    For i = 0 To i1
        ycon(i) = RGB(.颜色表(i).红, .颜色表(i).绿, .颜色表(i).蓝)
    Next i
End If
For i = 0 To .位图信息.图像高 - 1
'    For j = 1 To .位图信息.图像高
        Select Case .位图信息.色彩位数
        Case 1
            For j = 0 To (.位图信息.图像宽 / 8)
                For k = 0 To 7
                    n = 2 ^ (7 - k)
                    If j * 8 + k < .位图信息.图像宽 Then
                        i1 = .数据(i).X(j) And n / n        '第n位
                        PIC.PSet (j * 8 + k, .位图信息.图像高 - i), ycon(i1)
                    End If
                Next k
            Next j
        
        Case 4
            For j = 0 To (.位图信息.图像宽 / 2) - 1
                i1 = .数据(i).X(j) \ 16        '高位
                i2 = .数据(i).X(j) Mod 16      '低位
                PIC.PSet (j * 2, .位图信息.图像高 - i), ycon(i1)
                PIC.PSet (j * 2 + 1, .位图信息.图像高 - i), ycon(i2)
            Next j
            If j * 2 < .位图信息.图像宽 Then        '还少了一点
                i1 = .数据(i).X(j) \ 16        '高位
                PIC.PSet (j * 2, .位图信息.图像高 - i), ycon(i1)
            End If
        
        Case 8
            For j = 0 To .位图信息.图像宽 - 1
                PIC.PSet (j, .位图信息.图像高 - i), ycon(.数据(i).X(j))
            Next j
        
        Case 24
            For j = 0 To .位图信息.图像宽 - 1
                PIC.PSet (j, .位图信息.图像高 - i), RGB(.数据(i).X(j * 3 + 2), .数据(i).X(j * 3 + 1), .数据(i).X(j * 3 + 0))
            Next j
'    Next j
        End Select
Next i
End With
End Function

授人于鱼,不如授人于渔
早已停用QQ了
2022-04-27 19:45
jklqwe111
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:35
帖 子:335
专家分:1125
注 册:2014-4-13
得分:0 
vb提取像素颜色,在窗体或图片框中是有可用的函数的,从bmp文件中获得,是要自己去实现,方法就是用二进制方式打开文件,用随机读取的方式读取,这就要对bmp文件格式有所了解,网上搜一下会得到很低资料的,bmp文件的头部保存着文件的信息,所需的信息有:第10--13(字节)是像素数据距离文件头的偏移量ptr,18--21 像素宽度w,22--25 像素高度h,28-29 每个像素使用的比特位数nbit,24--27 像素数据长度(字节)len有了这些数据,先计算数据区每行的字节数len/h,还可以用w计算  ((w*nbit+31) and (not 31))/8 两种计算应该相同,这样,打开文件后定位到ptr位,每次读取计算的字节数,读入到一个字节数组中,这样就得到了像素阵列,如果是24位真色彩图,那么每三个字节就是rgb值,否则就是颜色表的序号,那么还要读取颜色表 位置在54-ptr,颜色表4个字节一条,前3个rgb值,第4个无用。大致的方法就是这样,实现起来还是比较复杂的。
2022-04-27 20:41
yjz2022
Rank: 1
等 级:新手上路
威 望:1
帖 子:17
专家分:0
注 册:2022-4-27
得分:0 
回复 7楼 风吹过b
非常感谢您的回复,您提供的资料很详细,我要花点时间消化,感觉我要的答案应该在您的回复中,等我我弄好了再告诉您,谢谢!
2022-04-28 09:34
yjz2022
Rank: 1
等 级:新手上路
威 望:1
帖 子:17
专家分:0
注 册:2022-4-27
得分:0 
回复 8楼 jklqwe111
感谢您的回复,我按您的思路再研究下,谢谢!
2022-04-28 09:35



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-508956-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.225612 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved