Jump to content

Recommended Posts

Posted (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

; 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 by ioa747
better cleaning resources

I know that I know nothing

  • 8 months later...
Posted

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?

Posted (edited)

difficult pattern for OCR program
but it has an easy pattern
i played with it a bit here are the results
 

#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 by ioa747
Update to Version: 2.0

I know that I know nothing

Posted (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 by Hashim
Posted

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

I know that I know nothing

Posted (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 by ioa747

I know that I know nothing

Posted (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 by Hashim
Posted (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 by ioa747

I know that I know nothing

Posted (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:

 

 

code_000000.png

Edited by Hashim
Posted (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 by Hashim
Posted

 

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

 

tmp_OCR_image.png.81e95094b95e23654a41ada576bd137b.pngin the first ones: Vpoint = 3x3

 

241103-024946-663_CorelPP_AM2Rp.png

 

in the second: Vpoint = 1x1

code_000000.png.9d19ad2bc17bff685aa60db49cb57257.png241103-025125-424_CorelPP_hTVRd.png

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

Posted (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 by argumentum
posted code

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

Posted (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

 

tmp_OCR_image.png.81e95094b95e23654a41ada576bd137b.pngin the first ones: Vpoint = 3x3

 

241103-024946-663_CorelPP_AM2Rp.png

 

in the second: Vpoint = 1x1

code_000000.png.9d19ad2bc17bff685aa60db49cb57257.png241103-025125-424_CorelPP_hTVRd.png

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 by Hashim
Posted (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 by Hashim
Posted

..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.
autoit_scripter_blue_userbar.png

Posted (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.

#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  code_000000.png
to make the rest num patterns and some test

Edited by ioa747
remove Do, Until

I know that I know nothing

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
×
×
  • Create New...