绿色风's Blog
专注AutoIT(Au3)
  • 首页
  • 流●年
  • 笔●记
    • 学习随记
    • 源码示例
  • 脚●本
    • UDF(收集)
    • 工作室UDF
    • 工具●教程
    • 教程之GDI
  • 作●品
  • 下●载
  • 情怀ExcelTip
4月142015

Au3[规则验证码]自动识别,并输出程序

作者:绿色风   发布:2015-4-14 13:42 Tuesday   分类:   阅读:9161次   评论:0条  

原创作者_ACN站:seniors 老师

1.JPG

看图就能明白,autoit v3 验证码自动识别



#include <WinAPIEx.au3>
#include <INet.au3>
#include <GDIPlusex.au3>
#include <Array.au3>
#include <Memory.au3>
#include <GUIConstantsEx.au3>
#include <WinAPI.au3>
#include <APIConstants.au3>
#include <WindowsConstants.au3>

Global $oldBitMap, $CaptchasArray, $hScaleBitmap, $DoneArray
Global $Scale = 4, $Coordinate = 20
;~ Global $LoginCaptchasUrl = "http://www.sbobet.com/zh-cn/resource/captcha/sign-in.jpg?634900445434772000"
;~ Global $LoginCaptchasUrl = "https://login.passport.9you.com/identifyingCode.jsp"
;~ Global $LoginCaptchasUrl = "http://captcha.sdo.com/fcgi-bin/show_img.fcgi?appid=112&session_key=TRs4HgQeATxE2cwB&gameid=112&areaid=0"
;~ Global $LoginCaptchasUrl = "http://www.dxqf10086.com/verifyimg.aspx"
Global $LoginCaptchasUrl = "http://jscs.fxl.teacheredu.cn/GuoPeiAdmin/Login/ImageLog.aspx"
Global $learnedCaptchas[1][1]
Global $learninput[6]
Global $left, $top, $zhong, $ziwidth, $ziHeight, $zishu, $Captchasclass = 10

$hGui = GUICreate("识别例子", 800, 400)

GUICtrlCreateGroup("验证码地址", 590, 5, 180, 45)
$InputCaptchasUrl = GUICtrlCreateInput($LoginCaptchasUrl, 600, 20, 160, 20)
GUICtrlCreateGroup("", -99, -99, 1, 1)

GUICtrlCreateGroup("放大验证码", 5, 5, 580, 255)
$Pic2 = GUICtrlCreatePic("", 20, 20, 500, 200)
Global $hPic2 = GUICtrlGetHandle(-1)
GUICtrlCreateGroup("", -99, -99, 1, 1)

GUICtrlCreateGroup("字型数据", 590, 60, 180, 110)
GUICtrlCreateLabel("左边空:", 600, 80)
GUICtrlCreateLabel("上边空:", 600, 110)
GUICtrlCreateLabel("字间空:", 600, 140)
GUICtrlCreateLabel("字符宽:", 680, 80)
GUICtrlCreateLabel("字符高:", 680, 110)
GUICtrlCreateLabel("字符数:", 680, 140)
$input1 = GUICtrlCreateInput("6", 650, 80, 20)
$input2 = GUICtrlCreateInput("5", 650, 110, 20)
$input3 = GUICtrlCreateInput("1", 650, 140, 20)
$input4 = GUICtrlCreateInput("8", 730, 80, 20)
$input5 = GUICtrlCreateInput("12", 730, 110, 20)
$input6 = GUICtrlCreateInput("4", 730, 140, 20)
GUICtrlCreateGroup("", -99, -99, 1, 1)

GUICtrlCreateGroup("验证码类型", 590, 180, 180, 80)
GUIStartGroup()
$radio1 = GUICtrlCreateRadio("仅数字", 600, 200)
$radio2 = GUICtrlCreateRadio("仅字母", 680, 200)
GUICtrlSetState(-1, $GUI_DISABLE)
$radio3 = GUICtrlCreateRadio("数字字母混合", 600, 230)
GUICtrlSetState(-1, $GUI_DISABLE)
GUICtrlSetState($radio1, $GUI_CHECKED)
GUICtrlCreateGroup("", -99, -99, 1, 1)

GUICtrlCreateGroup("原始验证码", 5, 270, 180, 80)
$Pic = GUICtrlCreatePic("", 20, 290, 50, 20)
Global $hPic = GUICtrlGetHandle(-1)
GUICtrlCreateGroup("", -99, -99, 1, 1)

GUICtrlCreateGroup("功能区", 190, 270, 580, 80)
$MedianFilter = GUICtrlCreateCheckbox("中值滤波", 200, 320, 60)
$TwoColors = GUICtrlCreateCheckbox("二色化", 280, 320, 60)
$DrawingBox = GUICtrlCreateCheckbox("画方框", 360, 320, 60)
$Study = GUICtrlCreateCheckbox("学习", 440, 320, 60)
$make = GUICtrlCreateButton("输出程序", 520, 320, 60)

GUIStartGroup()
$BGray = GUICtrlCreateRadio("蓝灰", 200, 290, 60)
$GGray = GUICtrlCreateRadio("绿灰", 280, 290, 60)
$RGray = GUICtrlCreateRadio("红灰", 360, 290, 60)
$AGray = GUICtrlCreateRadio("全灰", 440, 290, 60)
$NGray = GUICtrlCreateRadio("原色", 520, 290, 60)
GUICtrlSetState(-1, $GUI_CHECKED)
GUICtrlCreateGroup("", -99, -99, 1, 1)

GUISetState(@SW_SHOW)
showBitmap()
While 1
        $nMsg = GUIGetMsg()
        Switch $nMsg
                Case -3
                        GUIDelete()
                        quit()
                Case $Pic, $Pic2
                        showBitmap()
                Case $TwoColors, $DrawingBox, $BGray, $GGray, $RGray, $AGray, $NGray, $MedianFilter
                        $hScaleBitmap = ScaleImage()
                        SetPicBitmap($hPic2, $hScaleBitmap)
                Case $Study
                        learnCaptchas()
                Case $make
                        MakeAu3File()
        EndSwitch
WEnd

Func quit()

        Exit
EndFunc   ;==>quit

Func showBitmap()
        GetCaptchas()
        SetPicBitmap($hPic, $oldBitMap)
        $hScaleBitmap = ScaleImage()
        SetPicBitmap($hPic2, $hScaleBitmap)
        If BitAND(GUICtrlRead($Study), $GUI_CHECKED) Then whatnum()
EndFunc   ;==>showBitmap

Func SetPicBitmap($hPic, $hBitMap)
        Local $oldObj = _SendMessage($hPic, 0x0172, 0, $hBitMap)
        _WinAPI_DeleteObject($oldObj)
        Local $hObj = _SendMessage($hPic, 0x0173)
        If $hObj <> $hBitMap Then
                _WinAPI_DeleteObject($hBitMap)
        EndIf
        Return 1
EndFunc   ;==>SetPicBitmap

Func GetCaptchas()
;~      _INetGetSource(GUICtrlRead($InputCaptchasUrl), False)
        Local $bImage = _INetGetSource(GUICtrlRead($InputCaptchasUrl), False)
        Local $bData = Binary($bImage)
        Local $Lenght = BinaryLen($bData)
        Local $hData = _MemGlobalAlloc($Lenght, 0x0002)
        Local $pData = _MemGlobalLock($hData)
        Local $tData = DllStructCreate('byte[' & $Lenght & ']', $pData)
        DllStructSetData($tData, 1, $bData)
        _MemGlobalUnlock($hData)
        Local $pStream = _WinAPI_CreateStreamOnHGlobal($hData)
        _GDIPlus_Startup()
        Local $hImage = _GDIPlus_BitmapCreateFromStream($pStream)
        $CaptchasArray = CaptchasToArray($hImage)
        $oldBitMap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
        _GDIPlus_ImageDispose($hImage)
        _MemGlobalFree($hData)
        _GDIPlus_Shutdown()
        DllCall('psapi.dll', 'int', 'EmptyWorkingSet', 'hWnd', -1)
        Return 1
EndFunc   ;==>GetCaptchas

Func CaptchasToArray($hImage, $func_bg = 0xffffff)
        Local $BitmapData, $iwidth, $iheight, $Scan0, $pixelData, $s_BMPData, $i_Stride
        $iwidth = _GDIPlus_ImageGetWidth($hImage)
        $iheight = _GDIPlus_ImageGetHeight($hImage)
        $BitmapData = _GDIPlus_BitmapLockBits($hImage, 0, 0, $iwidth, $iheight, $GDIP_ILMREAD, $GDIP_PXF24RGB)
        $i_Stride = DllStructGetData($BitmapData, "Stride");Stride - Offset, in bytes, between consecutive scan lines of the bitmap. If the stride is positive, the bitmap is top-down. If the stride is negative, the bitmap is bottom-up.
        $Scan0 = DllStructGetData($BitmapData, "Scan0");Scan0 - Pointer to the first (index 0) scan line of the bitmap.
        $pixelData = DllStructCreate("ubyte lData[" & (Abs($i_Stride) * $iheight) & "]", $Scan0)
        ;不要使用官方论坛上提供的Abs($i_Stride) * $iheight-1,否则无法正确处理gif冗余等情形
        $s_BMPData = DllStructGetData($pixelData, "lData")
        $s_BMPData = StringTrimLeft($s_BMPData, 2);去掉头部"0x"
        DllCall('psapi.dll', 'int', 'EmptyWorkingSet', 'hWnd', -1)
        ;处理图片数组
        Local $a_return[$iwidth][$iheight], $x, $y, $s
        For $y = 0 To $iheight - 1
                $s = StringMid($s_BMPData, $y * ($i_Stride * 2) + 1, $iwidth * 6)
                For $x = 0 To $iwidth - 1
                        $a_return[$x][$y] = Number("0x" & StringMid($s, $x * 6 + 1, 6))
                Next
        Next
        Local $xScale = Int(510 / $iwidth)
        Local $yScale = Int(180 / $iheight)
        $Scale = $xScale
        If $xScale > $yScale Then $Scale = $yScale

        GUICtrlSetPos($Pic2, 20, 20, $iwidth * $Scale + $Coordinate * 2, $iheight * $Scale + $Coordinate * 2)
        GUICtrlSetPos($Pic, 20, 290, $iwidth, $iheight)
        Return $a_return
EndFunc   ;==>CaptchasToArray

Func ArrayTo2Color($aArray, $func_bg = 0x808080);对应的x808080是前背景阀值,这里只是简单的固定,如果这里修改了,对应输出程序中也要修改
        Local $iwidth = UBound($aArray), $iheight = UBound($aArray, 2)
        Local $a_return[$iwidth][$iheight]
;~      $func_bg = $aArray[1][1]
        For $y = 0 To $iheight - 1
                For $x = 0 To $iwidth - 1
                        If $aArray[$x][$y] < $func_bg Then
                                $a_return[$x][$y] = 0x0000FF
                        Else
                                $a_return[$x][$y] = 0xFFFFFF
                        EndIf
                Next
        Next
        Return $a_return
EndFunc   ;==>ArrayTo2Color

Func Medianfilter($aArray)
        Local $iwidth = UBound($aArray), $iheight = UBound($aArray, 2)
        Local $a_return[$iwidth][$iheight]
        Local $window[9], $min, $temp, $k
        For $y = 1 To $iheight - 2
                For $x = 1 To $iwidth - 2
                        $k = 0
                        For $i = $x - 1 To $x + 1
                                For $j = $y - 1 To $y + 1
                                        $window[$k] = $aArray[$i][$j]
                                        $k += 1
                                Next
                        Next
                        For $m = 0 To 4
                                $min = $m
                                For $n = $m + 1 To 8
                                        If $window[$n] < $window[$min] Then
                                                $min = $n
                                                $temp = $window[$m]
                                                $window[$m] = $window[$min]
                                                $window[$min] = $temp
                                        EndIf
                                Next
                        Next
                        $a_return[$x][$y] = $window[4]
                Next
        Next
        For $x = 0 To $iwidth - 1
                $a_return[$x][0] = $aArray[$x][0]
                $a_return[$x][$iheight - 1] = $aArray[$x][$iheight - 1]
        Next
        For $y = 0 To $iheight - 1
                $a_return[0][$y] = $aArray[0][$y]
                $a_return[$iwidth - 1][$y] = $aArray[$iwidth - 1][$y]
        Next
        Return $a_return
EndFunc   ;==>Medianfilter

Func Graycolor($aArray, $color = "all")
        Local $iwidth = UBound($aArray), $iheight = UBound($aArray, 2)
        Local $a_return[$iwidth][$iheight], $b, $g, $r, $ret
        $func_bg = $aArray[1][1]
        For $y = 0 To $iheight - 1
                For $x = 0 To $iwidth - 1
                        Switch $color
                                Case "blue"
                                        $b = BitAND(0xFF, BitShift($aArray[$x][$y], 16))
                                        $a_return[$x][$y] = BitOR(BitShift($b, -16), BitShift($b, -8), $b)
                                Case "green"
                                        $g = BitAND(0xFF, BitShift($aArray[$x][$y], 8))
                                        $a_return[$x][$y] = BitOR(BitShift($g, -16), BitShift($g, -8), $g)
                                Case "red"
                                        $r = BitAND(0xFF, $aArray[$x][$y])
                                        $a_return[$x][$y] = BitOR(BitShift($r, -16), BitShift($r, -8), $r)
                                Case "all"
                                        $b = BitAND(0xFF, BitShift($aArray[$x][$y], 16))
                                        $g = BitAND(0xFF, BitShift($aArray[$x][$y], 8))
                                        $r = BitAND(0xFF, $aArray[$x][$y])
                                        $ret = Int((30 * $r + $g * 59 + $b * 11) / 100)
                                        $b = BitAND(0xFF0000, BitShift($ret, -16))
                                        $g = BitAND(0x00FF00, BitShift($ret, -8))
                                        $r = $ret
                                        $a_return[$x][$y] = BitOR($b, $g, $r)
                        EndSwitch
                Next
        Next
        Return $a_return
EndFunc   ;==>Graycolor

Func pingjunColor($aArray)
        Local $iwidth = UBound($aArray), $iheight = UBound($aArray, 2)
        Local $sret
        For $y = 0 To $iheight - 1
                For $x = 0 To $iwidth - 1
                        $sret += Hex($aArray[$x][$y], 6)
                Next
        Next
        Return $sret = Int($sret / $iwidth / $iheight)
EndFunc   ;==>pingjunColor

Func DrawCoordinate($hMemDC, $iwidth, $iheight)
        For $i = 0 To $iwidth
                If Mod($i, 5) = 0 Then
                        _WinAPI_DrawLine($hMemDC, $Coordinate + $i * $Scale - 1, 10, $Coordinate + $i * $Scale - 1, $Coordinate - 1)
                Else
                        _WinAPI_DrawLine($hMemDC, $Coordinate + $i * $Scale - 1, 15, $Coordinate + $i * $Scale - 1, $Coordinate - 1)
                EndIf
                If Mod($i, 10) = 0 Then
                        _WinAPI_TextOut($hMemDC, $i * $Scale + 10, 0, $i)
                EndIf
        Next
        For $i = 0 To $iheight
                If Mod($i, 5) = 0 Then
                        _WinAPI_DrawLine($hMemDC, 10, $Coordinate + $i * $Scale - 1, $Coordinate - 1, $Coordinate + $i * $Scale - 1)
                Else
                        _WinAPI_DrawLine($hMemDC, 15, $Coordinate + $i * $Scale - 1, $Coordinate - 1, $Coordinate + $i * $Scale - 1)
                EndIf
                If Mod($i, 10) = 0 And $i <> 0 Then
                        _WinAPI_TextOut($hMemDC, 0, $i * $Scale + 10, $i)
                EndIf
        Next
EndFunc   ;==>DrawCoordinate

Func ScaleImage()
        $DoneArray = $CaptchasArray
        If BitAND(GUICtrlRead($BGray), $GUI_CHECKED) Then $DoneArray = Graycolor($DoneArray, "blue")
        If BitAND(GUICtrlRead($GGray), $GUI_CHECKED) Then $DoneArray = Graycolor($DoneArray, "green")
        If BitAND(GUICtrlRead($RGray), $GUI_CHECKED) Then $DoneArray = Graycolor($DoneArray, "red")
        If BitAND(GUICtrlRead($AGray), $GUI_CHECKED) Then $DoneArray = Graycolor($DoneArray, "all")

        If BitAND(GUICtrlRead($MedianFilter), $GUI_CHECKED) Then $DoneArray = Medianfilter($DoneArray)
        If BitAND(GUICtrlRead($TwoColors), $GUI_CHECKED) Then $DoneArray = ArrayTo2Color($DoneArray)
        Local $iwidth = UBound($DoneArray), $iheight = UBound($DoneArray, 2)
        Local $tRECT, $pRECT
        Local $hBrush
        Local $hDC = _WinAPI_GetDC(0)
        Local $hMemDC = _WinAPI_CreateCompatibleDC($hDC);建立兼容DC,即内存中的DC
        Local $hBitMap = _WinAPI_CreateCompatibleBitmapEx($hDC, $iwidth * $Scale + $Coordinate * 2, $iheight * $Scale + $Coordinate * 2, _
                        _WinAPI_SwitchColor(_WinAPI_GetSysColor($COLOR_3DFACE)));创建hBitmap
        Local $hSv = _WinAPI_SelectObject($hMemDC, $hBitMap);调入DC作图对象,即把图形画在$hBitmap上
        _WinAPI_SetBkMode($hMemDC, $TRANSPARENT)
        $tRECT = _WinAPI_CreateRect(0, 0, $iwidth * $Scale + $Coordinate * 2, $iheight * $Scale + $Coordinate * 2)
        $pRECT = DllStructGetPtr($tRECT)
        $hBrush = _WinAPI_CreateBrushIndirect($BS_SOLID, 0xEEEEEE, $HS_DIAGCROSS)
        _WinAPI_FillRect($hMemDC, $pRECT, $hBrush)
        _WinAPI_DeleteObject($hBrush)
        DrawCoordinate($hMemDC, $iwidth, $iheight)
        For $i = 0 To $iwidth - 1
                For $j = 0 To $iheight - 1
                        $tRECT = _WinAPI_CreateRect($i * $Scale + $Coordinate, $j * $Scale + $Coordinate, _
                                        ($i + 1) * $Scale + $Coordinate - 1, ($j + 1) * $Scale + $Coordinate - 1)
;~                                      ($i + 1) * $Scale + $Coordinate, ($j + 1) * $Scale + $Coordinate)
                        $pRECT = DllStructGetPtr($tRECT)
                        $hBrush = _WinAPI_CreateBrushIndirect($BS_SOLID, _WinAPI_SwitchColor($DoneArray[$i][$j]), $HS_DIAGCROSS)
                        _WinAPI_FillRect($hMemDC, $pRECT, $hBrush)
                        _WinAPI_DeleteObject($hBrush)
                Next
        Next
        If BitAND(GUICtrlRead($DrawingBox), $GUI_CHECKED) Then DrawLettlerRect($hMemDC, $iwidth, $iheight)
        _WinAPI_SelectObject($hMemDC, $hSv)
        _WinAPI_DeleteDC($hMemDC)
        _WinAPI_ReleaseDC(0, $hDC)
        Return $hBitMap
EndFunc   ;==>ScaleImage

Func DrawLettlerRect($hMemDC, $iwidth, $iheight)
        $left = GUICtrlRead($input1)
        $top = GUICtrlRead($input2)
        $zhong = GUICtrlRead($input3)
        $ziwidth = GUICtrlRead($input4)
        $ziHeight = GUICtrlRead($input5)
        $zishu = GUICtrlRead($input6)
        $hOldBrush = _WinAPI_SelectObject($hMemDC, _WinAPI_GetStockObject($NULL_BRUSH))
        For $i = 0 To $zishu - 1
                $tRECT = _WinAPI_CreateRect($Coordinate + ($left + $i * ($ziwidth + $zhong)) * $Scale - 1, _
                                $Coordinate + $top * $Scale - 1, _
                                $Coordinate + ($left + $ziwidth + $i * ($ziwidth + $zhong)) * $Scale - 1, _
                                $Coordinate + ($top + $ziHeight) * $Scale - 1)
                _WinAPI_Rectangle($hMemDC, $tRECT)
        Next
        _WinAPI_SelectObject($hMemDC, $hOldBrush)
EndFunc   ;==>DrawLettlerRect

Func learnCaptchas()
        If BitAND(GUICtrlRead($Study), $GUI_UNCHECKED) Then Return
        If BitAND(GUICtrlRead($DrawingBox), $GUI_UNCHECKED) Then
                GUICtrlSetState($Study, $GUI_UNCHECKED)
                MsgBox(0, "使用说明", "请先画方框,看是否能把字符全部区分开来!", -1, $hGui)
        Else
                $left = GUICtrlRead($input1)
                $top = GUICtrlRead($input2)
                $zhong = GUICtrlRead($input3)
                $ziwidth = GUICtrlRead($input4)
                $ziHeight = GUICtrlRead($input5)
                $zishu = GUICtrlRead($input6)
                If BitAND(GUICtrlRead($radio1), $GUI_CHECKED) Then $Captchasclass = 10
                If BitAND(GUICtrlRead($radio2), $GUI_CHECKED) Then $Captchasclass = 26
                If BitAND(GUICtrlRead($radio3), $GUI_CHECKED) Then $Captchasclass = 36
                ReDim $learnedCaptchas[$Captchasclass][$ziHeight]
                whatnum()
        EndIf

;~      Local $num, $ls = "", $lls = "", $aArray[$ziHeight]
;~      For $i = 0 To $zishu - 1
;~              $lls = ""
;~              For $y = $top To $top + $ziHeight - 1
;~                      $ls = ""
;~                      For $x = $left + $i * ($ziwidth + $zhong) To $left + $i * ($ziwidth + $zhong) + $ziwidth - 1
;~                              If $DoneArray[$x][$y] = 0xFFFFFF Then
;~                                      $ls &= "0"
;~                              Else
;~                                      $ls &= "1"
;~                              EndIf
;~                      Next
;~                      $aArray[$y - $top] = $ls
;~                      $ls &= '|'
;~                      $lls = $lls & $ls
;~              Next
;~              If waitInput($aArray, WhatNumber($lls)) = -1 Then ExitLoop
;~      Next
EndFunc   ;==>learnCaptchas

Func myArrayToString($aArray)
        Local $y = UBound($aArray), $ret = ""
        For $i = 1 To $y - 1
                $ret &= StringReplace($aArray[$i], "0", " ") & @CRLF
        Next
        Return $ret
EndFunc   ;==>myArrayToString

Func whatnum()
        Local $num = "", $ls = "", $lls = ""
        For $i = 0 To $zishu - 1
                $lls = ""
                For $y = $top To $top + $ziHeight - 1
                        $ls = ""
                        For $x = $left + $i * ($ziwidth + $zhong) To $left + $i * ($ziwidth + $zhong) + $ziwidth - 1
                                If $DoneArray[$x][$y] = 0xFFFFFF Then
                                        $ls &= "0"
                                Else
                                        $ls &= "1"
                                EndIf
                        Next
                        $ls &= '|'
                        $lls = $lls & $ls
                Next
                $num &= WhatNumber(StringTrimRight($lls, 1))
                $lls = ""
        Next
        MsgBox(0, "验证码结果", "这个验证码是:" & @CR & $num, -1, $hGui)
EndFunc   ;==>whatnum

Func WhatNumber($Sum)
        Local $checktotal, $aCheck = StringSplit($Sum, "|")
        For $i = 0 To $Captchasclass - 1
                $checktotal = 0
                For $j = 0 To $ziHeight - 1
                        If $learnedCaptchas[$i][$j] <> $aCheck[$j + 1] Then $checktotal += 1
                        If $checktotal > 1 Then ExitLoop
                Next
                If $checktotal < 2 Then Return $i
        Next
        Return waitInput($aCheck)
EndFunc   ;==>WhatNumber

Func waitInput($aArray, $sDefault = "")
        Do
                $num = InputBox("验证码学习", "请输入你所看到的验证码" & @CRLF & myArrayToString($aArray), $sDefault, " M1", _
                                300, 300, @DesktopWidth / 2 - 150, @DesktopHeight / 2 - 150, -1, $hGui)
                If @error Then Return -1
        Until StringLen($num) = 1
        For $j = 0 To $ziHeight - 1
                $learnedCaptchas[$num][$j] = $aArray[$j + 1]
        Next
        Return $num
EndFunc   ;==>waitInput

Func MakeAu3File()
        Local $ls
        If UBound($learnedCaptchas) = 1 Then
                MsgBox(0, "输出警告", "你还没有学习验证码的特征值!", -1, $hGui)
                Return
        EndIf
        For $i = 0 To UBound($learnedCaptchas) - 1
                If $learnedCaptchas[$i][0] = "" Then $ls &= $i
        Next
        If $ls <> "" Then
                MsgBox(0, "输出警告", "验证码特征" & $ls & "还没有学习到。" & @CRLF & "请点击图片更新验证码!", -1, $hGui)
                Return
        EndIf
        Local $hfile = FileOpen("自动输出程序.au3", 130)
        Local $include = '#include <INet.au3>' & @CRLF _
                         & '#include <GDIPlusex.au3>' & @CRLF _
                         & '#include <Array.au3>' & @CRLF _
                         & '#include <Memory.au3>' & @CRLF _
                         & ';0-9的数字值' & @CRLF
        Local $GuiCode = '$hGui = GUICreate("识别例子", 200, 60)' & @CRLF _
                         & '' & @CRLF _
                         & '$Pic1 = GUICtrlCreatePic("", 14, 10, 50, 20)' & @CRLF _
                         & 'Global $hPic = GUICtrlGetHandle(-1)' & @CRLF _
                         & '$Label1 = GUICtrlCreateLabel("点击我的上方", 14, 40, 80, 17)' & @CRLF _
                         & '' & @CRLF _
                         & 'GUISetState(@SW_SHOW)' & @CRLF _
                         & 'While 1' & @CRLF _
                         & '    $nMsg = GUIGetMsg()' & @CRLF _
                         & '    Switch $nMsg' & @CRLF _
                         & '            Case -3' & @CRLF _
                         & '                    GUIDelete()' & @CRLF _
                         & '                    Exit' & @CRLF _
                         & '            Case $Pic1' & @CRLF _
                         & '                    GUICtrlSetData($Label1, myYzmShibie($yzm))' & @CRLF _
                         & '    EndSwitch' & @CRLF _
                         & 'WEnd' & @CRLF _
                         & '' & @CRLF _
                         & 'Func myYzmShibie($URL, $func_bg = 0x808080)' & @CRLF _
                         & '    Local $BitmapData, $i_width, $i_height, $Scan0, $pixelData, $s_BMPData, $i_Stride' & @CRLF _
                         & '    _GDIPlus_Startup()' & @CRLF _
                         & '    ;获取图片' & @CRLF _
                         & '    $bImage = _INetGetSource($URL, False)' & @CRLF _
                         & '    $bData = Binary($bImage)' & @CRLF _
                         & '    $Lenght = BinaryLen($bData)' & @CRLF _
                         & '    $hData = _MemGlobalAlloc($Lenght, 0x0002)' & @CRLF _
                         & '    $pData = _MemGlobalLock($hData)' & @CRLF _
                         & '    $tData = DllStructCreate("byte[" & $Lenght & "]", $pData)' & @CRLF _
                         & '    DllStructSetData($tData, 1, $bData)' & @CRLF _
                         & '    _MemGlobalUnlock($hData)' & @CRLF _
                         & '    $pStream = _WinAPI_CreateStreamOnHGlobal($hData)' & @CRLF _
                         & '    $hImage = _GDIPlus_BitmapCreateFromStream($pStream)' & @CRLF _
                         & '    ;转换图片到pic控件显示' & @CRLF _
                         & '    $hBitMap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)' & @CRLF _
                         & '    ;把图片读入数组,来自阿福源码' & @CRLF _
                         & '    $i_width = _GDIPlus_ImageGetWidth($hImage)' & @CRLF _
                         & '    $i_height = _GDIPlus_ImageGetHeight($hImage)' & @CRLF _
                         & '    $BitmapData = _GDIPlus_BitmapLockBits($hImage, 0, 0, $i_width, $i_height, $GDIP_ILMREAD, $GDIP_PXF24RGB)' & @CRLF _
                         & '    $i_Stride = DllStructGetData($BitmapData, "Stride");Stride - Offset, in bytes, between consecutive scan lines of the bitmap. If the stride is positive, the bitmap is top-down. If the stride is negative, the bitmap is bottom-up.' & @CRLF _
                         & '    $Scan0 = DllStructGetData($BitmapData, "Scan0");Scan0 - Pointer to the first (index 0) scan line of the bitmap.' & @CRLF _
                         & '    $pixelData = DllStructCreate("ubyte lData[" & (Abs($i_Stride) * $i_height) & "]", $Scan0)' & @CRLF _
                         & '    ;不要使用官方论坛上提供的Abs($i_Stride) * $i_height-1,否则无法正确处理gif冗余等情形' & @CRLF _
                         & '    $s_BMPData = DllStructGetData($pixelData, "lData")' & @CRLF _
                         & '    $s_BMPData = StringTrimLeft($s_BMPData, 2);去掉头部"0x"' & @CRLF _
                         & '    _GDIPlus_ImageDispose($hImage)' & @CRLF _
                         & '    _MemGlobalFree($hData)' & @CRLF _
                         & '    _GDIPlus_Shutdown()' & @CRLF _
                         & '    ;设置到pic控件' & @CRLF _
                         & '    $oldObj = _SendMessage($hPic, 0x0172, 0, $hBitMap)' & @CRLF _
                         & '    _WinAPI_DeleteObject($oldObj)' & @CRLF _
                         & '    Local $hObj = _SendMessage($hPic, 0x0173)' & @CRLF _
                         & '    If $hObj <> $hBitMap Then' & @CRLF _
                         & '            _WinAPI_DeleteObject($hBitMap)' & @CRLF _
                         & '    EndIf' & @CRLF _
                         & '    DllCall("psapi.dll", "int", "EmptyWorkingSet", "hWnd", -1)' & @CRLF _
                         & '    ;处理图片数组' & @CRLF _
                         & '    Local $a_return[$i_width][$i_height], $x, $y, $s' & @CRLF _
                         & '    Local $ls = "", $lls = ""' & @CRLF _
                         & '    For $y = $top To $top + $ziHeight -1;5和4分别是图片上下的空边' & @CRLF _
                         & '            $s = StringMid($s_BMPData, $y * ($i_Stride * 2) + 1, $i_width * 6)' & @CRLF _
                         & '            For $x = $left To $left + $zishu * $ziWidth + ($zishu - 1) * $zhong - 1;6和9分别是图片左右的空边' & @CRLF _
                         & '                    $a_return[$x][$y] = Number("0x" & StringMid($s, $x * 6 + 1, 6))' & @CRLF

        $greenor = '                    $a_return[$x][$y] = Graycolor($a_return[$x][$y], "';'")' & @CRLF
        If BitAND(GUICtrlRead($BGray), $GUI_CHECKED) Then $greenor = $greenor & "blue" & '")' & @CRLF
        If BitAND(GUICtrlRead($GGray), $GUI_CHECKED) Then $greenor = $greenor & "green" & '")' & @CRLF
        If BitAND(GUICtrlRead($RGray), $GUI_CHECKED) Then $greenor = $greenor & "red" & '")' & @CRLF
        If BitAND(GUICtrlRead($AGray), $GUI_CHECKED) Then $greenor = $greenor & "all" & '")' & @CRLF
        If BitAND(GUICtrlRead($NGray), $GUI_CHECKED) Then $greenor = @CRLF
        $shibiCode = '                  If $a_return[$x][$y] < $func_bg Then' & @CRLF _
                         & '                            $a_return[$x][$y] = 1' & @CRLF _
                         & '                    Else' & @CRLF _
                         & '                            $a_return[$x][$y] = 0' & @CRLF _
                         & '                    EndIf' & @CRLF _
                         & '            Next' & @CRLF _
                         & '    Next' & @CRLF _
                         & '    Local $Number = ""' & @CRLF _
                         & '    For $i = 0 To $zishu - 1;读取4个数字的值' & @CRLF _
                         & '            $sx = $left + $ziWidth * $i + $zhong * $i;6是第一个数字的起点,每个数字占9列,第9列是空白列' & @CRLF _
                         & '            For $y = $top To $top + $ziHeight -1;5和4分别是图片上下的空边' & @CRLF _
                         & '                    $ls = ""' & @CRLF _
                         & '                    For $x = $sx To $sx + $ziWidth - 1;因为每个数字占9列,第9列是空白列,所以只读取8列' & @CRLF _
                         & '' & @CRLF _
                         & '                            If $a_return[$x][$y] = 1 Then' & @CRLF _
                         & '                                    $ls &= "1"' & @CRLF _
                         & '                            Else' & @CRLF _
                         & '                                    $ls &= "0"' & @CRLF _
                         & '                            EndIf' & @CRLF _
                         & '                    Next' & @CRLF _
                         & '                    $ls &= "|"' & @CRLF _
                         & '                    $lls = $lls & $ls' & @CRLF _
                         & '            Next' & @CRLF _
                         & '            $Number &= WhatNumber($lls)' & @CRLF _
                         & '            $lls = ""' & @CRLF _
                         & '    Next' & @CRLF _
                         & '    Return $Number' & @CRLF _
                         & 'EndFunc   ;==>myYzmShibie' & @CRLF _
                         & '' & @CRLF _
                         & 'Func WhatNumber($Sum)' & @CRLF _
                         & '    Local $checktotal, $aCheck = StringSplit($Sum, "|")' & @CRLF _
                         & '    For $i = 0 To 9 ;9是数字只有9个'  @CRLF _
                         & '            $checktotal = 0' & @CRLF _
                         & '            For $j = 0 To $ziHeight - 1' & @CRLF _
                         & '                    If $n[$i][$j] <> $aCheck[$j + 1] Then $checktotal += 1' & @CRLF _
                         & '                    If $checktotal > 1 Then ExitLoop' & @CRLF _
                         & '            Next' & @CRLF _
                         & '            If $checktotal < 2 Then Return $i' & @CRLF _
                         & '    Next' & @CRLF _
                         & '    Return -1' & @CRLF _
                         & 'EndFunc   ;==>WhatNumber' & @CRLF _
                         & '' & @CRLF _
                         & 'Func Graycolor($color, $style = "all")' & @CRLF _
                         & '    Local $a_return, $b, $g, $r, $ret' & @CRLF _
                         & '    Switch $style' & @CRLF _
                         & '            Case "blue"' & @CRLF _
                         & '                    $b = BitAND(0xFF, BitShift($color, 16))' & @CRLF _
                         & '                    $a_return = BitOR(BitShift($b, -16), BitShift($b, -8), $b)' & @CRLF _
                         & '            Case "green"' & @CRLF _
                         & '                    $g = BitAND(0xFF, BitShift($color, 8))' & @CRLF _
                         & '                    $a_return = BitOR(BitShift($g, -16), BitShift($g, -8), $g)' & @CRLF _
                         & '            Case "red"' & @CRLF _
                         & '                    $r = BitAND(0xFF, $color)' & @CRLF _
                         & '                    $a_return = BitOR(BitShift($r, -16), BitShift($r, -8), $r)' & @CRLF _
                         & '            Case "all"' & @CRLF _
                         & '                    $b = BitAND(0xFF, BitShift($color, 16))' & @CRLF _
                         & '                    $g = BitAND(0xFF, BitShift($color, 8))' & @CRLF _
                         & '                    $r = BitAND(0xFF, $color)' & @CRLF _
                         & '                    $ret = Int((30 * $r + $g * 59 + $b * 11) / 100)' & @CRLF _
                         & '                    $b = BitAND(0xFF0000, BitShift($ret, -16))' & @CRLF _
                         & '                    $g = BitAND(0x00FF00, BitShift($ret, -8))' & @CRLF _
                         & '                    $r = $ret' & @CRLF _
                         & '                    $a_return = BitOR($b, $g, $r)' & @CRLF _
                         & '    EndSwitch' & @CRLF _
                         & '    Return $a_return' & @CRLF _
                         & 'EndFunc   ;==>Graycolor' & @CRLF _
                         & '' & @CRLF
        $Const = '$yzm = "' & GUICtrlRead($InputCaptchasUrl) & '"' & @CRLF _
                         & '$left = ' & $left & @CRLF _
                         & '$top = ' & $top & @CRLF _
                         & '$zhong = ' & $zhong & @CRLF _
                         & '$ziWidth = ' & $ziwidth & @CRLF _
                         & '$ziHeight = ' & $ziHeight & @CRLF _
                         & '$zishu = ' & $zishu & @CRLF
        $ArrayCode = 'Global $n[10][$ziHeight] = [['
        For $i = 0 To 9
                For $j = 0 To $ziHeight - 1
                        $ArrayCode = $ArrayCode & '"' & $learnedCaptchas[$i][$j] & '"'
                        If $j < ($ziHeight - 1) Then
                                $ArrayCode &= ','
                        EndIf
                Next
                If $i < 9 Then
                        $ArrayCode &= '], _' & @CRLF & '['
                Else
                        $ArrayCode &= ']]' & @CRLF
                EndIf
        Next
        FileWrite($hfile, $include)
        FileWrite($hfile, $Const)
        FileWrite($hfile, $ArrayCode)
        FileWrite($hfile, $GuiCode)
        FileWrite($hfile, $greenor)
        FileWrite($hfile, $shibiCode)
        FileClose($hfile)
        MsgBox(0, "输出信息", "输出识别程序成功,文件名为" & @CRLF & "自动输出程序.au3", -1, $hGui)
        Return
EndFunc   ;==>MakeAu3File```
<br />




本文固定链接: http://www.jianyiit.com/post-93.html

blogger
该日志由 绿色风 于2015-4-14 13:42 Tuesday发表在 分类下。
版权所有:《绿色风's Blog》 → 《Au3[规则验证码]自动识别,并输出程序》;
除特别标注,本博客很多文章均为原创. 互联分享,尊重版权,转载请以链接形式标明本文地址;
本文标签:

扫描二维码,在手机上阅读
上一篇::阿拉伯数字转换成中文大写数字
下一篇:献给80后[逝去的青春]

热门文章

相关文章

  • Au3返回指定日期的国际标准(ISO)周数. 年度的第几周)
  • 根据自定义公式自动画图的强大工具
  • AU3版俄罗斯方块
  • Au3载入在线WEB网页音乐
  • autoit WebSocket示例WS协议
取消回复

发表评论

亲,头像对么?

67 + 49 =

提交中,请稍候……


木有头像就木JJ啦!还木有头像吗?点这里申请属于你的个性Gravatar头像吧!


    站点统计
    • 运行时间: 20228 天
    • 日志总数: 365 篇
    • 评论数量: 6210 条
    • 微语数量: 6 条
    • 附件总量: 388 件
  • 逝出的青春

  • 打赏"绿色风"



      扫码关注本站公众号 可搜本站内容

  • Autoit V3 脚本交流群

      常驻群1:905774875
      常驻群2:40672266


  • 链接

    • AU3中文论坛
    • Excel资料库
    • 完美者博客
    • 顺网小哥'S Blog
    • 猛牛哥的博客
    • 网吧系统下载
  • 分类

    • 流●年(66)
    • 笔●记(0)
    • 脚●本(0)
    • 作品(21)
    • 学习随记(51)
    • 源码示例(68)
    • UDF(收集)(26)
    • 工作室UDF(30)
    • 工具●教程(62)
    • 教程之GDI(24)
Copyright © 2013 绿色风's Blog. Powered by emlog. Theme by 射雕天龙. 鄂ICP备2021011689号-1 鄂公网安备42102302000078号 sitemap