Jump to content

Loop over 1M numbers fails on 9964th iteration


Recommended Posts

I'm working with a proprietary in-house tool that takes a 6-digit serial number and displays 3-digit output (actually it expects a 7-digit input but the first digit is a check digit that it isn't necessary to change for my purposes). I've been tasked with outputting 1 million serial number inputs in the range 000000-999999 to a CSV file with their corresponding outputs. Thanks to ioa747 I now have a bitmap-based solution that accurately detects the output from the application for this purpose, which I've wrapped in a (non-Functional but perfectly functional) loop. The whole script works without issue except for a really weird bug that throws a fatal but completely empty error on the 9964th (or possibly 9965th) iteration of the loop.

I've reproduced this at least 6 times while incrementing the start of the loop each time (and successfully written the first ~60,000 lines to the file in this way), so the problem is definitely the nth iteration of the loop rather than any particular serial number.

Adding a file exists condition prevents the program from crashing with the useless error, so this tells me the issue is the GDI functions suddenly not saving screenshots, maybe because of memory usage, but all the functions using GDI seem to have clean up functions and the system I'm working on has 16GB of RAM, so I'd be surprised if it's running out unless there's a memory leak somewhere.

Also, at its current rate the script will take a few days to output the entire dataset, so I'd also welcome any optimisations that anyone can think of to make it more efficient.

Here's the code for my own script, which also contains ioa747's custom _ScreenCapture function:

#cs ----------------------------------------------------------------------------

 AutoIt Version: 3.3.16.1
 Author:         Hashim

 Script Function:
    Template AutoIt script.

#ce ----------------------------------------------------------------------------
#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"
#include "Bitmap Digit Identifier.au3" ; https://www.autoitscript.com/forum/topic/211521-ocr-from-a-small-area/?do=findComment&comment=1538057

Run("Tool.exe");
Local $tool = WinWaitActive("Tool", "", 3)
ControlClick($tool, "", "TTabSheet1", "primary", 1, 210, 50)
ControlCommand($tool, "" , "TFlatComboBox1" , "SelectString" , "Old")

$db = FileOpen(@ScriptDir & "\tool-db.txt", 1)

DirRemove ("Bitmap ID Failed", 1)
DirCreate ("Bitmap ID Failed")

For $loop = 0 To 999999

    $serial = StringFormat('%06i', $loop)

    ControlSetText($tool, "", "TFlatMaskEdit3", "S.N: 9" & $serial) ; Enter serial number prefixed with the check digit
    ControlClick($tool, "", "TTabSheet1", "primary", 1, 69, 50) ; Press "Generate"

    $sImageResult = _ScreenCapture(@ScriptDir & "\Bitmap ID Failed\" & $serial & ".png", 792, 450, 927, 480)

    If Not FileExists($sImageResult) Then
        MsgBox(0, "Error encountered...", "No image found for serial of " & $serial)
        Exit
    EndIf

    Local $code = _GetNumber($sImageResult)
    If (StringLen($code) = 3 or StringIsDigit($code)) Then FileDelete($sImageResult)

    FileWrite($db, $serial & "," & $output & @LF)
Next

FileClose($db)

; #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, $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)
    $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap)

    ; Add Border
    If $iBorder > 0 Then
        $iBorderColor = _GDIPlus_BitmapGetPixel($hBitmap, 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, $hBitmap, $iBorder, $iBorder)

        _GDIPlus_ImageDispose($hBitmap)
    Else
        $hImage = $hBitmap
    EndIf

    $vRet = _GDIPlus_ImageSaveToFile($hImage, $sFileName)  ;save bitmap to disk
    If @error Then Return SetError(4, 0, False)
    If $vRet Then $vRet = $sFileName

    _WinAPI_DeleteObject($hHBitmap)
    _GDIPlus_BitmapDispose($hImage)
    _GDIPlus_BitmapDispose($hBitmap)
    _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 .........:
;--------------------------------------------------------------------------------------------------------------------------------
Exit

 

And here is ioa747's bitmap script, it's basically untouched except I removed the test() and main() functions, instead I just call _getNumber() directly from within my loop above.

 

#cs ----------------------------------------------------------------------------

 AutoIt Version: 3.3.16.1
 Author:         ioa747 (https://www.autoitscript.com/forum/topic/211521-ocr-from-a-small-area/?do=findComment&comment=1538057)
 Version:        4.0

 Script Function:
    Template AutoIt script.


#ce ----------------------------------------------------------------------------

#include <GDIPlus.au3>
#include <Array.au3>
#include <File.au3>

;--------------------------------------------------------------------------------------------------------------------------------
Func _GetNumber($sFileName, $hColor = 0x00FF00)   ; Main Program
    ; Capture the color map for the specified area
    Local $aColorMap = CaptureAreaColorMap($sFileName)
;~  _ArrayDisplay($aColorMap)

    Local $Result = FindNumberUsingColorMap($aColorMap, $hColor)
;~  MsgBox($MB_SYSTEMMODAL, "$Result", $Result)
    Return $Result
EndFunc   ;==>_GetNumber
;--------------------------------------------------------------------------------------------------------------------------------
Func CaptureAreaColorMap($sFileName)   ; create color map array
    ; Initialize GDI+ to work with bitmaps
    _GDIPlus_Startup()

    ; Capture the screen area as a bitmap
    Local $hBitmap = _GDIPlus_BitmapCreateFromFile($sFileName)

    ; Get the width and height of the captured area
    Local $width = _GDIPlus_ImageGetWidth($hBitmap)
    Local $height = _GDIPlus_ImageGetHeight($hBitmap)
;~  ConsoleWrite("Image: $width=" & $width & ", $height=" & $height & @CRLF)

    ; 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($hBitmap, $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($hBitmap)
    _GDIPlus_Shutdown()

    Return $aColorMap
EndFunc   ;==>CaptureAreaColorMap
;--------------------------------------------------------------------------------------------------------------------------------
Func FindNumberUsingColorMap($aColorMap, $hColor = 0x00FF00)   ; find number in color map array
    Local $width = UBound($aColorMap, 1)
    Local $height = UBound($aColorMap, 2)

    Local $firstRow = -1, $lastRow = -1, $firstCol = -1, $lastCol = -1

    ; Scan for the first and last rows and columns with $hColor 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

    ; each number Display is a matrix of 14x20 pixels
    Local $numberWidth = 14 ; set number width per digit
    Local $numberSpace = 2  ; set Space between digits

    Local $Empty = 0, $Corection = 0

    ; Corection for boundaries if 1st digit = 1
    For $x = $firstCol To $lastCol - 1
        If $aColorMap[$x][$firstRow] = 0x000000 Then
            $Empty += 1
            If $Empty = 3 Then
                ;found 1st Space between digits
                $Corection = $firstCol - 1 - Abs($x - $numberWidth - $numberSpace)
                ExitLoop
            EndIf
        Else
            $Empty = 0
        EndIf
    Next

    If $Corection > 0 Then $firstCol = $firstCol - $Corection

    Local $numberStart = $firstCol

;~  ConsoleWrite("$Corection=" & $Corection & @CRLF)
;~  ConsoleWrite("Display_boundaries firstRow:" & $firstRow & " lastRow:" & $lastRow & " firstCol:" & $firstCol & " lastCol:" & $lastCol & @CRLF)
;~  ConsoleWrite("" & @CRLF)

    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 &= _GetPattern($sPattern)
    Next

    Return $sNumber
EndFunc   ;==>FindNumberUsingColorMap
;--------------------------------------------------------------------------------------------------------------------------------
Func _GetPattern($sPattern)  ; patterns for each digit
;~  ConsoleWrite("**************" & @CRLF & $sPattern & @CRLF)
    Local $aNumber[10]

    ; Define simplified patterns for each digit

    $aNumber[0] = "" ; Pattern for '0'
    $aNumber[0] &= "...11.11.11..." & @CRLF
    $aNumber[0] &= "...11.11.11..." & @CRLF
    $aNumber[0] &= ".............." & @CRLF
    $aNumber[0] &= "11..........11" & @CRLF
    $aNumber[0] &= "11..........11" & @CRLF
    $aNumber[0] &= ".............." & @CRLF
    $aNumber[0] &= "11.......11.11" & @CRLF
    $aNumber[0] &= "11.......11.11" & @CRLF
    $aNumber[0] &= ".............." & @CRLF
    $aNumber[0] &= "11....11....11" & @CRLF
    $aNumber[0] &= "11....11....11" & @CRLF
    $aNumber[0] &= ".............." & @CRLF
    $aNumber[0] &= "11.11.......11" & @CRLF
    $aNumber[0] &= "11.11.......11" & @CRLF
    $aNumber[0] &= ".............." & @CRLF
    $aNumber[0] &= "11..........11" & @CRLF
    $aNumber[0] &= "11..........11" & @CRLF
    $aNumber[0] &= ".............." & @CRLF
    $aNumber[0] &= "...11.11.11..." & @CRLF
    $aNumber[0] &= "...11.11.11..." & @CRLF


    $aNumber[1] = "" ; Pattern for '1'
    $aNumber[1] &= "......11......" & @CRLF
    $aNumber[1] &= "......11......" & @CRLF
    $aNumber[1] &= ".............." & @CRLF
    $aNumber[1] &= "...11.11......" & @CRLF
    $aNumber[1] &= "...11.11......" & @CRLF
    $aNumber[1] &= ".............." & @CRLF
    $aNumber[1] &= "......11......" & @CRLF
    $aNumber[1] &= "......11......" & @CRLF
    $aNumber[1] &= ".............." & @CRLF
    $aNumber[1] &= "......11......" & @CRLF
    $aNumber[1] &= "......11......" & @CRLF
    $aNumber[1] &= ".............." & @CRLF
    $aNumber[1] &= "......11......" & @CRLF
    $aNumber[1] &= "......11......" & @CRLF
    $aNumber[1] &= ".............." & @CRLF
    $aNumber[1] &= "......11......" & @CRLF
    $aNumber[1] &= "......11......" & @CRLF
    $aNumber[1] &= ".............." & @CRLF
    $aNumber[1] &= "...11.11.11..." & @CRLF
    $aNumber[1] &= "...11.11.11..." & @CRLF


    $aNumber[2] = "" ; Pattern for '2'
    $aNumber[2] &= "...11.11.11..." & @CRLF
    $aNumber[2] &= "...11.11.11..." & @CRLF
    $aNumber[2] &= ".............." & @CRLF
    $aNumber[2] &= "11..........11" & @CRLF
    $aNumber[2] &= "11..........11" & @CRLF
    $aNumber[2] &= ".............." & @CRLF
    $aNumber[2] &= "............11" & @CRLF
    $aNumber[2] &= "............11" & @CRLF
    $aNumber[2] &= ".............." & @CRLF
    $aNumber[2] &= "......11.11..." & @CRLF
    $aNumber[2] &= "......11.11..." & @CRLF
    $aNumber[2] &= ".............." & @CRLF
    $aNumber[2] &= "...11........." & @CRLF
    $aNumber[2] &= "...11........." & @CRLF
    $aNumber[2] &= ".............." & @CRLF
    $aNumber[2] &= "11............" & @CRLF
    $aNumber[2] &= "11............" & @CRLF
    $aNumber[2] &= ".............." & @CRLF
    $aNumber[2] &= "11.11.11.11.11" & @CRLF
    $aNumber[2] &= "11.11.11.11.11" & @CRLF


    $aNumber[3] = "" ; Pattern for '3'
    $aNumber[3] &= "...11.11.11..." & @CRLF
    $aNumber[3] &= "...11.11.11..." & @CRLF
    $aNumber[3] &= ".............." & @CRLF
    $aNumber[3] &= "11..........11" & @CRLF
    $aNumber[3] &= "11..........11" & @CRLF
    $aNumber[3] &= ".............." & @CRLF
    $aNumber[3] &= "............11" & @CRLF
    $aNumber[3] &= "............11" & @CRLF
    $aNumber[3] &= ".............." & @CRLF
    $aNumber[3] &= "......11.11..." & @CRLF
    $aNumber[3] &= "......11.11..." & @CRLF
    $aNumber[3] &= ".............." & @CRLF
    $aNumber[3] &= "............11" & @CRLF
    $aNumber[3] &= "............11" & @CRLF
    $aNumber[3] &= ".............." & @CRLF
    $aNumber[3] &= "11..........11" & @CRLF
    $aNumber[3] &= "11..........11" & @CRLF
    $aNumber[3] &= ".............." & @CRLF
    $aNumber[3] &= "...11.11.11..." & @CRLF
    $aNumber[3] &= "...11.11.11..." & @CRLF


    $aNumber[4] = "" ; Pattern for '4'
    $aNumber[4] &= ".........11..." & @CRLF
    $aNumber[4] &= ".........11..." & @CRLF
    $aNumber[4] &= ".............." & @CRLF
    $aNumber[4] &= "......11.11..." & @CRLF
    $aNumber[4] &= "......11.11..." & @CRLF
    $aNumber[4] &= ".............." & @CRLF
    $aNumber[4] &= "...11....11..." & @CRLF
    $aNumber[4] &= "...11....11..." & @CRLF
    $aNumber[4] &= ".............." & @CRLF
    $aNumber[4] &= "11.......11..." & @CRLF
    $aNumber[4] &= "11.......11..." & @CRLF
    $aNumber[4] &= ".............." & @CRLF
    $aNumber[4] &= "11.11.11.11.11" & @CRLF
    $aNumber[4] &= "11.11.11.11.11" & @CRLF
    $aNumber[4] &= ".............." & @CRLF
    $aNumber[4] &= ".........11..." & @CRLF
    $aNumber[4] &= ".........11..." & @CRLF
    $aNumber[4] &= ".............." & @CRLF
    $aNumber[4] &= ".........11..." & @CRLF
    $aNumber[4] &= ".........11..." & @CRLF


    $aNumber[5] = "" ; Pattern for '5'
    $aNumber[5] &= "11.11.11.11.11" & @CRLF
    $aNumber[5] &= "11.11.11.11.11" & @CRLF
    $aNumber[5] &= ".............." & @CRLF
    $aNumber[5] &= "11............" & @CRLF
    $aNumber[5] &= "11............" & @CRLF
    $aNumber[5] &= ".............." & @CRLF
    $aNumber[5] &= "11.11.11.11..." & @CRLF
    $aNumber[5] &= "11.11.11.11..." & @CRLF
    $aNumber[5] &= ".............." & @CRLF
    $aNumber[5] &= "............11" & @CRLF
    $aNumber[5] &= "............11" & @CRLF
    $aNumber[5] &= ".............." & @CRLF
    $aNumber[5] &= "............11" & @CRLF
    $aNumber[5] &= "............11" & @CRLF
    $aNumber[5] &= ".............." & @CRLF
    $aNumber[5] &= "11..........11" & @CRLF
    $aNumber[5] &= "11..........11" & @CRLF
    $aNumber[5] &= ".............." & @CRLF
    $aNumber[5] &= "...11.11.11..." & @CRLF
    $aNumber[5] &= "...11.11.11..." & @CRLF


    $aNumber[6] = "" ; Pattern for '6'
    $aNumber[6] &= "......11.11..." & @CRLF
    $aNumber[6] &= "......11.11..." & @CRLF
    $aNumber[6] &= ".............." & @CRLF
    $aNumber[6] &= "...11........." & @CRLF
    $aNumber[6] &= "...11........." & @CRLF
    $aNumber[6] &= ".............." & @CRLF
    $aNumber[6] &= "11............" & @CRLF
    $aNumber[6] &= "11............" & @CRLF
    $aNumber[6] &= ".............." & @CRLF
    $aNumber[6] &= "11.11.11.11..." & @CRLF
    $aNumber[6] &= "11.11.11.11..." & @CRLF
    $aNumber[6] &= ".............." & @CRLF
    $aNumber[6] &= "11..........11" & @CRLF
    $aNumber[6] &= "11..........11" & @CRLF
    $aNumber[6] &= ".............." & @CRLF
    $aNumber[6] &= "11..........11" & @CRLF
    $aNumber[6] &= "11..........11" & @CRLF
    $aNumber[6] &= ".............." & @CRLF
    $aNumber[6] &= "...11.11.11..." & @CRLF
    $aNumber[6] &= "...11.11.11..." & @CRLF

    $aNumber[7] = "" ; Pattern for '7'
    $aNumber[7] &= "11.11.11.11.11" & @CRLF
    $aNumber[7] &= "11.11.11.11.11" & @CRLF
    $aNumber[7] &= ".............." & @CRLF
    $aNumber[7] &= "............11" & @CRLF
    $aNumber[7] &= "............11" & @CRLF
    $aNumber[7] &= ".............." & @CRLF
    $aNumber[7] &= ".........11..." & @CRLF
    $aNumber[7] &= ".........11..." & @CRLF
    $aNumber[7] &= ".............." & @CRLF
    $aNumber[7] &= "......11......" & @CRLF
    $aNumber[7] &= "......11......" & @CRLF
    $aNumber[7] &= ".............." & @CRLF
    $aNumber[7] &= "...11........." & @CRLF
    $aNumber[7] &= "...11........." & @CRLF
    $aNumber[7] &= ".............." & @CRLF
    $aNumber[7] &= "...11........." & @CRLF
    $aNumber[7] &= "...11........." & @CRLF
    $aNumber[7] &= ".............." & @CRLF
    $aNumber[7] &= "...11........." & @CRLF
    $aNumber[7] &= "...11........." & @CRLF

    $aNumber[8] = "" ; Pattern for '8'
    $aNumber[8] &= "...11.11.11..." & @CRLF
    $aNumber[8] &= "...11.11.11..." & @CRLF
    $aNumber[8] &= ".............." & @CRLF
    $aNumber[8] &= "11..........11" & @CRLF
    $aNumber[8] &= "11..........11" & @CRLF
    $aNumber[8] &= ".............." & @CRLF
    $aNumber[8] &= "11..........11" & @CRLF
    $aNumber[8] &= "11..........11" & @CRLF
    $aNumber[8] &= ".............." & @CRLF
    $aNumber[8] &= "...11.11.11..." & @CRLF
    $aNumber[8] &= "...11.11.11..." & @CRLF
    $aNumber[8] &= ".............." & @CRLF
    $aNumber[8] &= "11..........11" & @CRLF
    $aNumber[8] &= "11..........11" & @CRLF
    $aNumber[8] &= ".............." & @CRLF
    $aNumber[8] &= "11..........11" & @CRLF
    $aNumber[8] &= "11..........11" & @CRLF
    $aNumber[8] &= ".............." & @CRLF
    $aNumber[8] &= "...11.11.11..." & @CRLF
    $aNumber[8] &= "...11.11.11..." & @CRLF

    $aNumber[9] = "" ; Pattern for '9'
    $aNumber[9] &= "...11.11.11..." & @CRLF
    $aNumber[9] &= "...11.11.11..." & @CRLF
    $aNumber[9] &= ".............." & @CRLF
    $aNumber[9] &= "11..........11" & @CRLF
    $aNumber[9] &= "11..........11" & @CRLF
    $aNumber[9] &= ".............." & @CRLF
    $aNumber[9] &= "11..........11" & @CRLF
    $aNumber[9] &= "11..........11" & @CRLF
    $aNumber[9] &= ".............." & @CRLF
    $aNumber[9] &= "...11.11.11.11" & @CRLF
    $aNumber[9] &= "...11.11.11.11" & @CRLF
    $aNumber[9] &= ".............." & @CRLF
    $aNumber[9] &= "............11" & @CRLF
    $aNumber[9] &= "............11" & @CRLF
    $aNumber[9] &= ".............." & @CRLF
    $aNumber[9] &= ".........11..." & @CRLF
    $aNumber[9] &= ".........11..." & @CRLF
    $aNumber[9] &= ".............." & @CRLF
    $aNumber[9] &= "...11.11......" & @CRLF
    $aNumber[9] &= "...11.11......" & @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   ;==>_GetPattern
Edited by Hashim
Link to comment
Share on other sites

Could you post a screenshot of Tools.exe, so we can see what it looks like. (blur out any secrets).

Shouldnt be necessary with all the screengrab, files and color conversions, or checking for the whole pattern of each number, instead of just a small unique part.

But please, screenshot of tools.exe.

Some guy's script + some other guy's script = my script!

Link to comment
Share on other sites

Something looks wrong in the _ScreenCapture.  You are reusing the same variable for 2 different purposes (without cleaning up the memory) :

Here :

$hBitmap = _WinAPI_AdjustBitmap($hHBitmap, $iBmpW, $iBmpH, $HALFTONE, $tAdj)

and there :

$hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap)

That must create major memory leak, IMO.

Link to comment
Share on other sites

For $n = 0 To 100
    $aProcessMemoryInfo = _WinAPI_GetProcessMemoryInfo()
    ConsoleWrite( _GetNumber(@ScriptDir & "\code__51" & StringRight($n, 1) & "___.png") & @TAB & 'The peak working set: ' & $aProcessMemoryInfo[1] / 1024 / 1024 & ' MB'& @CRLF)
Next
510 The peak working set: 29.23046875 MB
511 The peak working set: 30.31640625 MB
512 The peak working set: 30.4375 MB
513 The peak working set: 30.47265625 MB
514 The peak working set: 30.484375 MB
515 The peak working set: 30.5 MB
516 The peak working set: 30.50390625 MB
517 The peak working set: 30.5078125 MB
518 The peak working set: 30.515625 MB
519 The peak working set: 30.5234375 MB
510 The peak working set: 30.5234375 MB
511 The peak working set: 30.5234375 MB
512 The peak working set: 30.53125 MB
513 The peak working set: 30.53125 MB
514 The peak working set: 30.54296875 MB
515 The peak working set: 30.54296875 MB
516 The peak working set: 30.546875 MB
517 The peak working set: 30.5546875 MB
518 The peak working set: 30.5546875 MB
519 The peak working set: 30.5546875 MB
510 The peak working set: 30.5546875 MB
511 The peak working set: 30.5546875 MB
512 The peak working set: 30.5546875 MB
513 The peak working set: 30.5546875 MB
514 The peak working set: 30.5546875 MB
515 The peak working set: 30.5546875 MB
516 The peak working set: 30.5546875 MB
517 The peak working set: 30.5546875 MB
518 The peak working set: 30.5546875 MB
519 The peak working set: 30.5546875 MB
510 The peak working set: 30.5546875 MB
511 The peak working set: 30.5546875 MB
512 The peak working set: 30.5703125 MB
513 The peak working set: 30.57421875 MB
514 The peak working set: 30.57421875 MB
515 The peak working set: 30.578125 MB
516 The peak working set: 30.578125 MB
517 The peak working set: 30.59375 MB
518 The peak working set: 30.59375 MB
519 The peak working set: 30.59375 MB
510 The peak working set: 30.59375 MB
511 The peak working set: 30.59375 MB
512 The peak working set: 30.59375 MB
513 The peak working set: 30.59375 MB
514 The peak working set: 30.59375 MB
515 The peak working set: 30.59375 MB
516 The peak working set: 30.59375 MB
517 The peak working set: 30.59375 MB
518 The peak working set: 30.59375 MB
519 The peak working set: 30.59375 MB
510 The peak working set: 30.59765625 MB
511 The peak working set: 30.59765625 MB
512 The peak working set: 30.6015625 MB
513 The peak working set: 30.6015625 MB
514 The peak working set: 30.6015625 MB
515 The peak working set: 30.6015625 MB
516 The peak working set: 30.609375 MB
517 The peak working set: 30.61328125 MB
518 The peak working set: 30.62109375 MB
519 The peak working set: 30.62109375 MB
510 The peak working set: 30.625 MB
511 The peak working set: 30.62890625 MB
512 The peak working set: 30.62890625 MB
513 The peak working set: 30.63671875 MB
514 The peak working set: 30.640625 MB
515 The peak working set: 30.640625 MB
516 The peak working set: 30.64453125 MB
517 The peak working set: 30.65234375 MB
518 The peak working set: 30.65234375 MB
519 The peak working set: 30.65234375 MB
510 The peak working set: 30.671875 MB
511 The peak working set: 30.68359375 MB
512 The peak working set: 30.6875 MB
513 The peak working set: 30.6875 MB
514 The peak working set: 30.69140625 MB
515 The peak working set: 30.6953125 MB
516 The peak working set: 30.6953125 MB
517 The peak working set: 30.6953125 MB
518 The peak working set: 30.6953125 MB
519 The peak working set: 30.6953125 MB
510 The peak working set: 30.6953125 MB
511 The peak working set: 30.6953125 MB
512 The peak working set: 30.6953125 MB
513 The peak working set: 30.6953125 MB
514 The peak working set: 30.6953125 MB
515 The peak working set: 30.6953125 MB
516 The peak working set: 30.6953125 MB
517 The peak working set: 30.6953125 MB
518 The peak working set: 30.6953125 MB
519 The peak working set: 30.6953125 MB
510 The peak working set: 30.6953125 MB
511 The peak working set: 30.6953125 MB
512 The peak working set: 30.6953125 MB
513 The peak working set: 30.6953125 MB
514 The peak working set: 30.6953125 MB
515 The peak working set: 30.6953125 MB
516 The peak working set: 30.6953125 MB
517 The peak working set: 30.6953125 MB
518 The peak working set: 30.6953125 MB
519 The peak working set: 30.6953125 MB
510 The peak working set: 30.6953125 MB

..in just 100 _GetNumber() the memory increases 2 MB.  It's got sporadic jumps in memory usage ?

Edited by argumentum
reviewed

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Link to comment
Share on other sites

3 hours ago, Werty said:

Could you post a screenshot of Tools.exe, so we can see what it looks like. (blur out any secrets).

Shouldnt be necessary with all the screengrab, files and color conversions, or checking for the whole pattern of each number, instead of just a small unique part.

But please, screenshot of tools.exe.

Unfortunately not, I've already revealed too much just to get this working and the client is known to be litigious so I'd rather not risk that. However I don't think a screenshot of the application is needed to fix this issue as the issue doesn't lie elsewhere in the application - the necessary part of it is being screenshotted fine right up until the moment it's not. I've also verified the loop carries on without issue when not taking screenshots, so it seems increasingly likely the issue is GDI failing to take/save a screenshot on the 9664th iteration.

The current version is actually not doing any colour conversions or scaling so I don't actually need that custom function anymore, I've decided to replace it with the underlying _ScreenCapture UDF. It's true a memory-only solution that doesn't save every image to the filesystem would be a lot faster, but it will probably be easier to get it working this way first before refactoring to an even more memory-intensive version.

 

3 hours ago, Nine said:

Something looks wrong in the _ScreenCapture.  You are reusing the same variable for 2 different purposes (without cleaning up the memory) :

Here :

$hBitmap = _WinAPI_AdjustBitmap($hHBitmap, $iBmpW, $iBmpH, $HALFTONE, $tAdj)

and there :

$hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap)

That must create major memory leak, IMO.

Good shout, unfortunately changing the first one to $hBitmapAdj and replacing the reference on the second line still doesn't fix this, so it doesn't look like the 9664 bug is being caused by this. However I have now removed that custom function entirely so that should simplify things quite a bit.

Link to comment
Share on other sites

49 minutes ago, argumentum said:
For $n = 0 To 100
    $aProcessMemoryInfo = _WinAPI_GetProcessMemoryInfo()
    ConsoleWrite( _GetNumber(@ScriptDir & "\code__51" & StringRight($n, 1) & "___.png") & @TAB & 'The peak working set: ' & $aProcessMemoryInfo[1] / 1024 / 1024 & ' MB'& @CRLF)
Next
510 The peak working set: 29.23046875 MB
511 The peak working set: 30.31640625 MB
512 The peak working set: 30.4375 MB
513 The peak working set: 30.47265625 MB
514 The peak working set: 30.484375 MB
515 The peak working set: 30.5 MB
516 The peak working set: 30.50390625 MB
517 The peak working set: 30.5078125 MB
518 The peak working set: 30.515625 MB
519 The peak working set: 30.5234375 MB
510 The peak working set: 30.5234375 MB
511 The peak working set: 30.5234375 MB
512 The peak working set: 30.53125 MB
513 The peak working set: 30.53125 MB
514 The peak working set: 30.54296875 MB
515 The peak working set: 30.54296875 MB
516 The peak working set: 30.546875 MB
517 The peak working set: 30.5546875 MB
518 The peak working set: 30.5546875 MB
519 The peak working set: 30.5546875 MB
510 The peak working set: 30.5546875 MB
511 The peak working set: 30.5546875 MB
512 The peak working set: 30.5546875 MB
513 The peak working set: 30.5546875 MB
514 The peak working set: 30.5546875 MB
515 The peak working set: 30.5546875 MB
516 The peak working set: 30.5546875 MB
517 The peak working set: 30.5546875 MB
518 The peak working set: 30.5546875 MB
519 The peak working set: 30.5546875 MB
510 The peak working set: 30.5546875 MB
511 The peak working set: 30.5546875 MB
512 The peak working set: 30.5703125 MB
513 The peak working set: 30.57421875 MB
514 The peak working set: 30.57421875 MB
515 The peak working set: 30.578125 MB
516 The peak working set: 30.578125 MB
517 The peak working set: 30.59375 MB
518 The peak working set: 30.59375 MB
519 The peak working set: 30.59375 MB
510 The peak working set: 30.59375 MB
511 The peak working set: 30.59375 MB
512 The peak working set: 30.59375 MB
513 The peak working set: 30.59375 MB
514 The peak working set: 30.59375 MB
515 The peak working set: 30.59375 MB
516 The peak working set: 30.59375 MB
517 The peak working set: 30.59375 MB
518 The peak working set: 30.59375 MB
519 The peak working set: 30.59375 MB
510 The peak working set: 30.59765625 MB
511 The peak working set: 30.59765625 MB
512 The peak working set: 30.6015625 MB
513 The peak working set: 30.6015625 MB
514 The peak working set: 30.6015625 MB
515 The peak working set: 30.6015625 MB
516 The peak working set: 30.609375 MB
517 The peak working set: 30.61328125 MB
518 The peak working set: 30.62109375 MB
519 The peak working set: 30.62109375 MB
510 The peak working set: 30.625 MB
511 The peak working set: 30.62890625 MB
512 The peak working set: 30.62890625 MB
513 The peak working set: 30.63671875 MB
514 The peak working set: 30.640625 MB
515 The peak working set: 30.640625 MB
516 The peak working set: 30.64453125 MB
517 The peak working set: 30.65234375 MB
518 The peak working set: 30.65234375 MB
519 The peak working set: 30.65234375 MB
510 The peak working set: 30.671875 MB
511 The peak working set: 30.68359375 MB
512 The peak working set: 30.6875 MB
513 The peak working set: 30.6875 MB
514 The peak working set: 30.69140625 MB
515 The peak working set: 30.6953125 MB
516 The peak working set: 30.6953125 MB
517 The peak working set: 30.6953125 MB
518 The peak working set: 30.6953125 MB
519 The peak working set: 30.6953125 MB
510 The peak working set: 30.6953125 MB
511 The peak working set: 30.6953125 MB
512 The peak working set: 30.6953125 MB
513 The peak working set: 30.6953125 MB
514 The peak working set: 30.6953125 MB
515 The peak working set: 30.6953125 MB
516 The peak working set: 30.6953125 MB
517 The peak working set: 30.6953125 MB
518 The peak working set: 30.6953125 MB
519 The peak working set: 30.6953125 MB
510 The peak working set: 30.6953125 MB
511 The peak working set: 30.6953125 MB
512 The peak working set: 30.6953125 MB
513 The peak working set: 30.6953125 MB
514 The peak working set: 30.6953125 MB
515 The peak working set: 30.6953125 MB
516 The peak working set: 30.6953125 MB
517 The peak working set: 30.6953125 MB
518 The peak working set: 30.6953125 MB
519 The peak working set: 30.6953125 MB
510 The peak working set: 30.6953125 MB

..in just 100 _GetNumber() the memory increases 2 MB.  It's got sporadic jumps in memory usage ?

 

Thanks for this, these results look stable to me but I suppose that's expected for a simple loop. I'll implement in my own loop after all the GDI disposal and see what the results look like.

Edited by Hashim
Link to comment
Share on other sites

51 minutes ago, Hashim said:

unfortunately changing the first one to $hBitmapAdj and replacing the reference on the second line still doesn't fix this

You need to delete the object otherwise it is just as useless as using the same variable

ps. next time, post a runable script that we actually can run that shows the issue, otherwise it is just a guessing game

Edited by Nine
Link to comment
Share on other sites

21 minutes ago, Nine said:

You need to delete the object otherwise it is just as useless as using the same variable

ps. next time, post a runable script that we actually can run that shows the issue, otherwise it is just a guessing game

Good point, I completely forgot about disposal. This may well have been the issue as I've just tested again after replacing the _GetCapture wrapper function with using _ScreenCapture directly, and have managed to successfully get past 15,000 iterations! Either way it seems the bug was somewhere in that wrapper function, which isn't surprising since ioa747 didn't write it with this level of abuse in mind, but good to know anyway for anyone that does actually need its scaling and adjustment functions.

Link to comment
Share on other sites

if the "\Bitmap ID Failed\" folder is placed on a ram drive
the process will speed up significantly
 

; Version: 5.0

#include <GDIPlus.au3>
#include <Array.au3>
#include <File.au3>

;~ Local $Result = _GetNumber(@ScriptDir & "\100num\152.png")
;~ MsgBox($MB_SYSTEMMODAL, "_GetNumber", $Result)

Test()

;--------------------------------------------------------------------------------------------------------------------------------
Func _Exit()   ; Cleanup & exit
    ; Cleanup resources
    _GDIPlus_Shutdown()
    
    Exit
EndFunc
;--------------------------------------------------------------------------------------------------------------------------------
Func _GetNumber($sFileName, $hColor = 0x00FF00)   ; Main Program
    ; Initialize GDI+ to work with bitmaps
    _GDIPlus_Startup()

    ; Capture the color map for the specified area
    Local $aColorMap = CaptureAreaColorMap($sFileName)
    If @error = 1 Then
        MsgBox($MB_SYSTEMMODAL, "LineNumber:" & @ScriptLineNumber, "Path was invalid.")
        _Exit()
    EndIf

;~  _ArrayDisplay($aColorMap)

    Local $Result = FindNumberUsingColorMap($aColorMap, $hColor)
;~  MsgBox($MB_SYSTEMMODAL, "$Result", $Result)

    ; Cleanup resources
    _GDIPlus_Shutdown()

    Return $Result
EndFunc   ;==>_GetNumber
;--------------------------------------------------------------------------------------------------------------------------------
Func CaptureAreaColorMap($sFileName)   ; create color map array

    ; Capture the screen area as a bitmap
    Local $hBitmap = _GDIPlus_BitmapCreateFromFile($sFileName)
    If @error Then Return SetError(1, 0, "") ; because the user ( me ) might do the unexpected  ;)

    ; Get the width and height of the captured area
    Local $width = _GDIPlus_ImageGetWidth($hBitmap)
    Local $height = _GDIPlus_ImageGetHeight($hBitmap)
;~  ConsoleWrite("Image: $width=" & $width & ", $height=" & $height & @CRLF)

    ; 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($hBitmap, $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($hBitmap)

    Return $aColorMap
EndFunc   ;==>CaptureAreaColorMap
;--------------------------------------------------------------------------------------------------------------------------------
Func FindNumberUsingColorMap($aColorMap, $hColor = 0x00FF00)   ; find number in color map array
    Local $width = UBound($aColorMap, 1)
    Local $height = UBound($aColorMap, 2)

    Local $firstRow = -1, $lastRow = -1, $firstCol = -1, $lastCol = -1

    ; Scan for the first and last rows and columns with $hColor 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

    ; each number Display is a matrix of 14x20 pixels
    Local $numberWidth = 14 ; set number width per digit
    Local $numberSpace = 2  ; set Space between digits

    Local $Empty = 0, $Corection = 0

    ; Corection for boundaries if 1st digit = 1
    For $x = $firstCol To $lastCol - 1
        If $aColorMap[$x][$firstRow] = 0x000000 Then
            $Empty += 1
            If $Empty = 3 Then
                ;found 1st Space between digits
                $Corection = $firstCol - 1 - Abs($x - $numberWidth - $numberSpace)
                ExitLoop
            EndIf
        Else
            $Empty = 0
        EndIf
    Next

    If $Corection > 0 Then $firstCol = $firstCol - $Corection

    Local $numberStart = $firstCol

;~  ConsoleWrite("$Corection=" & $Corection & @CRLF)
;~  ConsoleWrite("Display_boundaries firstRow:" & $firstRow & " lastRow:" & $lastRow & " firstCol:" & $firstCol & " lastCol:" & $lastCol & @CRLF)
;~  ConsoleWrite("" & @CRLF)

    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
;~  _ArrayDisplay($aNum)
    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 &= _GetPattern($sPattern)
    Next

    Return $sNumber
EndFunc   ;==>FindNumberUsingColorMap
;--------------------------------------------------------------------------------------------------------------------------------
Func _GetPattern($sPattern)  ; patterns for each digit
;~  ConsoleWrite("**************" & @CRLF & $sPattern & @CRLF)
    Local $aNumber[10]

    ; Define simplified patterns for each digit

    $aNumber[0] = "" ; Pattern for '0'
    $aNumber[0] &= "...11.11.11..." & @CRLF
    $aNumber[0] &= "...11.11.11..." & @CRLF
    $aNumber[0] &= ".............." & @CRLF
    $aNumber[0] &= "11..........11" & @CRLF
    $aNumber[0] &= "11..........11" & @CRLF
    $aNumber[0] &= ".............." & @CRLF
    $aNumber[0] &= "11.......11.11" & @CRLF
    $aNumber[0] &= "11.......11.11" & @CRLF
    $aNumber[0] &= ".............." & @CRLF
    $aNumber[0] &= "11....11....11" & @CRLF
    $aNumber[0] &= "11....11....11" & @CRLF
    $aNumber[0] &= ".............." & @CRLF
    $aNumber[0] &= "11.11.......11" & @CRLF
    $aNumber[0] &= "11.11.......11" & @CRLF
    $aNumber[0] &= ".............." & @CRLF
    $aNumber[0] &= "11..........11" & @CRLF
    $aNumber[0] &= "11..........11" & @CRLF
    $aNumber[0] &= ".............." & @CRLF
    $aNumber[0] &= "...11.11.11..." & @CRLF
    $aNumber[0] &= "...11.11.11..." & @CRLF


    $aNumber[1] = "" ; Pattern for '1'
    $aNumber[1] &= "......11......" & @CRLF
    $aNumber[1] &= "......11......" & @CRLF
    $aNumber[1] &= ".............." & @CRLF
    $aNumber[1] &= "...11.11......" & @CRLF
    $aNumber[1] &= "...11.11......" & @CRLF
    $aNumber[1] &= ".............." & @CRLF
    $aNumber[1] &= "......11......" & @CRLF
    $aNumber[1] &= "......11......" & @CRLF
    $aNumber[1] &= ".............." & @CRLF
    $aNumber[1] &= "......11......" & @CRLF
    $aNumber[1] &= "......11......" & @CRLF
    $aNumber[1] &= ".............." & @CRLF
    $aNumber[1] &= "......11......" & @CRLF
    $aNumber[1] &= "......11......" & @CRLF
    $aNumber[1] &= ".............." & @CRLF
    $aNumber[1] &= "......11......" & @CRLF
    $aNumber[1] &= "......11......" & @CRLF
    $aNumber[1] &= ".............." & @CRLF
    $aNumber[1] &= "...11.11.11..." & @CRLF
    $aNumber[1] &= "...11.11.11..." & @CRLF


    $aNumber[2] = "" ; Pattern for '2'
    $aNumber[2] &= "...11.11.11..." & @CRLF
    $aNumber[2] &= "...11.11.11..." & @CRLF
    $aNumber[2] &= ".............." & @CRLF
    $aNumber[2] &= "11..........11" & @CRLF
    $aNumber[2] &= "11..........11" & @CRLF
    $aNumber[2] &= ".............." & @CRLF
    $aNumber[2] &= "............11" & @CRLF
    $aNumber[2] &= "............11" & @CRLF
    $aNumber[2] &= ".............." & @CRLF
    $aNumber[2] &= "......11.11..." & @CRLF
    $aNumber[2] &= "......11.11..." & @CRLF
    $aNumber[2] &= ".............." & @CRLF
    $aNumber[2] &= "...11........." & @CRLF
    $aNumber[2] &= "...11........." & @CRLF
    $aNumber[2] &= ".............." & @CRLF
    $aNumber[2] &= "11............" & @CRLF
    $aNumber[2] &= "11............" & @CRLF
    $aNumber[2] &= ".............." & @CRLF
    $aNumber[2] &= "11.11.11.11.11" & @CRLF
    $aNumber[2] &= "11.11.11.11.11" & @CRLF


    $aNumber[3] = "" ; Pattern for '3'
    $aNumber[3] &= "...11.11.11..." & @CRLF
    $aNumber[3] &= "...11.11.11..." & @CRLF
    $aNumber[3] &= ".............." & @CRLF
    $aNumber[3] &= "11..........11" & @CRLF
    $aNumber[3] &= "11..........11" & @CRLF
    $aNumber[3] &= ".............." & @CRLF
    $aNumber[3] &= "............11" & @CRLF
    $aNumber[3] &= "............11" & @CRLF
    $aNumber[3] &= ".............." & @CRLF
    $aNumber[3] &= "......11.11..." & @CRLF
    $aNumber[3] &= "......11.11..." & @CRLF
    $aNumber[3] &= ".............." & @CRLF
    $aNumber[3] &= "............11" & @CRLF
    $aNumber[3] &= "............11" & @CRLF
    $aNumber[3] &= ".............." & @CRLF
    $aNumber[3] &= "11..........11" & @CRLF
    $aNumber[3] &= "11..........11" & @CRLF
    $aNumber[3] &= ".............." & @CRLF
    $aNumber[3] &= "...11.11.11..." & @CRLF
    $aNumber[3] &= "...11.11.11..." & @CRLF


    $aNumber[4] = "" ; Pattern for '4'
    $aNumber[4] &= ".........11..." & @CRLF
    $aNumber[4] &= ".........11..." & @CRLF
    $aNumber[4] &= ".............." & @CRLF
    $aNumber[4] &= "......11.11..." & @CRLF
    $aNumber[4] &= "......11.11..." & @CRLF
    $aNumber[4] &= ".............." & @CRLF
    $aNumber[4] &= "...11....11..." & @CRLF
    $aNumber[4] &= "...11....11..." & @CRLF
    $aNumber[4] &= ".............." & @CRLF
    $aNumber[4] &= "11.......11..." & @CRLF
    $aNumber[4] &= "11.......11..." & @CRLF
    $aNumber[4] &= ".............." & @CRLF
    $aNumber[4] &= "11.11.11.11.11" & @CRLF
    $aNumber[4] &= "11.11.11.11.11" & @CRLF
    $aNumber[4] &= ".............." & @CRLF
    $aNumber[4] &= ".........11..." & @CRLF
    $aNumber[4] &= ".........11..." & @CRLF
    $aNumber[4] &= ".............." & @CRLF
    $aNumber[4] &= ".........11..." & @CRLF
    $aNumber[4] &= ".........11..." & @CRLF


    $aNumber[5] = "" ; Pattern for '5'
    $aNumber[5] &= "11.11.11.11.11" & @CRLF
    $aNumber[5] &= "11.11.11.11.11" & @CRLF
    $aNumber[5] &= ".............." & @CRLF
    $aNumber[5] &= "11............" & @CRLF
    $aNumber[5] &= "11............" & @CRLF
    $aNumber[5] &= ".............." & @CRLF
    $aNumber[5] &= "11.11.11.11..." & @CRLF
    $aNumber[5] &= "11.11.11.11..." & @CRLF
    $aNumber[5] &= ".............." & @CRLF
    $aNumber[5] &= "............11" & @CRLF
    $aNumber[5] &= "............11" & @CRLF
    $aNumber[5] &= ".............." & @CRLF
    $aNumber[5] &= "............11" & @CRLF
    $aNumber[5] &= "............11" & @CRLF
    $aNumber[5] &= ".............." & @CRLF
    $aNumber[5] &= "11..........11" & @CRLF
    $aNumber[5] &= "11..........11" & @CRLF
    $aNumber[5] &= ".............." & @CRLF
    $aNumber[5] &= "...11.11.11..." & @CRLF
    $aNumber[5] &= "...11.11.11..." & @CRLF


    $aNumber[6] = "" ; Pattern for '6'
    $aNumber[6] &= "......11.11..." & @CRLF
    $aNumber[6] &= "......11.11..." & @CRLF
    $aNumber[6] &= ".............." & @CRLF
    $aNumber[6] &= "...11........." & @CRLF
    $aNumber[6] &= "...11........." & @CRLF
    $aNumber[6] &= ".............." & @CRLF
    $aNumber[6] &= "11............" & @CRLF
    $aNumber[6] &= "11............" & @CRLF
    $aNumber[6] &= ".............." & @CRLF
    $aNumber[6] &= "11.11.11.11..." & @CRLF
    $aNumber[6] &= "11.11.11.11..." & @CRLF
    $aNumber[6] &= ".............." & @CRLF
    $aNumber[6] &= "11..........11" & @CRLF
    $aNumber[6] &= "11..........11" & @CRLF
    $aNumber[6] &= ".............." & @CRLF
    $aNumber[6] &= "11..........11" & @CRLF
    $aNumber[6] &= "11..........11" & @CRLF
    $aNumber[6] &= ".............." & @CRLF
    $aNumber[6] &= "...11.11.11..." & @CRLF
    $aNumber[6] &= "...11.11.11..." & @CRLF

    $aNumber[7] = "" ; Pattern for '7'
    $aNumber[7] &= "11.11.11.11.11" & @CRLF
    $aNumber[7] &= "11.11.11.11.11" & @CRLF
    $aNumber[7] &= ".............." & @CRLF
    $aNumber[7] &= "............11" & @CRLF
    $aNumber[7] &= "............11" & @CRLF
    $aNumber[7] &= ".............." & @CRLF
    $aNumber[7] &= ".........11..." & @CRLF
    $aNumber[7] &= ".........11..." & @CRLF
    $aNumber[7] &= ".............." & @CRLF
    $aNumber[7] &= "......11......" & @CRLF
    $aNumber[7] &= "......11......" & @CRLF
    $aNumber[7] &= ".............." & @CRLF
    $aNumber[7] &= "...11........." & @CRLF
    $aNumber[7] &= "...11........." & @CRLF
    $aNumber[7] &= ".............." & @CRLF
    $aNumber[7] &= "...11........." & @CRLF
    $aNumber[7] &= "...11........." & @CRLF
    $aNumber[7] &= ".............." & @CRLF
    $aNumber[7] &= "...11........." & @CRLF
    $aNumber[7] &= "...11........." & @CRLF

    $aNumber[8] = "" ; Pattern for '8'
    $aNumber[8] &= "...11.11.11..." & @CRLF
    $aNumber[8] &= "...11.11.11..." & @CRLF
    $aNumber[8] &= ".............." & @CRLF
    $aNumber[8] &= "11..........11" & @CRLF
    $aNumber[8] &= "11..........11" & @CRLF
    $aNumber[8] &= ".............." & @CRLF
    $aNumber[8] &= "11..........11" & @CRLF
    $aNumber[8] &= "11..........11" & @CRLF
    $aNumber[8] &= ".............." & @CRLF
    $aNumber[8] &= "...11.11.11..." & @CRLF
    $aNumber[8] &= "...11.11.11..." & @CRLF
    $aNumber[8] &= ".............." & @CRLF
    $aNumber[8] &= "11..........11" & @CRLF
    $aNumber[8] &= "11..........11" & @CRLF
    $aNumber[8] &= ".............." & @CRLF
    $aNumber[8] &= "11..........11" & @CRLF
    $aNumber[8] &= "11..........11" & @CRLF
    $aNumber[8] &= ".............." & @CRLF
    $aNumber[8] &= "...11.11.11..." & @CRLF
    $aNumber[8] &= "...11.11.11..." & @CRLF

    $aNumber[9] = "" ; Pattern for '9'
    $aNumber[9] &= "...11.11.11..." & @CRLF
    $aNumber[9] &= "...11.11.11..." & @CRLF
    $aNumber[9] &= ".............." & @CRLF
    $aNumber[9] &= "11..........11" & @CRLF
    $aNumber[9] &= "11..........11" & @CRLF
    $aNumber[9] &= ".............." & @CRLF
    $aNumber[9] &= "11..........11" & @CRLF
    $aNumber[9] &= "11..........11" & @CRLF
    $aNumber[9] &= ".............." & @CRLF
    $aNumber[9] &= "...11.11.11.11" & @CRLF
    $aNumber[9] &= "...11.11.11.11" & @CRLF
    $aNumber[9] &= ".............." & @CRLF
    $aNumber[9] &= "............11" & @CRLF
    $aNumber[9] &= "............11" & @CRLF
    $aNumber[9] &= ".............." & @CRLF
    $aNumber[9] &= ".........11..." & @CRLF
    $aNumber[9] &= ".........11..." & @CRLF
    $aNumber[9] &= ".............." & @CRLF
    $aNumber[9] &= "...11.11......" & @CRLF
    $aNumber[9] &= "...11.11......" & @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   ;==>_GetPattern
;--------------------------------------------------------------------------------------------------------------------------------
Func Test()   ; _GetNumber for all

    Run("Tool.exe") ;
    Local $tool = WinWaitActive("Tool", "", 3)
    ControlClick($tool, "", "TTabSheet1", "primary", 1, 210, 50)
    ControlCommand($tool, "", "TFlatComboBox1", "SelectString", "Old")

    Local $db = FileOpen(@ScriptDir & "\tool-db.txt", 1)

    DirRemove("Bitmap ID Failed", 1)
    DirCreate("Bitmap ID Failed")

    ; Initialize GDI+ to work with bitmaps
    _GDIPlus_Startup()

    For $loop = 0 To 999999

        $serial = StringFormat('%06i', $loop)

        ControlSetText($tool, "", "TFlatMaskEdit3", "S.N: 9" & $serial) ; Enter serial number prefixed with the check digit
        ControlClick($tool, "", "TTabSheet1", "primary", 1, 69, 50) ; Press "Generate"

        ; Captures a region of the screen
        $sImageFile = @ScriptDir & "\Bitmap ID Failed\" & $serial & ".png"
        _ScreenCapture_Capture($sImageFile, 792, 450, 927, 480, False)

        ; Capture the color map for the specified area
        Local $aColorMap = CaptureAreaColorMap($sImageFile)
        If @error = 1 Then
            MsgBox($MB_SYSTEMMODAL, "LineNumber:" & @ScriptLineNumber, "File:" & @CRLF &  $sImageResult & @CRLF & " not found")
            _Exit()
        EndIf

        Local $output = FindNumberUsingColorMap($aColorMap)

        If (StringLen($output) = 3 And StringIsDigit($output)) Then FileDelete($sImageResult)

        FileWrite($db, $serial & "," & $output & @LF)

    Next

    FileClose($db)

    ; Cleanup resources
    _GDIPlus_Shutdown()
EndFunc   ;==>Test
;--------------------------------------------------------------------------------------------------------------------------------

 

I modified the script so that it calls _GDIPlus_Startup() once at the beginning,
and _GDIPlus_Shutdown() once at the end
instead of calling her for every number
I replaced the _ScreenCapture  function (although I believe I fixed it after  @Nine 's comments),
with _ScreenCapture_Capture  (since you didn't need the extras staff of _ScreenCapture)

I did a test with
Test("M:\TEMP\100num") 
where M: is my ram disk, and  100num is a folder with 17 .png files

Func Test($sFolderPath, $hColor = 0x00FF00)   ; _GetNumber for all the *.png files in $sFolderPath directory

    ; List all the *.png files in $sFolderPath directory
    Local $aFileList = _FileListToArray($sFolderPath, "*.png", $FLTA_FILES)
    If @error = 1 Then
        MsgBox($MB_SYSTEMMODAL, "LineNumber:" & @ScriptLineNumber, "Path was invalid.")
        Exit
    EndIf
    If @error = 4 Then
        MsgBox($MB_SYSTEMMODAL, "LineNumber:" & @ScriptLineNumber, "No file(s) were found.")
        Exit
    EndIf

    _ArrayColInsert($aFileList, 1) ; add 1 column to hold the numbers

    ; Initialize GDI+ to work with bitmaps
    _GDIPlus_Startup()

    Local $cnt = 0
    Local $CleanTime = 0

    For $j = 1 To 1000
        For $i = 1 To $aFileList[0][0]
            $cnt += 1
            ConsoleWrite("$cnt: " & $cnt & @CRLF)

            ; Capture the color map for the specified area
            Local $aColorMap = CaptureAreaColorMap($sFolderPath & "\" & $aFileList[$i][0])
            If @error = 1 Then
                MsgBox($MB_SYSTEMMODAL, "LineNumber:" & @ScriptLineNumber, "Path was invalid.")
                Exit
            EndIf

            $aFileList[$i][1] = FindNumberUsingColorMap($aColorMap, $hColor)

            ; Rename a file using FileMove and overwrite the new file if it exists.
;~          FileMove($sFolderPath & "\" & $aFileList[$i][0], $sFolderPath & "\" & $aFileList[$i][1] & ".png", $FC_OVERWRITE)

;~          $aProcessMemoryInfo = _WinAPI_GetProcessMemoryInfo()
;~          ConsoleWrite('The peak working set: ' & $aProcessMemoryInfo[1] / 1024 / 1014 & ' MB' & @CRLF)

        Next
    Next

    _ArrayDisplay($aFileList, "$aFileList")

    ; Cleanup resources
    _GDIPlus_Shutdown()
EndFunc   ;==>Test

 

Edited by ioa747

I know that I know nothing

Link to comment
Share on other sites

4 hours ago, ioa747 said:
 $aNumber[0] = "" ; Pattern for '0'
    $aNumber[0] &= "...11.11.11..." & @CRLF
    $aNumber[0] &= "...11.11.11..." & @CRLF
    $aNumber[0] &= ".............." & @CRLF
    $aNumber[0] &= "11..........11" & @CRLF
    $aNumber[0] &= "11..........11" & @CRLF
    $aNumber[0] &= ".............." & @CRLF
    $aNumber[0] &= "11.......11.11" & @CRLF
    $aNumber[0] &= "11.......11.11" & @CRLF
    $aNumber[0] &= ".............." & @CRLF
    $aNumber[0] &= "11....11....11" & @CRLF
    $aNumber[0] &= "11....11....11" & @CRLF
    $aNumber[0] &= ".............." & @CRLF
    $aNumber[0] &= "11.11.......11" & @CRLF
    $aNumber[0] &= "11.11.......11" & @CRLF
    $aNumber[0] &= ".............." & @CRLF
    $aNumber[0] &= "11..........11" & @CRLF
    $aNumber[0] &= "11..........11" & @CRLF
    $aNumber[0] &= ".............." & @CRLF
    $aNumber[0] &= "...11.11.11..." & @CRLF
    $aNumber[0] &= "...11.11.11..." & @CRLF

You dont need to check the whole pattern, the first column in each digit is unique...

 

Image49.png

Some guy's script + some other guy's script = my script!

Link to comment
Share on other sites

37 minutes ago, argumentum said:

as the number one could be just empty.

Doesnt matter, it'll work fine as the numbers are always 3 digits with a leading zero when the number is less than 100, like "......043......", as per his other thread where he posts examples of numbers.

Some guy's script + some other guy's script = my script!

Link to comment
Share on other sites

True, but you must be careful about the order you are looking for a match (ex : don't look for 4 before 6, don't look for 3 before 8 ) because you may end up for false positive.

Link to comment
Share on other sites

@Werty  just for information

the first column actually are 2 columns (2 pixels)

I did a test on a sample of 1700 images (1700 * 3 = 5100 numbers)

with 1 columns processed in: 103.986 seconds
with 2 columns processed in: 104.018 seconds
with 14 columns processed in: 105.922 seconds

in the 17 numbers I have, they didn't make any mistakes

 

Edited by ioa747
add with 1 columns

I know that I know nothing

Link to comment
Share on other sites

@Nine

How so, they are unique so how can they give a false positive? You check both the lit and unlit pixels.

We could store them in one byte each, they are 7 pixels tall (yes, i know they are actually taller but we only use those we need), and 7 bits fits a byte they would become (reading from top to bottom in little-endian)...

0 = 62
1 = 0
2 = 35
3 = 34
4 = 12
5 = 114
6 = 30
7 = 64
8 = 54
9 = 48

Edited by Werty

Some guy's script + some other guy's script = my script!

Link to comment
Share on other sites

1 minute ago, ioa747 said:

the first column actually are 2 columns

Yes, but you are supposed to skip those second ones, and only read the needed ones, i'll see if I can mock up an example later using pixelgetcolor, dinner time now. 😛

Some guy's script + some other guy's script = my script!

Link to comment
Share on other sites

1 hour ago, Werty said:

Doesnt matter, it'll work fine as the numbers are always 3 digits with a leading zero when...

Don't know about that. The OP shares bits and pieces. The extra millisecond saved is not that important. Producing an unequivocal output is**.
We should see if the OP fixed the high loop count crush. That merits attention. 

** Not saying that your trend of thought is wrong  

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Link to comment
Share on other sites

Here it is the edition with a single column patern
 

; https://www.autoitscript.com/forum/topic/211521-ocr-from-a-small-area/?do=findComment&comment=1538057
; Version: 5.0.2

#include <GDIPlus.au3>
#include <Array.au3>
#include <File.au3>
#include <WinAPIProc.au3>

;~ Local $Result = _GetNumber(@ScriptDir & "\100num\040.png")
;~ MsgBox($MB_SYSTEMMODAL, "_GetNumber", $Result)

Test("M:\TEMP\100num")

;--------------------------------------------------------------------------------------------------------------------------------
Func _GetNumber($sFileName, $hColor = 0x00FF00)   ; Main Program
    ; Initialize GDI+ to work with bitmaps
    _GDIPlus_Startup()

    ; Capture the color map for the specified area
    Local $aColorMap = CaptureAreaColorMap($sFileName)
    If @error = 1 Then
        MsgBox($MB_SYSTEMMODAL, "LineNumber:" & @ScriptLineNumber, "Path was invalid.")
        Exit
    EndIf

;~  _ArrayDisplay($aColorMap)

    Local $Result = FindNumberUsingColorMap($aColorMap, $hColor)
;~  MsgBox($MB_SYSTEMMODAL, "$Result", $Result)

    ; Cleanup resources
    _GDIPlus_Shutdown()

    Return $Result
EndFunc   ;==>_GetNumber
;--------------------------------------------------------------------------------------------------------------------------------
Func CaptureAreaColorMap($sFileName)   ; create color map array
    ; Initialize GDI+ to work with bitmaps
    ;_GDIPlus_Startup()

    ; Capture the screen area as a bitmap
    Local $hBitmap = _GDIPlus_BitmapCreateFromFile($sFileName)
    If @error Then Return SetError(1, 0, "") ; because the user ( me ) might do the unexpected  ;)

    ; Get the width and height of the captured area
    Local $width = _GDIPlus_ImageGetWidth($hBitmap)
    Local $height = _GDIPlus_ImageGetHeight($hBitmap)
;~  ConsoleWrite("Image: $width=" & $width & ", $height=" & $height & @CRLF)

    ; 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($hBitmap, $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($hBitmap)
    ;_GDIPlus_Shutdown()

    Return $aColorMap
EndFunc   ;==>CaptureAreaColorMap
;--------------------------------------------------------------------------------------------------------------------------------
Func FindNumberUsingColorMap($aColorMap, $hColor = 0x00FF00)   ; find number in color map array
    Local $width = UBound($aColorMap, 1)
    Local $height = UBound($aColorMap, 2)

    Local $firstRow = -1, $lastRow = -1, $firstCol = -1, $lastCol = -1

    ; Scan for the first and last rows and columns with $hColor 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

    ; each number Display is a matrix of 14x20 pixels
    Local $numberWidth = 14 ; set number width per digit
    Local $numberSpace = 2  ; set Space between digits

    Local $Empty = 0, $Corection = 0

    ; Corection for boundaries if 1st digit = 1
    For $x = $firstCol To $lastCol - 1
        If $aColorMap[$x][$firstRow] = 0x000000 Then
            $Empty += 1
            If $Empty = 3 Then
                ;found 1st Space between digits
                $Corection = $firstCol - 1 - Abs($x - $numberWidth - $numberSpace)
                ExitLoop
            EndIf
        Else
            $Empty = 0
        EndIf
    Next

    If $Corection > 0 Then $firstCol = $firstCol - $Corection

    Local $numberStart = $firstCol

;~  ConsoleWrite("$Corection=" & $Corection & @CRLF)
;~  ConsoleWrite("Display_boundaries firstRow:" & $firstRow & " lastRow:" & $lastRow & " firstCol:" & $firstCol & " lastCol:" & $lastCol & @CRLF)
;~  ConsoleWrite("" & @CRLF)

    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
;~  _ArrayDisplay($aNum)
    Local $sNumber

    ; Generate patterns for each found number
    For $i = 1 To $aNum[0][0]
        Local $sPattern = ""
        For $y = $firstRow To $lastRow
            $x = $aNum[$i][0]
            If $aColorMap[$x][$y] = $hColor Then
                $sPattern &= "1"
            Else
                $sPattern &= "."
            EndIf
            $sPattern &= @CRLF
        Next
        $sNumber &= _GetPattern($sPattern)
    Next

    Return $sNumber
EndFunc   ;==>FindNumberUsingColorMap
;--------------------------------------------------------------------------------------------------------------------------------
Func _GetPattern($sPattern)  ; patterns for each digit
;~  ConsoleWrite("**************" & @CRLF & $sPattern & @CRLF)

    Local Static $aPNum

    ; Define simplified patterns for each digit

    If Not IsArray($aPNum) Then

        Local $aNumber[10]

        $aNumber[0] = "" ; Pattern for '0'
        $aNumber[0] &= "." & @CRLF
        $aNumber[0] &= "." & @CRLF
        $aNumber[0] &= "." & @CRLF
        $aNumber[0] &= "1" & @CRLF
        $aNumber[0] &= "1" & @CRLF
        $aNumber[0] &= "." & @CRLF
        $aNumber[0] &= "1" & @CRLF
        $aNumber[0] &= "1" & @CRLF
        $aNumber[0] &= "." & @CRLF
        $aNumber[0] &= "1" & @CRLF
        $aNumber[0] &= "1" & @CRLF
        $aNumber[0] &= "." & @CRLF
        $aNumber[0] &= "1" & @CRLF
        $aNumber[0] &= "1" & @CRLF
        $aNumber[0] &= "." & @CRLF
        $aNumber[0] &= "1" & @CRLF
        $aNumber[0] &= "1" & @CRLF
        $aNumber[0] &= "." & @CRLF
        $aNumber[0] &= "." & @CRLF
        $aNumber[0] &= "." & @CRLF

        $aNumber[1] = "" ; Pattern for '1'
        $aNumber[1] &= "." & @CRLF
        $aNumber[1] &= "." & @CRLF
        $aNumber[1] &= "." & @CRLF
        $aNumber[1] &= "." & @CRLF
        $aNumber[1] &= "." & @CRLF
        $aNumber[1] &= "." & @CRLF
        $aNumber[1] &= "." & @CRLF
        $aNumber[1] &= "." & @CRLF
        $aNumber[1] &= "." & @CRLF
        $aNumber[1] &= "." & @CRLF
        $aNumber[1] &= "." & @CRLF
        $aNumber[1] &= "." & @CRLF
        $aNumber[1] &= "." & @CRLF
        $aNumber[1] &= "." & @CRLF
        $aNumber[1] &= "." & @CRLF
        $aNumber[1] &= "." & @CRLF
        $aNumber[1] &= "." & @CRLF
        $aNumber[1] &= "." & @CRLF
        $aNumber[1] &= "." & @CRLF
        $aNumber[1] &= "." & @CRLF

        $aNumber[2] = "" ; Pattern for '2'
        $aNumber[2] &= "." & @CRLF
        $aNumber[2] &= "." & @CRLF
        $aNumber[2] &= "." & @CRLF
        $aNumber[2] &= "1" & @CRLF
        $aNumber[2] &= "1" & @CRLF
        $aNumber[2] &= "." & @CRLF
        $aNumber[2] &= "." & @CRLF
        $aNumber[2] &= "." & @CRLF
        $aNumber[2] &= "." & @CRLF
        $aNumber[2] &= "." & @CRLF
        $aNumber[2] &= "." & @CRLF
        $aNumber[2] &= "." & @CRLF
        $aNumber[2] &= "." & @CRLF
        $aNumber[2] &= "." & @CRLF
        $aNumber[2] &= "." & @CRLF
        $aNumber[2] &= "1" & @CRLF
        $aNumber[2] &= "1" & @CRLF
        $aNumber[2] &= "." & @CRLF
        $aNumber[2] &= "1" & @CRLF
        $aNumber[2] &= "1" & @CRLF

        $aNumber[3] = "" ; Pattern for '3'
        $aNumber[3] &= "." & @CRLF
        $aNumber[3] &= "." & @CRLF
        $aNumber[3] &= "." & @CRLF
        $aNumber[3] &= "1" & @CRLF
        $aNumber[3] &= "1" & @CRLF
        $aNumber[3] &= "." & @CRLF
        $aNumber[3] &= "." & @CRLF
        $aNumber[3] &= "." & @CRLF
        $aNumber[3] &= "." & @CRLF
        $aNumber[3] &= "." & @CRLF
        $aNumber[3] &= "." & @CRLF
        $aNumber[3] &= "." & @CRLF
        $aNumber[3] &= "." & @CRLF
        $aNumber[3] &= "." & @CRLF
        $aNumber[3] &= "." & @CRLF
        $aNumber[3] &= "1" & @CRLF
        $aNumber[3] &= "1" & @CRLF
        $aNumber[3] &= "." & @CRLF
        $aNumber[3] &= "." & @CRLF
        $aNumber[3] &= "." & @CRLF

        $aNumber[4] = "" ; Pattern for '4'
        $aNumber[4] &= "." & @CRLF
        $aNumber[4] &= "." & @CRLF
        $aNumber[4] &= "." & @CRLF
        $aNumber[4] &= "." & @CRLF
        $aNumber[4] &= "." & @CRLF
        $aNumber[4] &= "." & @CRLF
        $aNumber[4] &= "." & @CRLF
        $aNumber[4] &= "." & @CRLF
        $aNumber[4] &= "." & @CRLF
        $aNumber[4] &= "1" & @CRLF
        $aNumber[4] &= "1" & @CRLF
        $aNumber[4] &= "." & @CRLF
        $aNumber[4] &= "1" & @CRLF
        $aNumber[4] &= "1" & @CRLF
        $aNumber[4] &= "." & @CRLF
        $aNumber[4] &= "." & @CRLF
        $aNumber[4] &= "." & @CRLF
        $aNumber[4] &= "." & @CRLF
        $aNumber[4] &= "." & @CRLF
        $aNumber[4] &= "." & @CRLF

        $aNumber[5] = "" ; Pattern for '5'
        $aNumber[5] &= "1" & @CRLF
        $aNumber[5] &= "1" & @CRLF
        $aNumber[5] &= "." & @CRLF
        $aNumber[5] &= "1" & @CRLF
        $aNumber[5] &= "1" & @CRLF
        $aNumber[5] &= "." & @CRLF
        $aNumber[5] &= "1" & @CRLF
        $aNumber[5] &= "1" & @CRLF
        $aNumber[5] &= "." & @CRLF
        $aNumber[5] &= "." & @CRLF
        $aNumber[5] &= "." & @CRLF
        $aNumber[5] &= "." & @CRLF
        $aNumber[5] &= "." & @CRLF
        $aNumber[5] &= "." & @CRLF
        $aNumber[5] &= "." & @CRLF
        $aNumber[5] &= "1" & @CRLF
        $aNumber[5] &= "1" & @CRLF
        $aNumber[5] &= "." & @CRLF
        $aNumber[5] &= "." & @CRLF
        $aNumber[5] &= "." & @CRLF

        $aNumber[6] = "" ; Pattern for '6'
        $aNumber[6] &= "." & @CRLF
        $aNumber[6] &= "." & @CRLF
        $aNumber[6] &= "." & @CRLF
        $aNumber[6] &= "." & @CRLF
        $aNumber[6] &= "." & @CRLF
        $aNumber[6] &= "." & @CRLF
        $aNumber[6] &= "1" & @CRLF
        $aNumber[6] &= "1" & @CRLF
        $aNumber[6] &= "." & @CRLF
        $aNumber[6] &= "1" & @CRLF
        $aNumber[6] &= "1" & @CRLF
        $aNumber[6] &= "." & @CRLF
        $aNumber[6] &= "1" & @CRLF
        $aNumber[6] &= "1" & @CRLF
        $aNumber[6] &= "." & @CRLF
        $aNumber[6] &= "1" & @CRLF
        $aNumber[6] &= "1" & @CRLF
        $aNumber[6] &= "." & @CRLF
        $aNumber[6] &= "." & @CRLF
        $aNumber[6] &= "." & @CRLF

        $aNumber[7] = "" ; Pattern for '7'
        $aNumber[7] &= "1" & @CRLF
        $aNumber[7] &= "1" & @CRLF
        $aNumber[7] &= "." & @CRLF
        $aNumber[7] &= "." & @CRLF
        $aNumber[7] &= "." & @CRLF
        $aNumber[7] &= "." & @CRLF
        $aNumber[7] &= "." & @CRLF
        $aNumber[7] &= "." & @CRLF
        $aNumber[7] &= "." & @CRLF
        $aNumber[7] &= "." & @CRLF
        $aNumber[7] &= "." & @CRLF
        $aNumber[7] &= "." & @CRLF
        $aNumber[7] &= "." & @CRLF
        $aNumber[7] &= "." & @CRLF
        $aNumber[7] &= "." & @CRLF
        $aNumber[7] &= "." & @CRLF
        $aNumber[7] &= "." & @CRLF
        $aNumber[7] &= "." & @CRLF
        $aNumber[7] &= "." & @CRLF
        $aNumber[7] &= "." & @CRLF

        $aNumber[8] = "" ; Pattern for '8'
        $aNumber[8] &= "." & @CRLF
        $aNumber[8] &= "." & @CRLF
        $aNumber[8] &= "." & @CRLF
        $aNumber[8] &= "1" & @CRLF
        $aNumber[8] &= "1" & @CRLF
        $aNumber[8] &= "." & @CRLF
        $aNumber[8] &= "1" & @CRLF
        $aNumber[8] &= "1" & @CRLF
        $aNumber[8] &= "." & @CRLF
        $aNumber[8] &= "." & @CRLF
        $aNumber[8] &= "." & @CRLF
        $aNumber[8] &= "." & @CRLF
        $aNumber[8] &= "1" & @CRLF
        $aNumber[8] &= "1" & @CRLF
        $aNumber[8] &= "." & @CRLF
        $aNumber[8] &= "1" & @CRLF
        $aNumber[8] &= "1" & @CRLF
        $aNumber[8] &= "." & @CRLF
        $aNumber[8] &= "." & @CRLF
        $aNumber[8] &= "." & @CRLF

        $aNumber[9] = "" ; Pattern for '9'
        $aNumber[9] &= "." & @CRLF
        $aNumber[9] &= "." & @CRLF
        $aNumber[9] &= "." & @CRLF
        $aNumber[9] &= "1" & @CRLF
        $aNumber[9] &= "1" & @CRLF
        $aNumber[9] &= "." & @CRLF
        $aNumber[9] &= "1" & @CRLF
        $aNumber[9] &= "1" & @CRLF
        $aNumber[9] &= "." & @CRLF
        $aNumber[9] &= "." & @CRLF
        $aNumber[9] &= "." & @CRLF
        $aNumber[9] &= "." & @CRLF
        $aNumber[9] &= "." & @CRLF
        $aNumber[9] &= "." & @CRLF
        $aNumber[9] &= "." & @CRLF
        $aNumber[9] &= "." & @CRLF
        $aNumber[9] &= "." & @CRLF
        $aNumber[9] &= "." & @CRLF
        $aNumber[9] &= "." & @CRLF
        $aNumber[9] &= "." & @CRLF

        $aPNum = $aNumber
    EndIf

    Switch $sPattern
        Case $aPNum[0]
            Return 0
        Case $aPNum[1]
            Return 1
        Case $aPNum[2]
            Return 2
        Case $aPNum[3]
            Return 3
        Case $aPNum[4]
            Return 4
        Case $aPNum[5]
            Return 5
        Case $aPNum[6]
            Return 6
        Case $aPNum[7]
            Return 7
        Case $aPNum[8]
            Return 8
        Case $aPNum[9]
            Return 9
        Case Else
            Return SetError(1, 0, "")
    EndSwitch
EndFunc   ;==>_GetPattern
;--------------------------------------------------------------------------------------------------------------------------------
Func Test($sFolderPath, $hColor = 0x00FF00)   ; _GetNumber for all the *.png files in $sFolderPath directory

    ; List all the *.png files in $sFolderPath directory
    Local $aFileList = _FileListToArray($sFolderPath, "*.png", $FLTA_FILES)
    If @error = 1 Then
        MsgBox($MB_SYSTEMMODAL, "LineNumber:" & @ScriptLineNumber, "Path was invalid.")
        Exit
    EndIf
    If @error = 4 Then
        MsgBox($MB_SYSTEMMODAL, "LineNumber:" & @ScriptLineNumber, "No file(s) were found.")
        Exit
    EndIf

    _ArrayColInsert($aFileList, 1) ; add 1 column to hold the numbers

    ; Initialize GDI+ to work with bitmaps
    _GDIPlus_Startup()

    Local $cnt = 0
    Local $CleanTime = 0
    Local $hTimer = TimerInit()

    For $j = 1 To 100
    For $i = 1 To $aFileList[0][0]
        $cnt += 1
        ConsoleWrite("$cnt: " & $cnt & @CRLF)

        ; Capture the color map for the specified area
        Local $aColorMap = CaptureAreaColorMap($sFolderPath & "\" & $aFileList[$i][0])
        If @error = 1 Then
            MsgBox($MB_SYSTEMMODAL, "LineNumber:" & @ScriptLineNumber, "Path was invalid.")
            Exit
        EndIf

        $aFileList[$i][1] = FindNumberUsingColorMap($aColorMap, $hColor)

        ; Rename a file using FileMove and overwrite the new file if it exists.
;~          FileMove($sFolderPath & "\" & $aFileList[$i][0], $sFolderPath & "\" & $aFileList[$i][1] & ".png", $FC_OVERWRITE)

;~          $aProcessMemoryInfo = _WinAPI_GetProcessMemoryInfo()
;~          ConsoleWrite('The peak working set: ' & $aProcessMemoryInfo[1] / 1024 / 1014 & ' MB' & @CRLF)

    Next
    Next

    ConsoleWrite("processed in: " & Round(TimerDiff($hTimer) / 1000, 3) & " seconds " & @LF)

    _ArrayDisplay($aFileList, "$aFileList")

    ; Cleanup resources
    _GDIPlus_Shutdown()
EndFunc   ;==>Test
;--------------------------------------------------------------------------------------------------------------------------------

 

Edited by ioa747
Update to Version: 5.0.2

I know that I know nothing

Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...