ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
楼主: 蓝天630902

[分享] 验证码识别讲座

  [复制链接]

TA的精华主题

TA的得分主题

 楼主| 发表于 2012-8-8 21:21 | 显示全部楼层
本帖已被收录到知识树中,索引项:图像处理和GDI
本帖最后由 蓝天630902 于 2012-8-8 21:24 编辑
cumulonimbus 发表于 2012-8-8 21:03
太深啦,看得我就像掉进大海里一样哈


这样子说,不好理解,是吗?
看看下面的,有没有帮助:

BMP文件,其存储结构的格式可以在Windows中的WINGDI.h文件中找到定义。(可以到网上下载一个看看)
DIB 是标准的 Windows 位图格式,设备无关位图,BMP 文件包含了一个 DIB。一个 BMP 文件包括 4个部分:
1、位图文件头结构BITMAPFILEHEADER
2、位图信息头结构 BITMAPINFOHEADER
3、调色板 PALETTE
4、位图像素数据
在 WINGDI.h 中定义了前3 个结构(可以用WinHex.exe观察):

第一部分为位图文件头结构BITMAPFILEHEADER,其结构为:
typedef struct tagBITMAPFILEHEADER
{
WORD bfType;  //指定文件类型,必须是0x424D,即字符串“BM”,也就是说所有.bmp 文件的头两个字节都是“BM”。(占2字节)
DWORD bfSize;  //指定文件大小,包括这14 个字节。(占4字节)
WORD bfReserved1;  //为保留字,不用考虑。(占2字节)
WORD bfReserved2;  //为保留字,不用考虑。(占2字节)
DWORD bfOffBits;  //为从文件头到实际的位图数据的偏移字节数,也就是BMP 文件 4个部分中的前三个部分的长度之和。(占4字节)
} BITMAPFILEHEADER, FAR *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER
这个结构的长度是固定的,为14 个字节(WORD 为无符号16 位整数,DWORD 为无符号32 位整数)

第二部分为位图信息头BITMAPINFOHEADER,也是一个结构,其定义如下:
typedef struct tagBITMAPINFOHEADER
{
DWORD biSize;  //指定这个结构(位图信息头BITMAPINFOHEADER)的长度,为40,单位是字节。(占4字节)
LONG biWidth;  //指定图像的宽度,单位是像素。(占4字节)
LONG biHeight;  //指定图像的高度,单位是像素。(占4字节)
WORD biPlanes;  //必须是1。(占2字节)
WORD biBitCount ; //指定表示颜色时要用到的位数,常用的值为1(黑白二色图)、4(16 色图)、8(256 色)、24(真彩色图)新的.bmp格式支持32位色(占2字节)
DWORD biCompression;  //指定位图是否压缩,有效的值为BI_RGB,BI_RLE8,BI_RLE4,BI_BITFIELDS(都是一些Windows定义好的常量)。要说明的是,Windows 位图可以采用RLE4 和RLE8 的压缩格式,但用的不多。(占4字节)
DWORD biSizeImage;  //指定实际的位图数据占用的字节数,其实也可以从以下的公式中计算出来:biSizeImage=biWidth’× biHeight(=4×int((biWidth+3)/4)× biHeight) 要注意的是:上述公式中的biWidth’必须是4 的整倍数(所以不是biWidth,而是biWidth’,表示大于或等于biWidth 的、离4最近的整倍数。举个例子,如果biWidth=240,则biWidth’=240;如果biWidth=241,则biWidth’=244)。如果biCompression 为BI_RGB,则该项可能为零。(占4字节)
LONG biXPelsPerMeter;  //指定目标设备的水平分辨率,单位是每米的像素个数。(占4字节)
LONG biYPelsPerMeter;  //指定目标设备的垂直分辨率,单位同上。(占4字节)
DWORD biClrUsed;  //指定本图像实际用到的颜色数,如果该值为零,则用到的颜色数为2 的biBitCount 次方。(占4字节)
DWORD biClrImportant;  //指定本图像中重要的颜色数,如果该值为零,则认为所有的颜色都是重要的。(占4字节)
} BITMAPINFOHEADER;
这个结构的长度是固定的,为40 个字节(WORD 为无符号16 位整数,DWORD 无符号32 位整数,LONG 为32 位整数)

第三部分为调色板(Palette),当然,这里是对那些需要调色板的位图文件而言的。有些位图,如真彩色图,前面已经讲过,是不需要调色板的,BITMAPINFOHEADER 后直接是位图数据。调色板实际上是一个数组,共有biClrUsed 个元素(如果该值为零,则有2 的biBitCount 次方个元素)。数组中每个元素的类型是一个RGBQUAD 结构,占4 个字节,其定义如下:
typedef struct tagRGBQUAD
{
BYTE rgbBlue; //该颜色的蓝色分量(占1字节)
BYTE rgbGreen; //该颜色的绿色分量(占1字节)
BYTE rgbRed; //该颜色的红色分量(占1字节)
BYTE rgbReserved; //保留值(占1字节)
} RGBQUAD;

第四部分就是实际的图像数据了。对于用到调色板的位图,图像数据就是该像素值在调色板中的索引值,对于真彩色图,图像数据就是实际的R、G、B 值。下面对2 色、16 色、256 色位图和真彩色位图分别介绍。
对于2 色位图,用1 位就可以表示该像素的颜色(一般0 表示黑,1 表示白),所以一个字节可以表示8 个像素。
对于16 色位图,用4 位可以表示一个像素的颜色,所以一个字节可以表示2 个像素。
对于256 色位图,一个字节刚好可以表示1 个像素。
对于真彩色图,三个字节才能表示1 个像素。

注意:
1.每一行的字节数必须是4 的整倍数,如果不是,则需要补齐。这在前面介绍biSizeImage时已经提到了。
2.一般来说,BMP 文件的数据从下到上,从左到右。也就是说,从文件中最先读到的是图像最下面一行的左边第一个像素,然后是左边第二个像素;接下来是倒数第二行左边第一个像素,左边第二个像素;依次类推 ,最后得到的是最上面一行的最右一个像素。

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2012-8-8 21:22 | 显示全部楼层
你钻研完BMP,还有JPG、GIF、PNG、TIF无数格式等着你呢

其实如果仅仅是做验证码识别的话,用GDI库的API是最简单的方法,无需知道图片的具体格式就可以转成像素的RGB数组,

处理RGB数组,才是最通用的方法。

TA的精华主题

TA的得分主题

 楼主| 发表于 2012-8-8 21:29 | 显示全部楼层
liucqa 发表于 2012-8-8 21:22
你钻研完BMP,还有JPG、GIF、PNG、TIF无数格式等着你呢

其实如果仅仅是做验证码识别的话,用GDI库的API是 ...

在40楼已经说过:
用GetClipboardData(8)方法,所得到的数据,是设备无关位图数据,即我们通常所见到的BMP文件存储结构的格式。任何格式的图片,Copy后,用GetClipboardData(8)方法,都得到BMP格式。
所以不必研究“JPG、GIF、PNG、TIF”等等文件。

TA的精华主题

TA的得分主题

发表于 2012-8-8 21:32 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
蓝天630902 发表于 2012-8-8 21:29
在40楼已经说过:
用GetClipboardData(8)方法,所得到的数据,是设备无关位图数据,即我们通常所见到的B ...

你这个离不开剪贴板和IE,实际应用起来经常会受限的。

TA的精华主题

TA的得分主题

 楼主| 发表于 2012-8-8 21:41 | 显示全部楼层
本帖最后由 蓝天630902 于 2012-8-8 23:07 编辑
liucqa 发表于 2012-8-8 21:32
你这个离不开剪贴板和IE,实际应用起来经常会受限的。


问题在于,可以确保得到BMP格式数据,和同步得到BMP数据,同步是很重要的。
比如说,下面的代码也能得到图片数据,但不能同步得到数据,也不能保证是bmp格式,当然BMP不是主要的。
仅仅是得到数据下面的代码,也应该有效:

Sub 读取图片()
    Dim arr() As Byte
    With CreateObject("Microsoft.XMLHTTP")
        .Open "GET", "http://www.zjadc.com/ADCCSSPortal/ValidateCode/generatevalidatecode.aspx", False
        .Send
        arr = .responseBody
    End With
    For i = 0 To UBound(arr)
        Cells(i + 1, 1) = arr(i)
    Next i
    Erase arr()          '清空数组,释放内存
End Sub

TA的精华主题

TA的得分主题

发表于 2012-8-8 22:03 | 显示全部楼层
本帖最后由 cumulonimbus 于 2012-8-8 22:30 编辑
蓝天630902 发表于 2012-8-8 20:04
其实这个应该是非常简单的事,就是数组里面的数相加:
1、如果是有调色板,就从第bfOffBits字节(其实是第 ...


这段话我看了三遍,还是弄不懂
        For i = 1 To a2 * a3
            arr(i) = 1
            ts = 0
            For j = 0 To a5 - 1
                ts = ts + Val(bytClipData((i - 1) * a5 + a1 + j))
            Next j
            ts = ts / a5
            If ts > 200 Then
                arr(i) = ""
            End If
        Next i
这段中ts > 200 ,这个200数字是如何得出来的?可否有个简单的算法?
希望得到兄弟的程序算法。

TA的精华主题

TA的得分主题

发表于 2012-8-8 22:21 | 显示全部楼层
本帖最后由 引子玄 于 2012-8-8 22:41 编辑

蓝天大师这么认真仔细的辅导抓图片的人,真不容易,很难得{:soso_e179:}值得其他人学习

大师这么辛苦指点求问的人,连鲜花都不送,汗、、、、、、

TA的精华主题

TA的得分主题

 楼主| 发表于 2012-8-8 22:50 | 显示全部楼层
cumulonimbus 发表于 2012-8-8 22:03
这段话我看了三遍,还是弄不懂
        For i = 1 To a2 * a3
            arr(i) = 1

其实算法都已经给出了,我估计你没有认真看“BMP格式说明.xlsm”

如果需要的点的ts是200以下,而不需要的点的ts在200以上,那么我们就用ts > 200 来过滤他们。

所以,这个200是随着问题的不同,肯定会取不同的值。

TA的精华主题

TA的得分主题

 楼主| 发表于 2012-8-8 22:53 | 显示全部楼层
引子玄 发表于 2012-8-8 22:21
蓝天大师这么认真仔细的辅导抓图片的人,真不容易,很难得值得其他人学习

大师这么辛苦指点 ...

清风_ll 大师给了我 + 50 财富、+ 2技术,我都感到惶恐。谢谢清风_ll 大师

TA的精华主题

TA的得分主题

发表于 2012-8-8 23:35 | 显示全部楼层
蓝天630902 发表于 2012-8-8 21:41
问题在于,可以确保得到BMP格式数据,和同步得到BMP数据,同步是很重要的。
比如说,下面的代码 ...

你不能用ie打开页面,然后再用xmlhttp,这样肯定不行。

只用xmlhttp就行了,换句话说,确保randcode的链接只访问一次
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-12-4 16:30 , Processed in 0.050974 second(s), 6 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表