ioa747 Posted February 18 Posted February 18 (edited) first of all i would like to thank @Danyfirex for this wonderful UWPOCR UDF that he offers us I noticed that when you perform OCR from a small area of the screen, it doesn't recognize it normally and can't read from it. and so I proceeded to these functions. Which work as I expected, However, I have no experience with GDIPlus. I post them, to share it with the community, and to get some hint, advice. In the example below I'm targeting the date on the bottom right of the taskbar, I have a 1920*1080 screen and 100% scale expandcollapse popup; https://www.autoitscript.com/forum/topic/211521-ocr-from-a-small-area/?do=findComment&comment=1530475 #AutoIt3Wrapper_Run_Debug_Mode=Y #include <GDIPlus.au3> #include <GUIConstantsEx.au3> #include <ScreenCapture.au3> #include <WindowsConstants.au3> #include "UWPOCR.au3" ; * <-"https://www.autoitscript.com/forum/topic/207324-uwpocr-windows-platform-optical-character-recognition-api-implementation" _Example() ;-------------------------------------------------------------------------------------------------------------------------------- Func _Example() Local $sImageResult, $sOCRTextResult ; 1) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; From my monitor capture the date of the tskbar = 1808, 1062, 1862, 1074 $sImageResult = _ScreenCapture(@ScriptDir & "\tmp_OCR_image.png", 1808, 1062, 1862, 1074) ConsoleWrite("$sImageResult=" & $sImageResult & @CRLF) ; reading text from $sImageResult $sOCRTextResult = _UWPOCR_GetText($sImageResult) ConsoleWrite("- 1) OCR Result=" & $sOCRTextResult & @CRLF) ShellExecuteWait($sImageResult) ; 2) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; capture the date and give a border with 20 pixels = 1808, 1062, 1862, 1074, 0, 20 $sImageResult = _ScreenCapture(@ScriptDir & "\tmp_OCR_image.png", 1808, 1062, 1862, 1074, 0, 20) ; reading text from $sImageResult $sOCRTextResult = _UWPOCR_GetText($sImageResult) ConsoleWrite("- 2) OCR Result=" & $sOCRTextResult & @CRLF) ShellExecuteWait($sImageResult) ; 3) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; capture the date, give a border with 20 pixels, and invert colors = 1808, 1062, 1862, 1074, 1, 20 $sImageResult = _ScreenCapture(@ScriptDir & "\tmp_OCR_image.png", 1808, 1062, 1862, 1074, 1, 20) ; reading text from $sImageResult $sOCRTextResult = _UWPOCR_GetText($sImageResult) ConsoleWrite("- 3) OCR Result=" & $sOCRTextResult & @CRLF) ShellExecuteWait($sImageResult) ; 4) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; and the same from memory ConsoleWrite("Delete tmp_OCR_image=" & FileDelete($sImageResult) & @CRLF) $sOCRTextResult = _GetText(1808, 1062, 1862, 1074, 1, 20) ConsoleWrite("- 4) OCR Result=" & $sOCRTextResult & @CRLF) EndFunc ;==>_Example ; #FUNCTION# -------------------------------------------------------------------------------------------------------------------- ; Name...........: _ScreenCapture ; Description ...: Captures a region of the screen ; Syntax.........: _ScreenCapture($sFileName [, $iLeft = 0 [, $iTop = 0 [, $iRight = -1 [, $iBottom = -1 [, $iNegative = 0 [, $iBorder = 0 [, $dScale = 1 [, $iBrightness = 0 [, $iContrast = 0]]]]]]]]]) ; Parameters ....: $sFileName Full path and extension of the image file ; $iLeft [optional] X coordinate of the upper left corner of the rectangle ; $iTop [optional] Y coordinate of the upper left corner of the rectangle ; $iRight [optional] X coordinate of the lower right corner of the rectangle. If this is -1, the current screen width will be used ; $iBottom [optional] Y coordinate of the lower right corner of the rectangle. If this is -1, the current screen height will be used. ; $iNegative [optional] 1 = Negative color, 0 = Normal color ; $iBorder [optional] Draw a border araunt, The color is taken from first pixel ; $dScale [optional] Scale factor ; $iBrightness [optional] Integer in the range -255 through 255 that specifies the brightness level. ; $iContrast [optional] Integer in the range -100 through 100 that specifies the contrast level. ; Return value...: Filepath of the image If the image is successfully saved. ; False If the image is Not successfully saved. ; ; Author ........: ; Notes .........: ;-------------------------------------------------------------------------------------------------------------------------------- Func _ScreenCapture($sFileName, $iLeft = 0, $iTop = 0, $iRight = -1, $iBottom = -1, $iNegative = 0, $iBorder = 0, $dScale = 1, $iBrightness = 0, $iContrast = 0) Local $hHBitmap, $hBitmap, $hGDIPlusBitmap, $hImage, $hImageCtxt, $vRet, $iBmpW, $iBmpH, $iBorderColor _GDIPlus_Startup() $hHBitmap = _ScreenCapture_Capture("", $iLeft, $iTop, $iRight, $iBottom, False) If @error Then Return SetError(1, 0, False) Local $tSIZE = _WinAPI_GetBitmapDimension($hHBitmap) $iBmpW = $dScale * DllStructGetData($tSIZE, 'X') $iBmpH = $dScale * DllStructGetData($tSIZE, 'Y') ;Default ;$iFlags=0,$iIlluminant=0,$iGammaR=10000,$iGammaG=10000,$iGammaB=10000,$iBlack=0,$iWhite=10000,$iContrast=0,$iBrightness=0,$iColorfulness=0,$iTint=0 Local $iIlluminant = 0, $iGammaR = 10000, $iGammaG = 10000, $iGammaB = 10000, $iBlack = 0, $iWhite = 10000, $iColorfulness = 0, $iTint = 0 Local $tAdj = 0 $tAdj = _WinAPI_CreateColorAdjustment($iNegative, $iIlluminant, $iGammaR, $iGammaG, $iGammaB, $iBlack, $iWhite, $iContrast, $iBrightness, $iColorfulness, $iTint) $hBitmap = _WinAPI_AdjustBitmap($hHBitmap, $iBmpW, $iBmpH, $HALFTONE, $tAdj) If @error Then Return SetError(2, 0, False) $hGDIPlusBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap) ; Add Border If $iBorder > 0 Then $iBorderColor = _GDIPlus_BitmapGetPixel($hGDIPlusBitmap, 1, 1) ;get pixel color from 1,1 $hImage = _GDIPlus_BitmapCreateFromScan0($iBmpW + (2 * $iBorder), $iBmpH + (2 * $iBorder)) ;create an empty bitmap If @error Then Return SetError(3, 0, False) $hImageCtxt = _GDIPlus_ImageGetGraphicsContext($hImage) ;get the graphics context of the bitmap _GDIPlus_GraphicsSetSmoothingMode($hImageCtxt, $GDIP_SMOOTHINGMODE_HIGHQUALITY) _GDIPlus_GraphicsClear($hImageCtxt, $iBorderColor) ;clear bitmap with color white _GDIPlus_GraphicsDrawImage($hImageCtxt, $hGDIPlusBitmap, $iBorder, $iBorder) _GDIPlus_ImageDispose($hGDIPlusBitmap) Else $hImage = $hGDIPlusBitmap EndIf $vRet = _GDIPlus_ImageSaveToFile($hImage, $sFileName) ;save bitmap to disk If @error Then Return SetError(4, 0, False) If $vRet Then $vRet = $sFileName ; Cleanup resources _WinAPI_DeleteObject($hBitmap) _WinAPI_DeleteObject($hHBitmap) _GDIPlus_BitmapDispose($hImage) _GDIPlus_BitmapDispose($hGDIPlusBitmap) _GDIPlus_GraphicsDispose($hImageCtxt) _GDIPlus_Shutdown() Return $vRet EndFunc ;==>_ScreenCapture ; #FUNCTION# -------------------------------------------------------------------------------------------------------------------- ; Name...........: _GetText ; Description ...: reading text from a region of the screen ; Syntax.........: _GetText([$iLeft = 0 [, $iTop = 0 [, $iRight = -1 [, $iBottom = -1 [, $iNegative = 0 [, $iBorder = 0 [, $dScale = 1 [, $iBrightness = 0 [, $iContrast = 0 [, $sLanguageTagToUse = Default [, $bUseOcrLine = False]]]]]]]]]]]) ; Parameters ....: $iLeft [optional] X coordinate of the upper left corner of the rectangle ; $iTop [optional] Y coordinate of the upper left corner of the rectangle ; $iRight [optional] X coordinate of the lower right corner of the rectangle. If this is -1, the current screen width will be used ; $iBottom [optional] Y coordinate of the lower right corner of the rectangle. If this is -1, the current screen height will be used. ; $iNegative [optional] 1 = Negative color, 0 = Normal color ; $iBorder [optional] Draw a border araunt, The color is taken from first pixel ; $dScale [optional] Scale factor ; $iBrightness [optional] Integer in the range -255 through 255 that specifies the brightness level. ; $iContrast [optional] Integer in the range -100 through 100 that specifies the contrast level. ; $sLanguageTagToUse [optional] Gets the language being used for text recognition ; $bUseOcrLine [optional] Represents a single line of text recognized by the OCR engine and returned as part of the OcrResult. ; Return value...: Success: Contains the results of Optical Character Recognition (OCR). ; Failure: "" Empty String otherwise. ; On Error: false ; ; Author ........: ; Notes .........: ;-------------------------------------------------------------------------------------------------------------------------------- Func _GetText($iLeft = 0, $iTop = 0, $iRight = -1, $iBottom = -1, $iNegative = 0, $iBorder = 0, $dScale = 1, $iBrightness = 0, $iContrast = 0, $sLanguageTagToUse = Default, $bUseOcrLine = False) Local $hHBitmap, $hBitmap, $hGDIPlusBitmap, $hImage, $hImageCtxt, $sOCRTextResult, $iBmpW, $iBmpH, $iBorderColor _GDIPlus_Startup() $hHBitmap = _ScreenCapture_Capture("", $iLeft, $iTop, $iRight, $iBottom, False) If @error Then Return SetError(1, 0, False) Local $tSIZE = _WinAPI_GetBitmapDimension($hHBitmap) $iBmpW = $dScale * DllStructGetData($tSIZE, 'X') $iBmpH = $dScale * DllStructGetData($tSIZE, 'Y') ;Default ;$iFlags=0,$iIlluminant=0,$iGammaR=10000,$iGammaG=10000,$iGammaB=10000,$iBlack=0,$iWhite=10000,$iContrast=0,$iBrightness=0,$iColorfulness=0,$iTint=0 Local $iIlluminant = 0, $iGammaR = 10000, $iGammaG = 10000, $iGammaB = 10000, $iBlack = 0, $iWhite = 10000, $iColorfulness = 0, $iTint = 0 Local $tAdj = 0 $tAdj = _WinAPI_CreateColorAdjustment($iNegative, $iIlluminant, $iGammaR, $iGammaG, $iGammaB, $iBlack, $iWhite, $iContrast, $iBrightness, $iColorfulness, $iTint) $hBitmap = _WinAPI_AdjustBitmap($hHBitmap, $iBmpW, $iBmpH, $HALFTONE, $tAdj) If @error Then Return SetError(2, 0, False) $hGDIPlusBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap) ; Add Border If $iBorder > 0 Then $iBorderColor = _GDIPlus_BitmapGetPixel($hGDIPlusBitmap, 1, 1) ;get pixel color from 1,1 $hImage = _GDIPlus_BitmapCreateFromScan0($iBmpW + (2 * $iBorder), $iBmpH + (2 * $iBorder)) ;create an empty bitmap If @error Then Return SetError(3, 0, False) $hImageCtxt = _GDIPlus_ImageGetGraphicsContext($hImage) ;get the graphics context of the bitmap _GDIPlus_GraphicsSetSmoothingMode($hImageCtxt, $GDIP_SMOOTHINGMODE_HIGHQUALITY) _GDIPlus_GraphicsClear($hImageCtxt, $iBorderColor) ;clear bitmap with color white _GDIPlus_GraphicsDrawImage($hImageCtxt, $hGDIPlusBitmap, $iBorder, $iBorder) _GDIPlus_ImageDispose($hGDIPlusBitmap) Else $hImage = $hGDIPlusBitmap EndIf $sOCRTextResult = _UWPOCR_GetText($hImage, $sLanguageTagToUse, $bUseOcrLine) If @error Then Return SetError(4, 0, False) ; Cleanup resources _WinAPI_DeleteObject($hBitmap) _WinAPI_DeleteObject($hHBitmap) _GDIPlus_BitmapDispose($hImage) _GDIPlus_BitmapDispose($hGDIPlusBitmap) _GDIPlus_GraphicsDispose($hImageCtxt) _GDIPlus_Shutdown() Return $sOCRTextResult EndFunc ;==>_GetText ;-------------------------------------------------------------------------------------------------------------------------------- Thank you very much Edited November 21 by ioa747 better cleaning resources Hashim and Danyfirex 2 I know that I know nothing
Hashim Posted October 29 Posted October 29 Hi, thanks for this, it took me a while to wrap my head around what the code is doing and how to use it but I can confirm your custom functions add some much-needed configuration to UWPOPR. Unfortunately even after trying all sorts of scaling, contrast and brightness I'm still unable to get the numbers I need from the attached image. Is this expected (maybe cause of the font, or just because OCR on numbers is harder?) and if so, do you know of a solution that would work on an image like this, and maybe even one that hasn't been scaled up 3x?
Hashim Posted October 29 Posted October 29 Scratch that, I managed to solve this moments after posting, could a moderator please delete my posts?
Hashim Posted October 29 Posted October 29 Thanks so much for this, it adds some much-needed configuration options to UWPOCR and I can confirm it works! ioa747 1
ioa747 Posted October 30 Author Posted October 30 (edited) difficult pattern for OCR program but it has an easy pattern i played with it a bit here are the results expandcollapse popup#AutoIt3Wrapper_UseX64=N ;Update to Version: 2.0 #include <WindowsConstants.au3> #include <ScreenCapture.au3> #include <Array.au3> #include <File.au3> #include <Misc.au3> Opt("TrayIconDebug", 1) ;0=no info, 1=debug line info ; Initialization DllCall("user32.dll", "bool", "SetProcessDpiAwarenessContext", "int", -4) ; -4=PerMonitorAwareV2 Global $hDLL = DllOpen("user32.dll") HotKeySet("{END}", "_Main") ; * <- selection of outer area with margin HotKeySet("{ESC}", "_Exit") ;************************************************ While 1 Sleep(100) WEnd ;************************************************ ;-------------------------------------------------------------------------------------------------------------------------------- Func _Exit() DllClose($hDLL) Exit EndFunc ;==>_Exit ;-------------------------------------------------------------------------------------------------------------------------------- Func _Main() ; Main Program ; $aArea = [18, 181, 182, 434] Local $aArea = SelectArea() ; Define the area to scan Local $hColor = 0x00FF00 ; Capture the color map for the specified area Local $aColorMap = CaptureAreaColorMap($aArea) ;_ArrayDisplay($aColorMap) Local $Result = FindNumberUsingColorMap($aColorMap, $hColor) MsgBox($MB_SYSTEMMODAL, "$Result", $Result) EndFunc ;==>_Main ;-------------------------------------------------------------------------------------------------------------------------------- Func CaptureAreaColorMap($aArea) ; Initialize GDI+ to work with bitmaps _GDIPlus_Startup() ; Capture the screen area as a bitmap Local $hBitmap = _ScreenCapture_Capture("", $aArea[0], $aArea[1], $aArea[2], $aArea[3]) ; Convert the captured bitmap to a GDI+ bitmap Local $hGDIPlusBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap) ; Get the width and height of the captured area Local $width = $aArea[2] - $aArea[0] Local $height = $aArea[3] - $aArea[1] ; Create an array to store color values Local $aColorMap[$width][$height] ; Loop through each pixel in the bitmap and retrieve its color For $y = 0 To $height - 1 For $x = 0 To $width - 1 ; Get the pixel color from the bitmap in ARGB format Local $argbColor = _GDIPlus_BitmapGetPixel($hGDIPlusBitmap, $x, $y) ; Convert ARGB to BGR for comparison (ignore the alpha channel) Local $bgrColor = BitAND($argbColor, 0x00FFFFFF) $aColorMap[$x][$y] = $bgrColor Next Next ; Cleanup resources _GDIPlus_BitmapDispose($hGDIPlusBitmap) _WinAPI_DeleteObject($hBitmap) _GDIPlus_Shutdown() Return $aColorMap EndFunc ;==>CaptureAreaColorMap ;-------------------------------------------------------------------------------------------------------------------------------- Func FindNumberUsingColorMap($aColorMap, $hColor = 0x00FF00) Local $width = UBound($aColorMap, 1) Local $height = UBound($aColorMap, 2) Local $firstRow = -1, $lastRow = -1, $firstCol = -1, $lastCol = -1, $blockWidth = 0 ; Scan for the first and last rows and columns with green pixels For $y = 0 To $height - 1 For $x = 0 To $width - 1 If $aColorMap[$x][$y] = $hColor Then If $firstRow = -1 Then $firstRow = $y $lastRow = $y If $firstCol = -1 Or $x < $firstCol Then $firstCol = $x If $lastCol = -1 Or $x > $lastCol Then $lastCol = $x EndIf Next Next If $firstRow = -1 Or $lastRow = -1 Or $firstCol = -1 Or $lastCol = -1 Then MsgBox($MB_SYSTEMMODAL, "LineNumber:" & @ScriptLineNumber, "No color found" & @TAB & @TAB) Exit EndIf ; Calculate block size for one digit For $x = $firstCol To $width - 1 For $y = $firstRow To $height - 1 If $aColorMap[$x][$y] = $hColor Then For $w = $x To $width - 1 If $aColorMap[$w][$y] = $hColor Then $blockWidth += 1 Else ExitLoop 3 EndIf Next EndIf Next Next $blockSize = $blockWidth / 2 ; Adjust based on actual digit width Local $numberWidth = 14 * $blockSize ; Adjust based on number of columns per digit Local $numberSpace = 2 * $blockSize ; Space between digits Local $numberStart = $firstCol Local $aNum[11][3] ; Define boundaries for each number position For $i = 1 To 10 $aNum[$i][0] = $numberStart $aNum[$i][1] = $numberStart + $numberWidth If $numberStart + $numberWidth + $numberSpace > $lastCol Then ExitLoop $numberStart += $numberWidth + $numberSpace $aNum[0][0] = $i + 1 Next Local $sNumber ; Generate patterns for each found number For $i = 1 To $aNum[0][0] Local $sPattern = "" For $y = $firstRow To $lastRow For $x = $aNum[$i][0] To $aNum[$i][1] - 1 If $aColorMap[$x][$y] = $hColor Then $sPattern &= "1" Else $sPattern &= "." EndIf Next $sPattern &= @CRLF Next $sNumber &= _GetNumber($sPattern) Next ; each number Display is a matrix of 14x20 Vpoint ; each Vpoint is a 3x3 pixel ; each number Display is 42x60 pixel ConsoleWrite("Display_boundaries firstRow:" & $firstRow & " lastRow:" & $lastRow & " firstCol:" & $firstCol & " lastCol:" & $lastCol & @CRLF) Return $sNumber EndFunc ;==>FindNumberUsingColorMap ;-------------------------------------------------------------------------------------------------------------------------------- Func _GetNumber($sPattern) ConsoleWrite("############### $sPattern ################" & @CRLF & $sPattern & @CRLF) Local $aNumber[10] ; Define simplified patterns for each digit $aNumber[0] = "" ; Pattern for '0' $aNumber[0] &= ".........111111...111111...111111........." & @CRLF $aNumber[0] &= ".........111111...111111...111111........." & @CRLF $aNumber[0] &= ".........111111...111111...111111........." & @CRLF $aNumber[0] &= ".........111111...111111...111111........." & @CRLF $aNumber[0] &= ".........111111...111111...111111........." & @CRLF $aNumber[0] &= ".........111111...111111...111111........." & @CRLF $aNumber[0] &= ".........................................." & @CRLF $aNumber[0] &= ".........................................." & @CRLF $aNumber[0] &= ".........................................." & @CRLF $aNumber[0] &= "111111..............................111111" & @CRLF $aNumber[0] &= "111111..............................111111" & @CRLF $aNumber[0] &= "111111..............................111111" & @CRLF $aNumber[0] &= "111111..............................111111" & @CRLF $aNumber[0] &= "111111..............................111111" & @CRLF $aNumber[0] &= "111111..............................111111" & @CRLF $aNumber[0] &= ".........................................." & @CRLF $aNumber[0] &= ".........................................." & @CRLF $aNumber[0] &= ".........................................." & @CRLF $aNumber[0] &= "111111.....................111111...111111" & @CRLF $aNumber[0] &= "111111.....................111111...111111" & @CRLF $aNumber[0] &= "111111.....................111111...111111" & @CRLF $aNumber[0] &= "111111.....................111111...111111" & @CRLF $aNumber[0] &= "111111.....................111111...111111" & @CRLF $aNumber[0] &= "111111.....................111111...111111" & @CRLF $aNumber[0] &= ".........................................." & @CRLF $aNumber[0] &= ".........................................." & @CRLF $aNumber[0] &= ".........................................." & @CRLF $aNumber[0] &= "111111............111111............111111" & @CRLF $aNumber[0] &= "111111............111111............111111" & @CRLF $aNumber[0] &= "111111............111111............111111" & @CRLF $aNumber[0] &= "111111............111111............111111" & @CRLF $aNumber[0] &= "111111............111111............111111" & @CRLF $aNumber[0] &= "111111............111111............111111" & @CRLF $aNumber[0] &= ".........................................." & @CRLF $aNumber[0] &= ".........................................." & @CRLF $aNumber[0] &= ".........................................." & @CRLF $aNumber[0] &= "111111...111111.....................111111" & @CRLF $aNumber[0] &= "111111...111111.....................111111" & @CRLF $aNumber[0] &= "111111...111111.....................111111" & @CRLF $aNumber[0] &= "111111...111111.....................111111" & @CRLF $aNumber[0] &= "111111...111111.....................111111" & @CRLF $aNumber[0] &= "111111...111111.....................111111" & @CRLF $aNumber[0] &= ".........................................." & @CRLF $aNumber[0] &= ".........................................." & @CRLF $aNumber[0] &= ".........................................." & @CRLF $aNumber[0] &= "111111..............................111111" & @CRLF $aNumber[0] &= "111111..............................111111" & @CRLF $aNumber[0] &= "111111..............................111111" & @CRLF $aNumber[0] &= "111111..............................111111" & @CRLF $aNumber[0] &= "111111..............................111111" & @CRLF $aNumber[0] &= "111111..............................111111" & @CRLF $aNumber[0] &= ".........................................." & @CRLF $aNumber[0] &= ".........................................." & @CRLF $aNumber[0] &= ".........................................." & @CRLF $aNumber[0] &= ".........111111...111111...111111........." & @CRLF $aNumber[0] &= ".........111111...111111...111111........." & @CRLF $aNumber[0] &= ".........111111...111111...111111........." & @CRLF $aNumber[0] &= ".........111111...111111...111111........." & @CRLF $aNumber[0] &= ".........111111...111111...111111........." & @CRLF $aNumber[0] &= ".........111111...111111...111111........." & @CRLF $aNumber[1] = "" ; Pattern for '1' $aNumber[1] &= "..................111111.................." & @CRLF $aNumber[1] &= "..................111111.................." & @CRLF $aNumber[1] &= "..................111111.................." & @CRLF $aNumber[1] &= "..................111111.................." & @CRLF $aNumber[1] &= "..................111111.................." & @CRLF $aNumber[1] &= "..................111111.................." & @CRLF $aNumber[1] &= ".........................................." & @CRLF $aNumber[1] &= ".........................................." & @CRLF $aNumber[1] &= ".........................................." & @CRLF $aNumber[1] &= ".........111111...111111.................." & @CRLF $aNumber[1] &= ".........111111...111111.................." & @CRLF $aNumber[1] &= ".........111111...111111.................." & @CRLF $aNumber[1] &= ".........111111...111111.................." & @CRLF $aNumber[1] &= ".........111111...111111.................." & @CRLF $aNumber[1] &= ".........111111...111111.................." & @CRLF $aNumber[1] &= ".........................................." & @CRLF $aNumber[1] &= ".........................................." & @CRLF $aNumber[1] &= ".........................................." & @CRLF $aNumber[1] &= "..................111111.................." & @CRLF $aNumber[1] &= "..................111111.................." & @CRLF $aNumber[1] &= "..................111111.................." & @CRLF $aNumber[1] &= "..................111111.................." & @CRLF $aNumber[1] &= "..................111111.................." & @CRLF $aNumber[1] &= "..................111111.................." & @CRLF $aNumber[1] &= ".........................................." & @CRLF $aNumber[1] &= ".........................................." & @CRLF $aNumber[1] &= ".........................................." & @CRLF $aNumber[1] &= "..................111111.................." & @CRLF $aNumber[1] &= "..................111111.................." & @CRLF $aNumber[1] &= "..................111111.................." & @CRLF $aNumber[1] &= "..................111111.................." & @CRLF $aNumber[1] &= "..................111111.................." & @CRLF $aNumber[1] &= "..................111111.................." & @CRLF $aNumber[1] &= ".........................................." & @CRLF $aNumber[1] &= ".........................................." & @CRLF $aNumber[1] &= ".........................................." & @CRLF $aNumber[1] &= "..................111111.................." & @CRLF $aNumber[1] &= "..................111111.................." & @CRLF $aNumber[1] &= "..................111111.................." & @CRLF $aNumber[1] &= "..................111111.................." & @CRLF $aNumber[1] &= "..................111111.................." & @CRLF $aNumber[1] &= "..................111111.................." & @CRLF $aNumber[1] &= ".........................................." & @CRLF $aNumber[1] &= ".........................................." & @CRLF $aNumber[1] &= ".........................................." & @CRLF $aNumber[1] &= "..................111111.................." & @CRLF $aNumber[1] &= "..................111111.................." & @CRLF $aNumber[1] &= "..................111111.................." & @CRLF $aNumber[1] &= "..................111111.................." & @CRLF $aNumber[1] &= "..................111111.................." & @CRLF $aNumber[1] &= "..................111111.................." & @CRLF $aNumber[1] &= ".........................................." & @CRLF $aNumber[1] &= ".........................................." & @CRLF $aNumber[1] &= ".........................................." & @CRLF $aNumber[1] &= ".........111111...111111...111111........." & @CRLF $aNumber[1] &= ".........111111...111111...111111........." & @CRLF $aNumber[1] &= ".........111111...111111...111111........." & @CRLF $aNumber[1] &= ".........111111...111111...111111........." & @CRLF $aNumber[1] &= ".........111111...111111...111111........." & @CRLF $aNumber[1] &= ".........111111...111111...111111........." & @CRLF $aNumber[2] = "" ; Pattern for '2' $aNumber[2] &= ".........111111...111111...111111........." & @CRLF $aNumber[2] &= ".........111111...111111...111111........." & @CRLF $aNumber[2] &= ".........111111...111111...111111........." & @CRLF $aNumber[2] &= ".........111111...111111...111111........." & @CRLF $aNumber[2] &= ".........111111...111111...111111........." & @CRLF $aNumber[2] &= ".........111111...111111...111111........." & @CRLF $aNumber[2] &= ".........................................." & @CRLF $aNumber[2] &= ".........................................." & @CRLF $aNumber[2] &= ".........................................." & @CRLF $aNumber[2] &= "111111..............................111111" & @CRLF $aNumber[2] &= "111111..............................111111" & @CRLF $aNumber[2] &= "111111..............................111111" & @CRLF $aNumber[2] &= "111111..............................111111" & @CRLF $aNumber[2] &= "111111..............................111111" & @CRLF $aNumber[2] &= "111111..............................111111" & @CRLF $aNumber[2] &= ".........................................." & @CRLF $aNumber[2] &= ".........................................." & @CRLF $aNumber[2] &= ".........................................." & @CRLF $aNumber[2] &= "....................................111111" & @CRLF $aNumber[2] &= "....................................111111" & @CRLF $aNumber[2] &= "....................................111111" & @CRLF $aNumber[2] &= "....................................111111" & @CRLF $aNumber[2] &= "....................................111111" & @CRLF $aNumber[2] &= "....................................111111" & @CRLF $aNumber[2] &= ".........................................." & @CRLF $aNumber[2] &= ".........................................." & @CRLF $aNumber[2] &= ".........................................." & @CRLF $aNumber[2] &= "..................111111...111111........." & @CRLF $aNumber[2] &= "..................111111...111111........." & @CRLF $aNumber[2] &= "..................111111...111111........." & @CRLF $aNumber[2] &= "..................111111...111111........." & @CRLF $aNumber[2] &= "..................111111...111111........." & @CRLF $aNumber[2] &= "..................111111...111111........." & @CRLF $aNumber[2] &= ".........................................." & @CRLF $aNumber[2] &= ".........................................." & @CRLF $aNumber[2] &= ".........................................." & @CRLF $aNumber[2] &= ".........111111..........................." & @CRLF $aNumber[2] &= ".........111111..........................." & @CRLF $aNumber[2] &= ".........111111..........................." & @CRLF $aNumber[2] &= ".........111111..........................." & @CRLF $aNumber[2] &= ".........111111..........................." & @CRLF $aNumber[2] &= ".........111111..........................." & @CRLF $aNumber[2] &= ".........................................." & @CRLF $aNumber[2] &= ".........................................." & @CRLF $aNumber[2] &= ".........................................." & @CRLF $aNumber[2] &= "111111...................................." & @CRLF $aNumber[2] &= "111111...................................." & @CRLF $aNumber[2] &= "111111...................................." & @CRLF $aNumber[2] &= "111111...................................." & @CRLF $aNumber[2] &= "111111...................................." & @CRLF $aNumber[2] &= "111111...................................." & @CRLF $aNumber[2] &= ".........................................." & @CRLF $aNumber[2] &= ".........................................." & @CRLF $aNumber[2] &= ".........................................." & @CRLF $aNumber[2] &= "111111...111111...111111...111111...111111" & @CRLF $aNumber[2] &= "111111...111111...111111...111111...111111" & @CRLF $aNumber[2] &= "111111...111111...111111...111111...111111" & @CRLF $aNumber[2] &= "111111...111111...111111...111111...111111" & @CRLF $aNumber[2] &= "111111...111111...111111...111111...111111" & @CRLF $aNumber[2] &= "111111...111111...111111...111111...111111" & @CRLF $aNumber[3] = "" ; Pattern for '3' $aNumber[3] &= ".........111111...111111...111111........." & @CRLF $aNumber[3] &= ".........111111...111111...111111........." & @CRLF $aNumber[3] &= ".........111111...111111...111111........." & @CRLF $aNumber[3] &= ".........111111...111111...111111........." & @CRLF $aNumber[3] &= ".........111111...111111...111111........." & @CRLF $aNumber[3] &= ".........111111...111111...111111........." & @CRLF $aNumber[3] &= ".........................................." & @CRLF $aNumber[3] &= ".........................................." & @CRLF $aNumber[3] &= ".........................................." & @CRLF $aNumber[3] &= "111111..............................111111" & @CRLF $aNumber[3] &= "111111..............................111111" & @CRLF $aNumber[3] &= "111111..............................111111" & @CRLF $aNumber[3] &= "111111..............................111111" & @CRLF $aNumber[3] &= "111111..............................111111" & @CRLF $aNumber[3] &= "111111..............................111111" & @CRLF $aNumber[3] &= ".........................................." & @CRLF $aNumber[3] &= ".........................................." & @CRLF $aNumber[3] &= ".........................................." & @CRLF $aNumber[3] &= "....................................111111" & @CRLF $aNumber[3] &= "....................................111111" & @CRLF $aNumber[3] &= "....................................111111" & @CRLF $aNumber[3] &= "....................................111111" & @CRLF $aNumber[3] &= "....................................111111" & @CRLF $aNumber[3] &= "....................................111111" & @CRLF $aNumber[3] &= ".........................................." & @CRLF $aNumber[3] &= ".........................................." & @CRLF $aNumber[3] &= ".........................................." & @CRLF $aNumber[3] &= "..................111111...111111........." & @CRLF $aNumber[3] &= "..................111111...111111........." & @CRLF $aNumber[3] &= "..................111111...111111........." & @CRLF $aNumber[3] &= "..................111111...111111........." & @CRLF $aNumber[3] &= "..................111111...111111........." & @CRLF $aNumber[3] &= "..................111111...111111........." & @CRLF $aNumber[3] &= ".........................................." & @CRLF $aNumber[3] &= ".........................................." & @CRLF $aNumber[3] &= ".........................................." & @CRLF $aNumber[3] &= "....................................111111" & @CRLF $aNumber[3] &= "....................................111111" & @CRLF $aNumber[3] &= "....................................111111" & @CRLF $aNumber[3] &= "....................................111111" & @CRLF $aNumber[3] &= "....................................111111" & @CRLF $aNumber[3] &= "....................................111111" & @CRLF $aNumber[3] &= ".........................................." & @CRLF $aNumber[3] &= ".........................................." & @CRLF $aNumber[3] &= ".........................................." & @CRLF $aNumber[3] &= "111111..............................111111" & @CRLF $aNumber[3] &= "111111..............................111111" & @CRLF $aNumber[3] &= "111111..............................111111" & @CRLF $aNumber[3] &= "111111..............................111111" & @CRLF $aNumber[3] &= "111111..............................111111" & @CRLF $aNumber[3] &= "111111..............................111111" & @CRLF $aNumber[3] &= ".........................................." & @CRLF $aNumber[3] &= ".........................................." & @CRLF $aNumber[3] &= ".........................................." & @CRLF $aNumber[3] &= ".........111111...111111...111111........." & @CRLF $aNumber[3] &= ".........111111...111111...111111........." & @CRLF $aNumber[3] &= ".........111111...111111...111111........." & @CRLF $aNumber[3] &= ".........111111...111111...111111........." & @CRLF $aNumber[3] &= ".........111111...111111...111111........." & @CRLF $aNumber[3] &= ".........111111...111111...111111........." & @CRLF $aNumber[4] = "" ; Pattern for '4' $aNumber[4] &= "...........................111111........." & @CRLF $aNumber[4] &= "...........................111111........." & @CRLF $aNumber[4] &= "...........................111111........." & @CRLF $aNumber[4] &= "...........................111111........." & @CRLF $aNumber[4] &= "...........................111111........." & @CRLF $aNumber[4] &= "...........................111111........." & @CRLF $aNumber[4] &= ".........................................." & @CRLF $aNumber[4] &= ".........................................." & @CRLF $aNumber[4] &= ".........................................." & @CRLF $aNumber[4] &= "..................111111...111111........." & @CRLF $aNumber[4] &= "..................111111...111111........." & @CRLF $aNumber[4] &= "..................111111...111111........." & @CRLF $aNumber[4] &= "..................111111...111111........." & @CRLF $aNumber[4] &= "..................111111...111111........." & @CRLF $aNumber[4] &= "..................111111...111111........." & @CRLF $aNumber[4] &= ".........................................." & @CRLF $aNumber[4] &= ".........................................." & @CRLF $aNumber[4] &= ".........................................." & @CRLF $aNumber[4] &= ".........111111............111111........." & @CRLF $aNumber[4] &= ".........111111............111111........." & @CRLF $aNumber[4] &= ".........111111............111111........." & @CRLF $aNumber[4] &= ".........111111............111111........." & @CRLF $aNumber[4] &= ".........111111............111111........." & @CRLF $aNumber[4] &= ".........111111............111111........." & @CRLF $aNumber[4] &= ".........................................." & @CRLF $aNumber[4] &= ".........................................." & @CRLF $aNumber[4] &= ".........................................." & @CRLF $aNumber[4] &= "111111.....................111111........." & @CRLF $aNumber[4] &= "111111.....................111111........." & @CRLF $aNumber[4] &= "111111.....................111111........." & @CRLF $aNumber[4] &= "111111.....................111111........." & @CRLF $aNumber[4] &= "111111.....................111111........." & @CRLF $aNumber[4] &= "111111.....................111111........." & @CRLF $aNumber[4] &= ".........................................." & @CRLF $aNumber[4] &= ".........................................." & @CRLF $aNumber[4] &= ".........................................." & @CRLF $aNumber[4] &= "111111...111111...111111...111111...111111" & @CRLF $aNumber[4] &= "111111...111111...111111...111111...111111" & @CRLF $aNumber[4] &= "111111...111111...111111...111111...111111" & @CRLF $aNumber[4] &= "111111...111111...111111...111111...111111" & @CRLF $aNumber[4] &= "111111...111111...111111...111111...111111" & @CRLF $aNumber[4] &= "111111...111111...111111...111111...111111" & @CRLF $aNumber[4] &= ".........................................." & @CRLF $aNumber[4] &= ".........................................." & @CRLF $aNumber[4] &= ".........................................." & @CRLF $aNumber[4] &= "...........................111111........." & @CRLF $aNumber[4] &= "...........................111111........." & @CRLF $aNumber[4] &= "...........................111111........." & @CRLF $aNumber[4] &= "...........................111111........." & @CRLF $aNumber[4] &= "...........................111111........." & @CRLF $aNumber[4] &= "...........................111111........." & @CRLF $aNumber[4] &= ".........................................." & @CRLF $aNumber[4] &= ".........................................." & @CRLF $aNumber[4] &= ".........................................." & @CRLF $aNumber[4] &= "...........................111111........." & @CRLF $aNumber[4] &= "...........................111111........." & @CRLF $aNumber[4] &= "...........................111111........." & @CRLF $aNumber[4] &= "...........................111111........." & @CRLF $aNumber[4] &= "...........................111111........." & @CRLF $aNumber[4] &= "...........................111111........." & @CRLF $aNumber[5] = "" ; Pattern for '5' $aNumber[5] &= "111111...111111...111111...111111...111111" & @CRLF $aNumber[5] &= "111111...111111...111111...111111...111111" & @CRLF $aNumber[5] &= "111111...111111...111111...111111...111111" & @CRLF $aNumber[5] &= "111111...111111...111111...111111...111111" & @CRLF $aNumber[5] &= "111111...111111...111111...111111...111111" & @CRLF $aNumber[5] &= "111111...111111...111111...111111...111111" & @CRLF $aNumber[5] &= ".........................................." & @CRLF $aNumber[5] &= ".........................................." & @CRLF $aNumber[5] &= ".........................................." & @CRLF $aNumber[5] &= "111111...................................." & @CRLF $aNumber[5] &= "111111...................................." & @CRLF $aNumber[5] &= "111111...................................." & @CRLF $aNumber[5] &= "111111...................................." & @CRLF $aNumber[5] &= "111111...................................." & @CRLF $aNumber[5] &= "111111...................................." & @CRLF $aNumber[5] &= ".........................................." & @CRLF $aNumber[5] &= ".........................................." & @CRLF $aNumber[5] &= ".........................................." & @CRLF $aNumber[5] &= "111111...111111...111111...111111........." & @CRLF $aNumber[5] &= "111111...111111...111111...111111........." & @CRLF $aNumber[5] &= "111111...111111...111111...111111........." & @CRLF $aNumber[5] &= "111111...111111...111111...111111........." & @CRLF $aNumber[5] &= "111111...111111...111111...111111........." & @CRLF $aNumber[5] &= "111111...111111...111111...111111........." & @CRLF $aNumber[5] &= ".........................................." & @CRLF $aNumber[5] &= ".........................................." & @CRLF $aNumber[5] &= ".........................................." & @CRLF $aNumber[5] &= "....................................111111" & @CRLF $aNumber[5] &= "....................................111111" & @CRLF $aNumber[5] &= "....................................111111" & @CRLF $aNumber[5] &= "....................................111111" & @CRLF $aNumber[5] &= "....................................111111" & @CRLF $aNumber[5] &= "....................................111111" & @CRLF $aNumber[5] &= ".........................................." & @CRLF $aNumber[5] &= ".........................................." & @CRLF $aNumber[5] &= ".........................................." & @CRLF $aNumber[5] &= "....................................111111" & @CRLF $aNumber[5] &= "....................................111111" & @CRLF $aNumber[5] &= "....................................111111" & @CRLF $aNumber[5] &= "....................................111111" & @CRLF $aNumber[5] &= "....................................111111" & @CRLF $aNumber[5] &= "....................................111111" & @CRLF $aNumber[5] &= ".........................................." & @CRLF $aNumber[5] &= ".........................................." & @CRLF $aNumber[5] &= ".........................................." & @CRLF $aNumber[5] &= "111111..............................111111" & @CRLF $aNumber[5] &= "111111..............................111111" & @CRLF $aNumber[5] &= "111111..............................111111" & @CRLF $aNumber[5] &= "111111..............................111111" & @CRLF $aNumber[5] &= "111111..............................111111" & @CRLF $aNumber[5] &= "111111..............................111111" & @CRLF $aNumber[5] &= ".........................................." & @CRLF $aNumber[5] &= ".........................................." & @CRLF $aNumber[5] &= ".........................................." & @CRLF $aNumber[5] &= ".........111111...111111...111111........." & @CRLF $aNumber[5] &= ".........111111...111111...111111........." & @CRLF $aNumber[5] &= ".........111111...111111...111111........." & @CRLF $aNumber[5] &= ".........111111...111111...111111........." & @CRLF $aNumber[5] &= ".........111111...111111...111111........." & @CRLF $aNumber[5] &= ".........111111...111111...111111........." & @CRLF $aNumber[6] = "" ; Pattern for '6' $aNumber[6] &= "..................111111...111111........." & @CRLF $aNumber[6] &= "..................111111...111111........." & @CRLF $aNumber[6] &= "..................111111...111111........." & @CRLF $aNumber[6] &= "..................111111...111111........." & @CRLF $aNumber[6] &= "..................111111...111111........." & @CRLF $aNumber[6] &= "..................111111...111111........." & @CRLF $aNumber[6] &= ".........................................." & @CRLF $aNumber[6] &= ".........................................." & @CRLF $aNumber[6] &= ".........................................." & @CRLF $aNumber[6] &= ".........111111..........................." & @CRLF $aNumber[6] &= ".........111111..........................." & @CRLF $aNumber[6] &= ".........111111..........................." & @CRLF $aNumber[6] &= ".........111111..........................." & @CRLF $aNumber[6] &= ".........111111..........................." & @CRLF $aNumber[6] &= ".........111111..........................." & @CRLF $aNumber[6] &= ".........................................." & @CRLF $aNumber[6] &= ".........................................." & @CRLF $aNumber[6] &= ".........................................." & @CRLF $aNumber[6] &= "111111...................................." & @CRLF $aNumber[6] &= "111111...................................." & @CRLF $aNumber[6] &= "111111...................................." & @CRLF $aNumber[6] &= "111111...................................." & @CRLF $aNumber[6] &= "111111...................................." & @CRLF $aNumber[6] &= "111111...................................." & @CRLF $aNumber[6] &= ".........................................." & @CRLF $aNumber[6] &= ".........................................." & @CRLF $aNumber[6] &= ".........................................." & @CRLF $aNumber[6] &= "111111...111111...111111...111111........." & @CRLF $aNumber[6] &= "111111...111111...111111...111111........." & @CRLF $aNumber[6] &= "111111...111111...111111...111111........." & @CRLF $aNumber[6] &= "111111...111111...111111...111111........." & @CRLF $aNumber[6] &= "111111...111111...111111...111111........." & @CRLF $aNumber[6] &= "111111...111111...111111...111111........." & @CRLF $aNumber[6] &= ".........................................." & @CRLF $aNumber[6] &= ".........................................." & @CRLF $aNumber[6] &= ".........................................." & @CRLF $aNumber[6] &= "111111..............................111111" & @CRLF $aNumber[6] &= "111111..............................111111" & @CRLF $aNumber[6] &= "111111..............................111111" & @CRLF $aNumber[6] &= "111111..............................111111" & @CRLF $aNumber[6] &= "111111..............................111111" & @CRLF $aNumber[6] &= "111111..............................111111" & @CRLF $aNumber[6] &= ".........................................." & @CRLF $aNumber[6] &= ".........................................." & @CRLF $aNumber[6] &= ".........................................." & @CRLF $aNumber[6] &= "111111..............................111111" & @CRLF $aNumber[6] &= "111111..............................111111" & @CRLF $aNumber[6] &= "111111..............................111111" & @CRLF $aNumber[6] &= "111111..............................111111" & @CRLF $aNumber[6] &= "111111..............................111111" & @CRLF $aNumber[6] &= "111111..............................111111" & @CRLF $aNumber[6] &= ".........................................." & @CRLF $aNumber[6] &= ".........................................." & @CRLF $aNumber[6] &= ".........................................." & @CRLF $aNumber[6] &= ".........111111...111111...111111........." & @CRLF $aNumber[6] &= ".........111111...111111...111111........." & @CRLF $aNumber[6] &= ".........111111...111111...111111........." & @CRLF $aNumber[6] &= ".........111111...111111...111111........." & @CRLF $aNumber[6] &= ".........111111...111111...111111........." & @CRLF $aNumber[6] &= ".........111111...111111...111111........." & @CRLF $aNumber[7] = "" ; Pattern for '7' $aNumber[7] &= "111111...111111...111111...111111...111111" & @CRLF $aNumber[7] &= "111111...111111...111111...111111...111111" & @CRLF $aNumber[7] &= "111111...111111...111111...111111...111111" & @CRLF $aNumber[7] &= "111111...111111...111111...111111...111111" & @CRLF $aNumber[7] &= "111111...111111...111111...111111...111111" & @CRLF $aNumber[7] &= "111111...111111...111111...111111...111111" & @CRLF $aNumber[7] &= ".........................................." & @CRLF $aNumber[7] &= ".........................................." & @CRLF $aNumber[7] &= ".........................................." & @CRLF $aNumber[7] &= "....................................111111" & @CRLF $aNumber[7] &= "....................................111111" & @CRLF $aNumber[7] &= "....................................111111" & @CRLF $aNumber[7] &= "....................................111111" & @CRLF $aNumber[7] &= "....................................111111" & @CRLF $aNumber[7] &= "....................................111111" & @CRLF $aNumber[7] &= ".........................................." & @CRLF $aNumber[7] &= ".........................................." & @CRLF $aNumber[7] &= ".........................................." & @CRLF $aNumber[7] &= "...........................111111........." & @CRLF $aNumber[7] &= "...........................111111........." & @CRLF $aNumber[7] &= "...........................111111........." & @CRLF $aNumber[7] &= "...........................111111........." & @CRLF $aNumber[7] &= "...........................111111........." & @CRLF $aNumber[7] &= "...........................111111........." & @CRLF $aNumber[7] &= ".........................................." & @CRLF $aNumber[7] &= ".........................................." & @CRLF $aNumber[7] &= ".........................................." & @CRLF $aNumber[7] &= "..................111111.................." & @CRLF $aNumber[7] &= "..................111111.................." & @CRLF $aNumber[7] &= "..................111111.................." & @CRLF $aNumber[7] &= "..................111111.................." & @CRLF $aNumber[7] &= "..................111111.................." & @CRLF $aNumber[7] &= "..................111111.................." & @CRLF $aNumber[7] &= ".........................................." & @CRLF $aNumber[7] &= ".........................................." & @CRLF $aNumber[7] &= ".........................................." & @CRLF $aNumber[7] &= ".........111111..........................." & @CRLF $aNumber[7] &= ".........111111..........................." & @CRLF $aNumber[7] &= ".........111111..........................." & @CRLF $aNumber[7] &= ".........111111..........................." & @CRLF $aNumber[7] &= ".........111111..........................." & @CRLF $aNumber[7] &= ".........111111..........................." & @CRLF $aNumber[7] &= ".........................................." & @CRLF $aNumber[7] &= ".........................................." & @CRLF $aNumber[7] &= ".........................................." & @CRLF $aNumber[7] &= ".........111111..........................." & @CRLF $aNumber[7] &= ".........111111..........................." & @CRLF $aNumber[7] &= ".........111111..........................." & @CRLF $aNumber[7] &= ".........111111..........................." & @CRLF $aNumber[7] &= ".........111111..........................." & @CRLF $aNumber[7] &= ".........111111..........................." & @CRLF $aNumber[7] &= ".........................................." & @CRLF $aNumber[7] &= ".........................................." & @CRLF $aNumber[7] &= ".........................................." & @CRLF $aNumber[7] &= ".........111111..........................." & @CRLF $aNumber[7] &= ".........111111..........................." & @CRLF $aNumber[7] &= ".........111111..........................." & @CRLF $aNumber[7] &= ".........111111..........................." & @CRLF $aNumber[7] &= ".........111111..........................." & @CRLF $aNumber[7] &= ".........111111..........................." & @CRLF $aNumber[8] = "" ; Pattern for '8' $aNumber[8] &= ".........111111...111111...111111........." & @CRLF $aNumber[8] &= ".........111111...111111...111111........." & @CRLF $aNumber[8] &= ".........111111...111111...111111........." & @CRLF $aNumber[8] &= ".........111111...111111...111111........." & @CRLF $aNumber[8] &= ".........111111...111111...111111........." & @CRLF $aNumber[8] &= ".........111111...111111...111111........." & @CRLF $aNumber[8] &= ".........................................." & @CRLF $aNumber[8] &= ".........................................." & @CRLF $aNumber[8] &= ".........................................." & @CRLF $aNumber[8] &= "111111..............................111111" & @CRLF $aNumber[8] &= "111111..............................111111" & @CRLF $aNumber[8] &= "111111..............................111111" & @CRLF $aNumber[8] &= "111111..............................111111" & @CRLF $aNumber[8] &= "111111..............................111111" & @CRLF $aNumber[8] &= "111111..............................111111" & @CRLF $aNumber[8] &= ".........................................." & @CRLF $aNumber[8] &= ".........................................." & @CRLF $aNumber[8] &= ".........................................." & @CRLF $aNumber[8] &= "111111..............................111111" & @CRLF $aNumber[8] &= "111111..............................111111" & @CRLF $aNumber[8] &= "111111..............................111111" & @CRLF $aNumber[8] &= "111111..............................111111" & @CRLF $aNumber[8] &= "111111..............................111111" & @CRLF $aNumber[8] &= "111111..............................111111" & @CRLF $aNumber[8] &= ".........................................." & @CRLF $aNumber[8] &= ".........................................." & @CRLF $aNumber[8] &= ".........................................." & @CRLF $aNumber[8] &= ".........111111...111111...111111........." & @CRLF $aNumber[8] &= ".........111111...111111...111111........." & @CRLF $aNumber[8] &= ".........111111...111111...111111........." & @CRLF $aNumber[8] &= ".........111111...111111...111111........." & @CRLF $aNumber[8] &= ".........111111...111111...111111........." & @CRLF $aNumber[8] &= ".........111111...111111...111111........." & @CRLF $aNumber[8] &= ".........................................." & @CRLF $aNumber[8] &= ".........................................." & @CRLF $aNumber[8] &= ".........................................." & @CRLF $aNumber[8] &= "111111..............................111111" & @CRLF $aNumber[8] &= "111111..............................111111" & @CRLF $aNumber[8] &= "111111..............................111111" & @CRLF $aNumber[8] &= "111111..............................111111" & @CRLF $aNumber[8] &= "111111..............................111111" & @CRLF $aNumber[8] &= "111111..............................111111" & @CRLF $aNumber[8] &= ".........................................." & @CRLF $aNumber[8] &= ".........................................." & @CRLF $aNumber[8] &= ".........................................." & @CRLF $aNumber[8] &= "111111..............................111111" & @CRLF $aNumber[8] &= "111111..............................111111" & @CRLF $aNumber[8] &= "111111..............................111111" & @CRLF $aNumber[8] &= "111111..............................111111" & @CRLF $aNumber[8] &= "111111..............................111111" & @CRLF $aNumber[8] &= "111111..............................111111" & @CRLF $aNumber[8] &= ".........................................." & @CRLF $aNumber[8] &= ".........................................." & @CRLF $aNumber[8] &= ".........................................." & @CRLF $aNumber[8] &= ".........111111...111111...111111........." & @CRLF $aNumber[8] &= ".........111111...111111...111111........." & @CRLF $aNumber[8] &= ".........111111...111111...111111........." & @CRLF $aNumber[8] &= ".........111111...111111...111111........." & @CRLF $aNumber[8] &= ".........111111...111111...111111........." & @CRLF $aNumber[8] &= ".........111111...111111...111111........." & @CRLF $aNumber[9] = "" ; Pattern for '9' $aNumber[9] &= ".........111111...111111...111111........." & @CRLF $aNumber[9] &= ".........111111...111111...111111........." & @CRLF $aNumber[9] &= ".........111111...111111...111111........." & @CRLF $aNumber[9] &= ".........111111...111111...111111........." & @CRLF $aNumber[9] &= ".........111111...111111...111111........." & @CRLF $aNumber[9] &= ".........111111...111111...111111........." & @CRLF $aNumber[9] &= ".........................................." & @CRLF $aNumber[9] &= ".........................................." & @CRLF $aNumber[9] &= ".........................................." & @CRLF $aNumber[9] &= "111111..............................111111" & @CRLF $aNumber[9] &= "111111..............................111111" & @CRLF $aNumber[9] &= "111111..............................111111" & @CRLF $aNumber[9] &= "111111..............................111111" & @CRLF $aNumber[9] &= "111111..............................111111" & @CRLF $aNumber[9] &= "111111..............................111111" & @CRLF $aNumber[9] &= ".........................................." & @CRLF $aNumber[9] &= ".........................................." & @CRLF $aNumber[9] &= ".........................................." & @CRLF $aNumber[9] &= "111111..............................111111" & @CRLF $aNumber[9] &= "111111..............................111111" & @CRLF $aNumber[9] &= "111111..............................111111" & @CRLF $aNumber[9] &= "111111..............................111111" & @CRLF $aNumber[9] &= "111111..............................111111" & @CRLF $aNumber[9] &= "111111..............................111111" & @CRLF $aNumber[9] &= ".........................................." & @CRLF $aNumber[9] &= ".........................................." & @CRLF $aNumber[9] &= ".........................................." & @CRLF $aNumber[9] &= ".........111111...111111...111111...111111" & @CRLF $aNumber[9] &= ".........111111...111111...111111...111111" & @CRLF $aNumber[9] &= ".........111111...111111...111111...111111" & @CRLF $aNumber[9] &= ".........111111...111111...111111...111111" & @CRLF $aNumber[9] &= ".........111111...111111...111111...111111" & @CRLF $aNumber[9] &= ".........111111...111111...111111...111111" & @CRLF $aNumber[9] &= ".........................................." & @CRLF $aNumber[9] &= ".........................................." & @CRLF $aNumber[9] &= ".........................................." & @CRLF $aNumber[9] &= "....................................111111" & @CRLF $aNumber[9] &= "....................................111111" & @CRLF $aNumber[9] &= "....................................111111" & @CRLF $aNumber[9] &= "....................................111111" & @CRLF $aNumber[9] &= "....................................111111" & @CRLF $aNumber[9] &= "....................................111111" & @CRLF $aNumber[9] &= ".........................................." & @CRLF $aNumber[9] &= ".........................................." & @CRLF $aNumber[9] &= ".........................................." & @CRLF $aNumber[9] &= "...........................111111........." & @CRLF $aNumber[9] &= "...........................111111........." & @CRLF $aNumber[9] &= "...........................111111........." & @CRLF $aNumber[9] &= "...........................111111........." & @CRLF $aNumber[9] &= "...........................111111........." & @CRLF $aNumber[9] &= "...........................111111........." & @CRLF $aNumber[9] &= ".........................................." & @CRLF $aNumber[9] &= ".........................................." & @CRLF $aNumber[9] &= ".........................................." & @CRLF $aNumber[9] &= ".........111111...111111.................." & @CRLF $aNumber[9] &= ".........111111...111111.................." & @CRLF $aNumber[9] &= ".........111111...111111.................." & @CRLF $aNumber[9] &= ".........111111...111111.................." & @CRLF $aNumber[9] &= ".........111111...111111.................." & @CRLF $aNumber[9] &= ".........111111...111111.................." & @CRLF Switch $sPattern Case $aNumber[0] Return 0 Case $aNumber[1] Return 1 Case $aNumber[2] Return 2 Case $aNumber[3] Return 3 Case $aNumber[4] Return 4 Case $aNumber[5] Return 5 Case $aNumber[6] Return 6 Case $aNumber[7] Return 7 Case $aNumber[8] Return 8 Case $aNumber[9] Return 9 Case Else Return SetError(1, 0, "") EndSwitch EndFunc ;==>_GetNumber ;-------------------------------------------------------------------------------------------------------------------------------- Func SelectArea() ; SelectArea Local $aRecPos[4], $aMPos[2], $tPos ;, $aTipPos[4], $iX, $iY Local $iDeskWidth, $iDeskHeight, $iDeskLeft, $iDeskTop Local $sDevice, $hMonitor, $sCurDevice, $aData, $Status = 0 ; make Capture gui $hGUICapture = GUICreate("Capture_gui", 1, 1, 1, 1, $WS_POPUP, BitOR($WS_EX_TOOLWINDOW, $WS_EX_TOPMOST)) GUISetBkColor("0xFFFF00", $hGUICapture) ; $COLOR_YELLOW WinSetTrans($hGUICapture, "", 50) ; make mouse block gui $block_gui = GUICreate("block_gui", 1, 1, 1, 1, $WS_POPUP, BitOR($WS_EX_TOOLWINDOW, $WS_EX_TOPMOST)) WinSetTrans($block_gui, "", 1) GUISetState(@SW_SHOW, $block_gui) GUISetCursor($MCID_CROSS, 1, $block_gui) Sleep(200) Local $iMaxLoop = 1200, $iCntLoop = 0 While Sleep(10) $iCntLoop += 1 If $iCntLoop = $iMaxLoop Then ExitLoop ; get mouse coordinates $tPos = _WinAPI_GetMousePos() $aMPos[0] = DllStructGetData($tPos, 1) $aMPos[1] = DllStructGetData($tPos, 2) ; get $hMonitor from previously defined Mouse coordinates $hMonitor = _WinAPI_MonitorFromPoint($tPos) ; get monitor $aData appropriate for previously defined coordinates $aData = _WinAPI_GetMonitorInfo($hMonitor) If Not @error Then $sDevice = $aData[3] $iDeskLeft = DllStructGetData($aData[0], 1) $iDeskTop = DllStructGetData($aData[0], 2) $iDeskWidth = DllStructGetData($aData[0], 3) $iDeskHeight = DllStructGetData($aData[0], 4) EndIf ;move the $block_gui to active monitor If $sCurDevice <> $sDevice Then $sCurDevice = $sDevice ;ConsoleWrite("- $sCurDevice=" & $sCurDevice & @CRLF) WinMove($block_gui, "", $iDeskLeft, $iDeskTop, $iDeskWidth, $iDeskHeight) EndIf ; whait Left_mouse_button _IsPressed If _IsPressed("01", $hDLL) Then $Status = 1 $aMPos = MouseGetPos() $aRecPos[0] = $aMPos[0] $aRecPos[1] = $aMPos[1] ; Wait until key is released. While _IsPressed("01", $hDLL) Sleep(50) $aMPos = MouseGetPos() $aRecPos[2] = $aMPos[0] $aRecPos[3] = $aMPos[1] ; show Capture gui GUISetState(@SW_SHOW, $hGUICapture) WinMove($hGUICapture, "", $aRecPos[0], $aRecPos[1], $aRecPos[2] - $aRecPos[0], $aRecPos[3] - $aRecPos[1]) WEnd ElseIf _IsPressed("1B", $hDLL) Then ;1B=ESC key - emergency exit GUIDelete($hGUICapture) GUIDelete($block_gui) Return SetError(1, 1, 0) EndIf If $Status = 1 Then ExitLoop WEnd GUIDelete($hGUICapture) GUIDelete($block_gui) ConsoleWrite("outer area: " &$aRecPos[0] & ";" & $aRecPos[1] & ";" & $aRecPos[2] + $aRecPos[0] & ";" & $aRecPos[3] + $aRecPos[1] & @CRLF) Return $aRecPos EndFunc ;==>SelectArea ;-------------------------------------------------------------------------------------------------------------------------------- Edited October 31 by ioa747 Update to Version: 2.0 argumentum, Hashim and Danyfirex 3 I know that I know nothing
Hashim Posted October 31 Posted October 31 (edited) Wow, you did all this manually in less than a day, without even being asked? Thank you so much. I "solved" the issue by using a smaller portion of the screen elsewhere, but that was too small so the accuracy wasn't good enough to be reliable and I had to abandon it, so this is looking like my best hope. Unfortunately I couldn't get it working with the test image, maybe I'm selecting the wrong part? I opened the image in the Windows viewer and tried selecting the whole image, and then tried just the digits and some border/margin, but each time it says "No color found". Should I be selecting a specific part of the image? Also, should I be importing/calling it in my script in a certain way? As currently it stops execution of my main script when I include it at the top. In the meantime I'll provide the other 7 digits to help you complete the pattern if possible. Feel free to do it in your own time and let me know if you need any more examples/padding/contrast. Edited November 4 by Hashim
ioa747 Posted October 31 Author Posted October 31 I don't know why it won't work for you the only limitation it has is that it has to run in 32 bit otherwise try disabling , in line:10 DllCall("user32.dll", "bool", "SetProcessDpiAwarenessContext", "int", -4) ; -4=PerMonitorAwareV2 and do a test this script is more a fast how-to guide for that and it doesn't have full error handling it seems long and many pieces are copied from other scripts, and a large part they need the patterns which, by the way, it prints on the console, you just copy and paste when you choose the area it is better not to choose a large area but to give a margin of 10 to 20 pixels, the bigger it is the more it delays give me some time and i will integrate the other numbers Hashim 1 I know that I know nothing
ioa747 Posted October 31 Author Posted October 31 (edited) updated the script above what to watch out for: script run in 32 bit the image should be at 100% size Feel free to ask if you have any questions. Edited October 31 by ioa747 Hashim 1 I know that I know nothing
Hashim Posted November 2 Posted November 2 (edited) On 10/31/2024 at 1:21 AM, ioa747 said: this script is more a fast how-to guide for that and it doesn't have full error handling it seems long and many pieces are copied from other scripts, and a large part they need the patterns I don't know what you mean by 100% size, but I've tried with both scale 1 and 2 from your UWPOCR script + a few different borders, and then selecting the numbers in that image while leaving a 10-20 pixel margin, but unfortunately I keep getting the same "color not found" error every single time. I'm also making sure to execute the script as 32-bit and tried with commenting out line 18 as you mentioend. I'm not sure exactly what the console is for AutoIT but if it means SciteLite's Output tab I'm never able to see anything on it, it just remains blank. Is there anything I might be doing wrong or is this font just impossible to OCR on? Edited November 2 by Hashim
ioa747 Posted November 2 Author Posted November 2 (edited) 2 hours ago, Hashim said: I don't know what you mean by 100% size, but I've tried with both scale 1 and 2 from your UWPOCR script now you've confused me, since the UWPOCR has nothing to do with this particular scenario when I say the image should be at 100% size, i mean that it will not have zoom and will show on screen 1:1 I use IrfanView but I also tried with Microsoft.Windows.Photos, both have a combo box with zoom factor chose 100% 2 hours ago, Hashim said: I'm not sure exactly what the console is for AutoIT but if it means SciteLite's Output tab I'm never able to see anything on it, it just remains blank yes, I mean the site SciteLite's output console. oops ?? SciteLite's ?? very likely then this is the problem try putting the SciTE4AutoIt3.exe from https://www.autoitscript.com/site/autoit-script-editor/downloads/ and then re try the script and see what results you get the console should show at least the selected scan area e.g. outer area: 58;426;270;1014 Edited November 2 by ioa747 I know that I know nothing
Hashim Posted November 3 Posted November 3 (edited) Yeah, apparently only SciTELite comes with the default installation package and I thought its Output tab would be enough. I have now downloaded SciTe but still can't see anything in the console, even when running a ConsoleWrite("Test") in the initialisation section. Maybe similar to this issue, as I am running 64-bit Windows 10. Either way this is not a huge problem as I can use MsgBox or just output to a file instead, the real problem is that it fails with the "No color found" error before the first ConsoleWrite call, so this issue doesn't seem likely to be caused by the console. I'm using UWPOCR and your custom _ScreenCapture function to capture the images then opening these images to select the area, am I doing this the wrong way? I can't get the script to work even without any scaling or zooming. Here is one of the images at original scale of the application: Edited November 3 by Hashim
Hashim Posted November 3 Posted November 3 (edited) Scratch that, just realised this is not an OCR solution and is probably still my best chance of doing this at ~100% effectiveness Edited November 3 by Hashim
ioa747 Posted November 3 Author Posted November 3 35 minutes ago, Hashim said: I'm using UWPOCR and your custom _ScreenCapture function to capture the images then opening these images to select the area, am I doing this the wrong way? in this script which is above I don't use either UWPOCR or the _ScreenCapture function, otherwise you would see it just run script , then press '{End}' key (right above the arrows) , which is a hotkey button to start the process, to select the area that will be scanned for the number now let us clarify another point the first pictures you sent us and the last one have some differences ; each number Display is a matrix of 14x20 Vpoint ; each Vpoint is a 3x3 pixel ; each number Display is 42x60 pixel (these numbers were calculated with the first images that passed to us ) Vpoint = on the right side that has two green squares with each one of them is the v point in the first ones: Vpoint = 3x3 in the second: Vpoint = 1x1 conclusion: the first numbers you gave us, were they with zoom factor 3 for the script to work you must open one of the first photos you sent us in a viewer with the zoom factor at 100%, run my script, press '{End}' key, and select in the area from the number to the viewer I know that I know nothing
argumentum Posted November 3 Posted November 3 (edited) .. about PixelSearch() ? If the images are as crisp looking as the ones posted here, it should work 100%. Idea: Spoiler ;coded by UEZ 2011 ;;; butchered by argumentum: https://www.autoitscript.com/forum/topic/135989-png-in-gui/?do=findComment&comment=950214 #include <GUIConstantsEx.au3> #include <GDIPlus.au3> ;~ Global Const $IMAGE_BITMAP = 0 Global Const $STM_SETIMAGE = 0x0172 Global $msg Global Const $hGUI = GUICreate("Display PNG Image in picture control", 450, 200, 0, 0) Global Const $idPic = GUICtrlCreatePic("", 10, 10) _GDIPlus_Startup() ;~ Global $png = StringReplace(@AutoItExe, "\autoit3.exe", "\Examples\GUI\Torus.png") Global $png = "code_000002.png.654788f00e8a50a71a5443f06266b80c.png" ; from your post Global $hImage = _GDIPlus_ImageLoadFromFile($png) Global $Bmp = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage) _WinAPI_DeleteObject(GUICtrlSendMsg($idPic, $STM_SETIMAGE, $IMAGE_BITMAP, $Bmp)) GUISetState() Sleep(1000) Global $a = PixelSearch(0, 0, 500, 250, 0x00FF00, 0, 1, $hGUI) If @error Then Exit 6 ConsoleWrite($a[0] & ', ' & $a[1] & @CRLF) MouseMove($a[0], $a[1]) While True $msg = GUIGetMsg() Switch $msg Case $idPic MsgBox(0, "Information", "PNG image was clicked") Case $GUI_EVENT_CLOSE _WinAPI_DeleteObject($Bmp) _GDIPlus_ImageDispose($hImage) _GDIPlus_Shutdown() GUIDelete($hGUI) Exit EndSwitch WEnd Edited November 3 by argumentum posted code Hashim 1 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
Hashim Posted November 3 Posted November 3 (edited) 22 hours ago, ioa747 said: in this script which is above I don't use either UWPOCR or the _ScreenCapture function, otherwise you would see it just run script , then press '{End}' key (right above the arrows) , which is a hotkey button to start the process, to select the area that will be scanned for the number now let us clarify another point the first pictures you sent us and the last one have some differences ; each number Display is a matrix of 14x20 Vpoint ; each Vpoint is a 3x3 pixel ; each number Display is 42x60 pixel (these numbers were calculated with the first images that passed to us ) Vpoint = on the right side that has two green squares with each one of them is the v point in the first ones: Vpoint = 3x3 in the second: Vpoint = 1x1 conclusion: the first numbers you gave us, were they with zoom factor 3 for the script to work you must open one of the first photos you sent us in a viewer with the zoom factor at 100%, run my script, press '{End}' key, and select in the area from the number to the viewer I had figured all this out before and that's what I've been doing all this time, as mentioned the _ScreenCapture function was only being used to generate the image from the application, and I am running your script on its own. Yes you're right, the original images were generated with the _ScreenCapture function's scale factor of 3, I thought this would make it easier for you. Unfortunately I still get the "no color found" error, whether the selection is done from an image at scale factor 3 or at scale factor 1. 21 hours ago, argumentum said: .. about PixelSearch() ? If the images are as crisp looking as the ones posted here, it should work 100%. Idea: Hide contents ;coded by UEZ 2011 ;;; butchered by argumentum: https://www.autoitscript.com/forum/topic/135989-png-in-gui/?do=findComment&comment=950214 #include <GUIConstantsEx.au3> #include <GDIPlus.au3> ;~ Global Const $IMAGE_BITMAP = 0 Global Const $STM_SETIMAGE = 0x0172 Global $msg Global Const $hGUI = GUICreate("Display PNG Image in picture control", 450, 200, 0, 0) Global Const $idPic = GUICtrlCreatePic("", 10, 10) _GDIPlus_Startup() ;~ Global $png = StringReplace(@AutoItExe, "\autoit3.exe", "\Examples\GUI\Torus.png") Global $png = "code_000002.png.654788f00e8a50a71a5443f06266b80c.png" ; from your post Global $hImage = _GDIPlus_ImageLoadFromFile($png) Global $Bmp = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage) _WinAPI_DeleteObject(GUICtrlSendMsg($idPic, $STM_SETIMAGE, $IMAGE_BITMAP, $Bmp)) GUISetState() Sleep(1000) Global $a = PixelSearch(0, 0, 500, 250, 0x00FF00, 0, 1, $hGUI) If @error Then Exit 6 ConsoleWrite($a[0] & ', ' & $a[1] & @CRLF) MouseMove($a[0], $a[1]) While True $msg = GUIGetMsg() Switch $msg Case $idPic MsgBox(0, "Information", "PNG image was clicked") Case $GUI_EVENT_CLOSE _WinAPI_DeleteObject($Bmp) _GDIPlus_ImageDispose($hImage) _GDIPlus_Shutdown() GUIDelete($hGUI) Exit EndSwitch WEnd Sorry, I don't understand how this script fits into what I'm trying to do here. Is it intended to replace _FindNumberUsingColorMap in ioa747's script, or something else? The images I generate all have the same level of quality so if I can get a bitmap solution like ioa747's working on one image it *should* work on all of them. Edited November 4 by Hashim
argumentum Posted November 3 Posted November 3 1 hour ago, Hashim said: Sorry, I don't understand how this script fits into what I'm trying to do here Thought that you needed to read the number without fail. That pixlesearch() can do that, 100% correct, every time, all the time. Or just plain fail. No wrong number, ever. Hashim 1 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
Hashim Posted November 4 Posted November 4 (edited) 1 hour ago, argumentum said: Thought that you needed to read the number without fail. That pixlesearch() can do that, 100% correct, every time, all the time. Or just plain fail. No wrong number, ever. That does sound very promising, but unfortunately your script is a demo that only shows how to get the first pixel of that colour, and I can't figure out how to use the PixelSearch coordinates to actually find entire numbers, or how to plug it into ioa747's script if that's what you're suggesting - that seems like the hard part here. How would I go about doing that? Edited November 4 by Hashim
argumentum Posted November 4 Posted November 4 ..is just an idea. You'd find the 1st corner with 0x006000 or 0x00FF00, then check the color at X intervals where the 0x00FF00 ( bright green ) is at with PixelGetColor(), and if they match the array, you've got your number. Don't have the time to code it but am sure that you can do it. C'mon !, show what you are made of !!! 💪 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
ioa747 Posted November 4 Author Posted November 4 (edited) Try this part (it's one of the first ones I did) which piece only does the delimitation of the number area (and not the recognition of the pattern) where the procedures are a bit more simplified and it goes step by step, so you can figure out what the procedures are doing. expandcollapse popup#AutoIt3Wrapper_UseX64=N #include <WinAPI.au3> #include <GDIPlus.au3> #include <ScreenCapture.au3> #include <Array.au3> #include <File.au3> #include <WindowsConstants.au3> #include <MsgBoxConstants.au3> #include <Misc.au3> $aTSR = _GetTotalScreenResolution() ConsoleWrite("before -> Total Screen Resolution: " & $aTSR[0] & " x " & $aTSR[1] & @CRLF) ; Initialization DllCall("user32.dll", "bool", "SetProcessDpiAwarenessContext", "int", -4) ; -4=PerMonitorAwareV2 $aTSR = _GetTotalScreenResolution() ConsoleWrite("after -> Total Screen Resolution: " & $aTSR[0] & " x " & $aTSR[1] & @CRLF) ConsoleWrite("Desktop: " & @DesktopWidth & "x" & @DesktopHeight & @CRLF) ConsoleWrite("" & @CRLF) Global $hDLL = DllOpen("user32.dll") HotKeySet("{END}", "_Main") ; * <- selection of outer area with margin HotKeySet("{ESC}", "_Exit") ;********************************** While 1 Switch GUIGetMsg() Case -3 ;$GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd ;********************************** _Exit() Func _Exit() DllClose($hDLL) Exit EndFunc ;==>_Exit Func _Main() ; Main Program Local $aArea = SelectArea() ; Define the area to scan Local $hColor = 0x00FF00 ; Capture the color map for the specified area Local $aColorMap = CaptureAreaColorMap($aArea) ;_ArrayDisplay($aColorMap) ; set outer area manual ;_Test(61, 212, 287, 498) _Test($aArea[0], $aArea[1], $aArea[2], $aArea[3]) EndFunc ;==>_Main Func _Test($iLeft, $iTop, $iRight, $iBottom, $hColor = 0x00FF00) Local $aArea = [$iLeft, $iTop, $iRight, $iBottom] ; area to scan ; Capture the color map for the specified area Local $colorMap = CaptureAreaColorMap($aArea) ; _ArrayDisplay($colorMap) ; and then try to find digit positions Local $aNumArea = FindGreenBoundariesUsingColorMap($colorMap, $aArea, $hColor) ;Local $aNumArea = [$firstRow, $lastRow, $firstCol, $lastCol] Local $aMarkArea[4] = [$aArea[0] + $aNumArea[2], $aArea[1] + $aNumArea[0], _ $aNumArea[3] - $aNumArea[2] + 1, $aNumArea[1] - $aNumArea[0] + 1] DRC($aMarkArea, 0xFF0000, "Color_Gui") ConsoleWrite("$MarkArea: x=" & $aMarkArea[0] & ", y=" & $aMarkArea[1] & ", w=" & $aMarkArea[2] & ", h=" & $aMarkArea[3] & @CRLF) EndFunc ;==>_Test Func CaptureAreaColorMap($aArea) ; Initialize GDI+ to work with bitmaps _GDIPlus_Startup() ; Capture the screen area as a bitmap Local $hBitmap = _ScreenCapture_Capture("", $aArea[0], $aArea[1], $aArea[2], $aArea[3]) ; Convert the captured bitmap to a GDI+ bitmap Local $hGDIPlusBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap) ; Get the width and height of the captured area Local $width = $aArea[2] - $aArea[0] Local $height = $aArea[3] - $aArea[1] ; Create an array to store color values Local $colorMap[$width][$height] ; Loop through each pixel in the bitmap and retrieve its color For $y = 0 To $height - 1 For $x = 0 To $width - 1 ; Get the pixel color from the bitmap in ARGB format Local $argbColor = _GDIPlus_BitmapGetPixel($hGDIPlusBitmap, $x, $y) ; Convert ARGB to BGR for comparison (ignore the alpha channel) Local $bgrColor = BitAND($argbColor, 0x00FFFFFF) $colorMap[$x][$y] = $bgrColor Next Next ; Cleanup resources _GDIPlus_BitmapDispose($hGDIPlusBitmap) _WinAPI_DeleteObject($hBitmap) _GDIPlus_Shutdown() Return $colorMap EndFunc ;==>CaptureAreaColorMap Func FindGreenBoundariesUsingColorMap($colorMap, $aArea, $hColor = 0x00FF00) Local $width = UBound($colorMap, 1) Local $height = UBound($colorMap, 2) ConsoleWrite("$width=" & $width & ", $height=" & $height & @CRLF) Local $firstRow = -1, $lastRow = -1, $firstCol = -1, $lastCol = -1, $blockWidth = 0 ; Scan for the first row with green color For $y = 0 To $height - 1 For $x = 0 To $width - 1 If $colorMap[$x][$y] = $hColor Then $firstRow = $y ExitLoop 2 EndIf Next Next ; Scan for the last row with green color For $y = $height - 1 To 0 Step -1 For $x = 0 To $width - 1 If $colorMap[$x][$y] = $hColor Then $lastRow = $y ExitLoop 2 EndIf Next Next ; Scan for the first column with green color For $x = 0 To $width - 1 For $y = 0 To $height - 1 If $colorMap[$x][$y] = $hColor Then $firstCol = $x ExitLoop 2 EndIf Next Next ; Scan for the last column with green color For $x = $width - 1 To 0 Step -1 For $y = 0 To $height - 1 If $colorMap[$x][$y] = $hColor Then $lastCol = $x ExitLoop 2 EndIf Next Next ; find the width of block pixel For $x = $firstCol To $width - 1 For $y = $firstRow To $height - 1 If $colorMap[$x][$y] = $hColor Then For $w = $x To $width - 1 If $colorMap[$w][$y] = $hColor Then $blockWidth += 1 Else ExitLoop 3 EndIf Next EndIf Next Next $blockSize = $blockWidth / 2 ConsoleWrite("$blockSize=" & $blockSize & @CRLF) ; each number Display is a matrix of 14x20 Vpoint ; each Vpoint is a 3x3 pixel ; each number Display is 42x60 pixel ConsoleWrite("X:" & $aArea[0] & " Y:" & $aArea[1] & @CRLF) ConsoleWrite("Area firstRow:" & $firstRow & " lastRow:" & $lastRow & " firstCol:" & $firstCol & " lastCol:" & $lastCol & @CRLF) Local $aNumArea = [$firstRow, $lastRow, $firstCol, $lastCol] Return $aNumArea EndFunc ;==>FindGreenBoundariesUsingColorMap ;Original code by Larry. ;Edited by BrettF Func _GetTotalScreenResolution() Local $aRet[2] Local Const $SM_CXVIRTUALSCREEN = 78 Local Const $SM_VIRTUALHEIGHT = 79 $VirtualDesktopWidth = DllCall("user32.dll", "int", "GetSystemMetrics", "int", $SM_CXVIRTUALSCREEN) $aRet[0] = $VirtualDesktopWidth[0] $VirtualDesktopHeight = DllCall("user32.dll", "int", "GetSystemMetrics", "int", $SM_VIRTUALHEIGHT) $aRet[1] = $VirtualDesktopHeight[0] Return $aRet EndFunc ;==>_GetTotalScreenResolution ;-------------------------------------------------------------------------------------------------------------------------------- Func SelectArea() ; SelectArea Local $aRecPos[4], $aMPos[2], $tPos ;, $aTipPos[4], $iX, $iY Local $iDeskWidth, $iDeskHeight, $iDeskLeft, $iDeskTop Local $sDevice, $hMonitor, $sCurDevice, $aData, $Status = 0 ; make Capture gui $hGUICapture = GUICreate("Capture_gui", 1, 1, 1, 1, $WS_POPUP, BitOR($WS_EX_TOOLWINDOW, $WS_EX_TOPMOST)) GUISetBkColor("0xFFFF00", $hGUICapture) ; $COLOR_YELLOW WinSetTrans($hGUICapture, "", 50) ; make mouse block gui $block_gui = GUICreate("block_gui", 1, 1, 1, 1, $WS_POPUP, BitOR($WS_EX_TOOLWINDOW, $WS_EX_TOPMOST)) WinSetTrans($block_gui, "", 1) GUISetState(@SW_SHOW, $block_gui) GUISetCursor($MCID_CROSS, 1, $block_gui) Sleep(200) Local $iMaxLoop = 1200, $iCntLoop = 0 While Sleep(10) $iCntLoop += 1 If $iCntLoop = $iMaxLoop Then ExitLoop ; get mouse coordinates $tPos = _WinAPI_GetMousePos() $aMPos[0] = DllStructGetData($tPos, 1) $aMPos[1] = DllStructGetData($tPos, 2) ; get $hMonitor from previously defined Mouse coordinates $hMonitor = _WinAPI_MonitorFromPoint($tPos) ; get monitor $aData appropriate for previously defined coordinates $aData = _WinAPI_GetMonitorInfo($hMonitor) If Not @error Then $sDevice = $aData[3] $iDeskLeft = DllStructGetData($aData[0], 1) $iDeskTop = DllStructGetData($aData[0], 2) $iDeskWidth = DllStructGetData($aData[0], 3) $iDeskHeight = DllStructGetData($aData[0], 4) EndIf ;move the $block_gui to active monitor If $sCurDevice <> $sDevice Then $sCurDevice = $sDevice ;ConsoleWrite("- $sCurDevice=" & $sCurDevice & @CRLF) WinMove($block_gui, "", $iDeskLeft, $iDeskTop, $iDeskWidth, $iDeskHeight) EndIf ; whait Left_mouse_button _IsPressed If _IsPressed("01", $hDLL) Then $Status = 1 $aMPos = MouseGetPos() $aRecPos[0] = $aMPos[0] $aRecPos[1] = $aMPos[1] ; Wait until key is released. While _IsPressed("01", $hDLL) Sleep(50) $aMPos = MouseGetPos() $aRecPos[2] = $aMPos[0] $aRecPos[3] = $aMPos[1] ; show Capture gui GUISetState(@SW_SHOW, $hGUICapture) WinMove($hGUICapture, "", $aRecPos[0], $aRecPos[1], $aRecPos[2] - $aRecPos[0], $aRecPos[3] - $aRecPos[1]) WEnd ElseIf _IsPressed("1B", $hDLL) Then ;1B=ESC key - emergency exit GUIDelete($hGUICapture) GUIDelete($block_gui) Return SetError(1, 1, 0) EndIf If $Status = 1 Then ExitLoop WEnd GUIDelete($hGUICapture) GUIDelete($block_gui) ConsoleWrite("outer area: " & $aRecPos[0] & ";" & $aRecPos[1] & ";" & $aRecPos[2] + $aRecPos[0] & ";" & $aRecPos[3] + $aRecPos[1] & @CRLF) Return $aRecPos EndFunc ;==>SelectArea Func DRC($aArray, $color = 0xFFFF00, $sTitle = "Gui") Local $gGUI = GUICreate($sTitle, $aArray[2], $aArray[3], $aArray[0], $aArray[1], $WS_POPUP, $WS_EX_TRANSPARENT) GUISetBkColor($color) WinSetTrans($gGUI, '', 150) GUISetState(@SW_SHOW, $gGUI) Return $gGUI EndFunc ;==>DRC My console output before -> Total Screen Resolution: 3840 x 1341 after -> Total Screen Resolution: 5760 x 2160 Desktop: 1920x1080 outer area: 124;273;426;670 $width=178, $height=124 $blockSize=3 X:124 Y:273 Area firstRow:29 lastRow:88 firstCol:43 lastCol:123 $MarkArea: x=167, y=302, w=81, h=60 P.S.: upload some numbers to 100% like this to make the rest num patterns and some test Edited November 4 by ioa747 remove Do, Until Hashim and argumentum 2 I know that I know nothing
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now