Jump to content

OCR from a small area


Recommended Posts

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

#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, $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_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, $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)
    $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

    $sOCRTextResult = _UWPOCR_GetText($hImage, $sLanguageTagToUse, $bUseOcrLine)
    If @error Then Return SetError(4, 0, False)

    _WinAPI_DeleteObject($hHBitmap)
    _GDIPlus_BitmapDispose($hImage)
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_Shutdown()

    Return $sOCRTextResult

EndFunc   ;==>_GetText
;--------------------------------------------------------------------------------------------------------------------------------

Thank you very much  :)

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

×
×
  • Create New...