基本上的功能都有了,可惜还是差了一点点,一直都没有拿出来。
QQ验证码的样本实在太多,该死的图片比较又不是很聪明,4个图片往往只能辨别出2,3个,甚至一个都认不出来。有空的时候自己去写个图片识别的来
不管怎样,还是先把这些脚本给整理出来了,期待有朝一日出来新的图片比较API,让该死的QQ验证码见鬼去吧
—————————————————-获取图片———————————————————————–
getImg= function()
local ele=wb:getEle(“temp”);–这是模拟程序web界面上的一个节点,用来显示程序运行过程的相关信息
tab={wb:eleImages()}; –枚举web页所有图片
img=image.new();
for i,tele in ipairs(tab) do
if tele:id()==’idtimage’ then –获取指定id的图片
tele:exec(“Copy”); –拷贝
img:getClipBD() ;–从粘贴板获取
end
end;
img:Crop(1,2,37,18);–修剪图片。查看下载下来的图片,不断微调。 每个验证码图片这个参数可能不同。
img2,img3,img4,img5=img:split(1,4); –分割图片
img:paint(100,100,40,20); –屏幕显示图片
img2:paint(100,120,10,20);
img3:paint(120,120,10,20);
img4:paint(140,120,10,20);
img5:paint(160,120,10,20);
img:save(“c:\\temp\\temp.png”);–把图片保存到本地
ele:setAttribute(“value”,”已从指定网址得到图像”);–在web界面上显示提示信息。
ele:setAttribute(“value”,”拆分并保存图像已经完成”);–在web界面上显示提示信息
return img;
end;
——————————得到样本图片并保存在数据岛的函数——————————————————————
sampleImg=function()
–遍历图片目录,读取样本图片
local tkey={};
win.enumProc = function(dir,filename)
if(not dir)then
tkey[string.sub(filename,9,10)]=string.sub(filename,9,14); –文件名形如c:\test\1a.jpg
end;
return nStop();
end;
win.enumDir(“c:\\test\\”,”*.jpg”) –显示该目录*.jpg文件
–k参数为键,v参数表示值 一个典型的tkeyle迭代器回调函数
loadtkey = function(k,v)
local img = image.new();
img:load(“C:\\test\\”..k..”.jpg”);
assert(img:ok(),”C:\\test\\”..k..”.jpg”..”\n不是有效的图片”);
img:bpp(1);
img:bpp(24);
–通过上面两句,轻松去掉验证码上的杂色杂点
img:Crop( 0 , 0 , 9 , 16);–修剪单个字符
img:median(2);–中值滤波进一步去杂点
tkey[k]= string.encode( img:getBytes(“*.jpg”) , “”);
–因为转换到字符串还是二进制,所以用base64进行编码
image.del(img);
end;
–遍历表tkey的所有元素,调用loadtkey加载图片文件
for k,v in pairs(tkey) do
loadtkey(k,v);
end;
–把所有图片保存到数据岛,
ape:saveTable(tkey,”验证码样本”)
end;
———————————————-把界面写入web窗体的函数——————————————————-
write= function()
html = [[
<html>
<head>
<meta http-equiv=”Content-Type” c>
<title>form</title>
</head>
<script> LAScript=external;;</script>
<body>
<form name=”form1″ method=”post” action=””>
<div id=”userdata” style=”display:none”></div><br><br>
<INPUT id=”loadstring” type=”button” value=”从指定网址得到图像”><img id=”idtimage” src=”http://verify.qq.com/getimage?0.9075894487369346″>
<br>
<br>
<INPUT id=”loadstring” type=”button” value=”保存样本图片到数据岛”>
<br>
<br>
<INPUT id=”loadstring” type=”button” value=”开始校验图片”>
<br>
<br>
这里显示程序运行过程相关信息:
<input id=”temp” type=”text” width=”100″>
</form>
</body>
</html>
]]
wb:go(“about:blank”);
delay(100)
wb:wait(“about”)
wb:write(html);
wb:setTitle(true);
wb:setScroll(true);
delay(1000)
wb:wait(“”)
wb:show(true);
end;
——————————————————————————————————————–
local timg = {}; –这是一个图像数组,用来储存还原后的验证码样本的图片数据
–必须进行一个转换,因为codekey里面只是base64编码的普通字符串,而timg 将是真正的图片对象(二进制数据)
———————————还原到图片对象————————————————————–
toImage = function(k,v)
local img = image.new();
local str = string.decode( v ,””);–首先进行base64解码,将纯文本转换为二进制数据
img:setBytes( str ,”*.jpg”);–将二进制数据还原为图像
timg[k] = img;
end;
———————————转换图片验证码到字符串的函数—————————————–
function ImgToString(img)
function test(imgX) –test是一个被包含在函数中的内部函数
sleep(0);
local limit = (60 * 20) + (60 * 20); –最小相似度 local关键字声明为局部变量
local chr = “A”; –读取的字符
–testimg是一个被包含在函数中的内部函数,作为table.foreach的回调函数,k参数表示键,v参数表示值
testimg = function(k,v)
–调用image.testXX()函数得出相似度,类似的函数还有image.testX() image.test()
local n = imgX:testXX(timg[k]); –就是这个“图片比较”太垃圾,不然就没有问题了,55555
if(n<limit)then –比较最小相似度
limit = n;
chr = k..””;
end;
end;
–遍历timg表,并调用testimg函数
for k,v in pairs(timg) do
testimg(k,v);
end;
return string.left(chr,1); –返回读取到的字符串首字符(如果每个字符有多个样本)
end;
–修剪图片
–image.Crop(img, 1 ,2 , 37 ,18 )
img:bpp(1);
img:bpp(24);
–上面的过程必须与下载样本时的代码完全一致。
–使用split函数分割图片
local img2,img3,img4,img5 = img:split(1,4);
win.messagePrint(“正在检测图片,请稍候….”);
return test(img2)..test(img3)..test(img4)..test(img5);
end;
———————————–输出辨认结果——————————————-
function showresult(str)
–下面我们把验证码的每个字符都转换为大写,并控制键盘顺序按键
code1 = string.upper( string.sub(str,1,1) );
code2 = string.upper( string.sub(str,2,2) );
code3 = string.upper( string.sub(str,3,3) );
code4 = string.upper( string.sub(str,4,4) );
win.consoleOpen()
print(code1);
print(code2);
print(code3);
print(code4);
end
———————————–主调用———————————————–
wb=web.new();
write();–构建页面
sampleImg();–读取图片样本
tkey = ape:loadTable(“验证码样本”);
for k,v in pairs(tkey) do –验证样本
toImage(k,v); –转换为图像
end;
img = getImg();–读取图片
showresult(ImgToString(img));