Jump to content

UWPOCR - Windows Platform Optical character recognition API Implementation

Recommended Posts

Try “fa-IR”? Also check if it is supported by your OS and install additional language pack if required (and available).



Edited by KaFu
Link to post
Share on other sites
  • Replies 55
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Popular Posts

Hello guys.  I recently saw some posts that Windows 10 provides OCR API. So I decided to create a UDF.     What's UWPOCR? UWPOCR UDF is a simple library to use Universal Windows Pl

Try “fa-IR”? Also check if it is supported by your OS and install additional language pack if required (and available).    

Here is a script to compare UWPOCR vs Tesseract. (it just load image process and show result in editboxes and display the processed image to compare visually.  #include <WinAPI

Posted Images

On 4/17/2022 at 11:55 AM, KaFu said:

Try “fa-IR”? Also check if it is supported by your OS and install additional language pack if required (and available).



Yes, I tried fa-IR, farsi-IR, Per-IR, persian-IR, fa, persian, per.

None of them worked. I've also installed additional persian lang. pack on my Windows 11.

Link to post
Share on other sites

I've installed Persian and tested it.

The GetText throws an error 7 here: _UWPOCR_Log("FAIL __UWPOCR_GetText -> WaitForAsync IOcrResult")

So the OCR engine does not seem to respond, that's where it lost me :), sorry, have no further clue.

Here's a test sentence:


Edited by KaFu
Link to post
Share on other sites
  • 1 month later...

I used this udf to OCR the content in Command Prompt. After I adjusted the ClearType settings in Control Panel. The recognition rate becomes very poor. Now I can't get back to to the initial result even I disabled it. Is there any requirement stated in the API reference?

Noticed the OCR on number string are not very accurate.

Cleartype off.jpg

Link to post
Share on other sites

Don't know about the ClearType setting, but maybe using a different font type and size for the command prompt will increase accuracy? Create a shortcut to cmd.exe, in the right-click properties you can adjust the layout settings.

Link to post
Share on other sites
  • 4 weeks later...

Is there a min. size the picture has to be? Because for small pictures(139x26 in my case) it doesnt work.
However if i make the picture bigger without changing the size of the text, it will detect it properly.

I have attached both files.
The first one (Test.jpg) doesnt work.
The second bigger one (Test2.jpg) does work

Any clue whats going on?



Edited by Patrik96
Link to post
Share on other sites
  • 2 months later...



I am interested in trying this out on my own program however I have a quick question.


I will be trying to use this on an application (would prefer not to take screenshots) so I would use the second example from @mLipok

1) if I am trying to find the location of a given text, ex “hello” and then get those location details to eventually left click center of that word, how would I add that?

Edited by Nick3399
Link to post
Share on other sites
  • 2 weeks later...

Superb toolset, many thanks.

In my process, I'm trying to read small black text/white background boxes placed on a page wide graphic. The decode is about 75% reliable and I'm looking for tips to improve that. The code is still way to messy to post here. The process is, in summary:

1. Use a WebCapture routine to capture the full page to a 1280x768 bitmap on a hidden window.
2. Convert bmp, using handle, to image using _GDIPlus_BitmapCreateFromHBITMAP($hBmp)
3. Crop image to extract the required box, using _GDIPlus_BitmapCloneArea()
4. Create a 100x200 blank white canvas and merge the cropped image into the middle of it, using _GDIPlus_ImageGetGraphicsContext() and  
 _GDIPlus_GraphicsDrawImage(). I do this because the OCR is unhappy about small images (but will detect small text on a large enough file!)
5. Finally using _UWPOCR_GetText() to extract the text

I have tried enlarging the cropped image to a larger size, using _GDIPlus_ImageResize() instead of step 4 but this introduced extraneous noise (randomly coloured pixels) around the character edges, which affected decode reliability.

Any suggestions on process techniques to maximise the OCR reliability, whilst retaining the inherent simplicity of using the built in Win10 OCR capabilities?

I'm not, on this occasion, looking for coding; it's more about suggestions on whether, for example, I should try capturing a bigger web page first, or if there's a way of specifying the font/size/content type which would give the OCR module a tighter focus, etc. 



Win10 x64
Autoit (compiling to x86)

Link to post
Share on other sites

It would be great to see the input image to be sure what suggestions to give you.




Link to post
Share on other sites

Thanks Dany,

Typical source snip attached as file TIM2.bmp, with GDIPlus_ImageT.jpg showing how it appears just before submitting to UWPOCR for processing, as follows:

#Include <UWPOCR.au3>

    Local $sTIMTextResult = _UWPOCR_GetText(@ScriptDir & "\GDIPlus_ImageT.jpg", "en-GB", False);True)
    msgbox(0,"Capture Time", $sTIMTextResult)

    $sTIMTextResult = StringReplace($sTIMTextResult," ","")
    $sTIMTextResult = StringReplace($sTIMTextResult,":","")
    $sTIMTextResult = StringReplace($sTIMTextResult,".","")
    $sTIMTextResult = StringReplace($sTIMTextResult,"O","0")
    $sTIMTextResult = StringReplace($sTIMTextResult,"C","0")
    $sTIMTextResult = StringReplace($sTIMTextResult,"I","1")

    $sTIMTextResult = StringLeft($sTIMTextResult,2) & ":" & StringMid($sTIMTextResult,3,2) & ":"  & StringMid($sTIMTextResult,5,2)

    msgbox(0,"Modified Capture Time", $sTIMTextResult)

I've used the cleanup code with some success to allow for misreads of the colons and 0/1 as O,C or I.

Since posting yesterday, I further experimented, a bit more systematically and found that:

- So long as the overall image was big enough, UWPOCR would at least try to decode the image
- The size of the text in the image, or the image itself, made little difference to the success
- Language setting and "UseOCRLine" parameters made no observable difference

What seems to be most promising at the moment is that I have just introduced a filter to force each pixel in the source image to either black or white, based on R,G and B being all greater than 240 being white, otherwise black. The decode reliability has increased dramatically. I can get away with the extra time used because the function is called infrequently and has a long window of opportunity to complete; also the images involved are comparatively small. So I think I have a solution to the immediate problem.

I believe that my source image may be not pure black and white and that's what is at the root of the poor decoding. To me, that points to the Windows 10 native OCR being weak - the UDF is certainly working well and is remarkably easy to understand, use and integrate. I'd certainly be interested in your thoughts.




//Edit: Well that theory has just been blown out of the water. I realised that the attached images were captured after I had applied the filter. So I turned it off to run new images... and the OCR is working fine !?! So new images attached without filter described above.






Edited by g0gcd
Updated information
Link to post
Share on other sites

Hello @g0gcd What I would do is to append your image to an image with a similar text pattern so that the OCR engine can get a better result.

So you will end up with a joined image like this one:


then process it with the OCR.

Test Code:

#include <ScreenCapture.au3>
#include <GDIPlus.au3>
#include "..\UWPOCR.au3"


Func _Example()

    ;hImage/hBitmap GDI
    Local $hTimer = TimerInit()
    Local $sImageFilePath = @ScriptDir & "\JoinedImage.jpg"
    Local $sImageTIM2FilePath = @ScriptDir & "\TIM2.bmp"
    Local $sText = "0123456789"
    Local Const $iW = 270, $iH = 40
    Local $hImageToProcess = _GDIPlus_ImageLoadFromFile($sImageTIM2FilePath)
    Local $hBitmap = _GDIPlus_BitmapCreateFromScan0($iW, $iH) ;create an empty bitmap
    Local $hBmpCtxt = _GDIPlus_ImageGetGraphicsContext($hBitmap) ;get the graphics context of the bitmap
    _GDIPlus_GraphicsSetSmoothingMode($hBmpCtxt, $GDIP_SMOOTHINGMODE_HIGHQUALITY)
    _GDIPlus_GraphicsClear($hBmpCtxt, 0xFFFFFFFF) ;clear bitmap with color white
    _GDIPlus_GraphicsDrawString($hBmpCtxt, $sText, 0, 0, "Arial", 18)  ;draw some text to the bitmap
    _GDIPlus_GraphicsDrawImage($hBmpCtxt, $hImageToProcess,140, -16)
    _GDIPlus_ImageSaveToFile($hBitmap, $sImageFilePath) ;save bitmap to disk
    Local $sOCRTextResult = _UWPOCR_GetText($sImageFilePath)
    MsgBox(0, "Time Elapsed: " & TimerDiff($hTimer),StringStripWS(StringReplace( $sOCRTextResult,$sText,""), $STR_STRIPALL))
EndFunc   ;==>_Example




Link to post
Share on other sites

That's inspired! ✔️

I'll try that approach and let you know how it goes.

Brilliant, thanks



Thank you so much DanyFirex!

By experiment I have found:

1. The canvas (combined image) itself needs to be of a significant size. I found that 200x200 pixels was the minimum; any less than this caused intermittent decoding irrespective of the image quality. My solution uses 900 wide by 300 tall.

2. The helper text provided assistance wherever it was placed on the canvas but best improvement came with placing it immediately to the left of the source image text, with about 1 or 2 "spaces" gap between the helper text and the source image text. No further improvement came from adding alphabetic characters or punctuation to the helper text. (Note: en-gb used)

3. The helper text helped immensely whatever font and size was used for it, but in my case, the best improvement came from using the same font and size as the source (Arial, 27pt).

4. I found that the source image text font size should be between 12 and 30. Too big and the OCR misreads and too small, the OCR doesn't see small characteristic differences. My source was 9pt from the capture process, which I enlarged to 27pt.

5. With poor source images, it does help to force pixels into pure black/white before merging into the canvas. There may be a UDF out there that does that but I did it by hand as I needed to find the edge of my source "white" box within a coloured image anyway.

6. The OCR seems to "like" a substantial white border around the two elements. If the helper text was too close to any edge, I had problems decoding. Between 50 and 100 pixels seemed to be a minimum acceptable border. (Note, this may also explain 1.)

7. I inserted __UWPOCR_Initialize() before each _UWPOCR_GetText() function call. (I process several boxes on each run). I can't see why this might be helpful but, whilst running repeated, frequent, testing I found several results were corrupted with previous or non-sensical values. I will continue to hunt my code for an error on my part, where I haven't cleared a variable, or have inadvertently re-used it! 

I hope these notes are helpful to anyone else who is struggling with decoding a less than perfect source image. My infinite thanks to DanyFirex for the pointer towards using "helper" text, as that unlocked a massive improvement in reliability.

Best Regards / Saludos




Edited by g0gcd
Update with findings
Link to post
Share on other sites
  • 4 months later...

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
  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By ioa747
      SmartNote is a screen snip tool to take Screenshot with OCR ability from Tesseract 100+ languages
      Of course you will have to install it first. https://github.com/UB-Mannheim/tesseract/wiki
      I tried it with the version of 32bit tesseract-ocr-w32-setup-v5.2.0.20220712.exe
      in Windows 10 Pro 64-bit 21H2
      as default with ALT_key and Left_mouse_button snipe the note
      #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Icon=mmcndmgr-106.ico #AutoIt3Wrapper_Outfile=SmartNote.exe #AutoIt3Wrapper_Res_Description=SmartNote screen snip & Tesserac ocr #AutoIt3Wrapper_Res_Fileversion= #AutoIt3Wrapper_Res_Fileversion_AutoIncrement=y #AutoIt3Wrapper_Res_ProductName=SmartNote.au3 #AutoIt3Wrapper_Res_ProductVersion= #AutoIt3Wrapper_Res_CompanyName=ioa747 #AutoIt3Wrapper_Res_LegalCopyright=Free with regards of AutoIT forum #AutoIt3Wrapper_Run_Tidy=y #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** ;~ ScriptName=SmartNote.au3 #include <MsgBoxConstants.au3> #include <ScreenCapture.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <StaticConstants.au3> #include <TrayConstants.au3> #include <Misc.au3> #include <Array.au3> ;tray entry to exit script Opt("TrayMenuMode", 3) ;0=append, 1=no default menu, 2=no automatic check, 4=menuitemID not return Opt("TrayOnEventMode", 1) ; Enable TrayOnEventMode. TrayCreateItem("Exit") TrayItemSetOnEvent(-1, "ExitScript") TraySetIcon("mmcndmgr.dll", -106) Local $mPos, $gPos[4], $Active_title, $ghost_gui, $block_gui, $Active_hWnd ;~ array to hold the Contextmenu data Local $NoteGui[1][10] $NoteGui[0][0] = 0 ; Note_Handle cnt $NoteGui[0][1] = "jpgPath" $NoteGui[0][2] = "ID_PicCtrl" $NoteGui[0][3] = "ID_ContextMenu" $NoteGui[0][4] = "ID_cMenuCopy" $NoteGui[0][5] = "ID_cMenuSave" $NoteGui[0][6] = "ID_cMenuOpen" $NoteGui[0][7] = "ID_cMenuOCR-eng" $NoteGui[0][8] = "ID_cMenuOCR-eng+ell" $NoteGui[0][9] = "ID_cMenuClose" ;~ HotKeySet("{PGUP}", "NoteGui_display") ;<|<|<|<|<|<|<|<|<| contex array info ; make ghost gui $ghost_gui = GUICreate("ghost_gui", 100, 100, 1, 1, $WS_POPUP, BitOR($WS_EX_TOOLWINDOW, $WS_EX_TOPMOST)) GUISetBkColor("0xFFFF00") ; $COLOR_YELLOW WinSetTrans($ghost_gui, "", 50) ; make mouse block gui $block_gui = GUICreate("ghost_gui", 100, 100, 1, 1, $WS_POPUP, BitOR($WS_EX_TOOLWINDOW, $WS_EX_TOPMOST)) WinSetTrans($block_gui, "", 1) ; Check for leftover files Local $iFileExists = FileExists(@ScriptDir & "\tmp") If $iFileExists Then FileDelete(@ScriptDir & "\tmp\*.*") Else DirCreate(@ScriptDir & "\tmp") EndIf ; loop until program exit ;********************************************************************************************* While 1 $Active_title = WinGetTitle("[ACTIVE]") $Active_hWnd = WinGetHandle($Active_title) ; whait ALT_key and Left_mouse_button _IsPressed If _IsPressed("12") And _IsPressed("01") Then ; for create new note $mPos = MouseGetPos() $gPos[0] = $mPos[0] $gPos[1] = $mPos[1] ; Wait until key is released. While _IsPressed("01") Sleep(250) $mPos = MouseGetPos() $gPos[2] = $mPos[0] $gPos[3] = $mPos[1] ; show ghost gui GUISetState(@SW_SHOW, $ghost_gui) WinMove($ghost_gui, "", $gPos[0], $gPos[1], $gPos[2] - $gPos[0], $gPos[3] - $gPos[1]) ; show ghost gui GUISetState(@SW_SHOW, $block_gui) WinMove($block_gui, "", $mPos[0] - 50, $mPos[1] - 50) WEnd GUISetState(@SW_HIDE, $ghost_gui) GUISetState(@SW_HIDE, $block_gui) CreateNew_NoteGui($gPos) ; create new note EndIf $Active_title = WinGetTitle("[ACTIVE]") $Active_hWnd = WinGetHandle($Active_title) $aMsg = GUIGetMsg() If $aMsg = 0 Or $aMsg = $GUI_EVENT_MOUSEMOVE Then ContinueLoop Switch $aMsg ; Copy to Clipboard Case 6, 17, 28, 39, 50, 61, 72, 83, 94, 105, 116, 127, 138, 149, 160, 171, 182, 193, 204, 215, 226, 237, 248, 259, 270, 281, 292, 303, 314, 325, 336, 347, 358 _PicToClip($Active_title) ; Save as... Case 7, 18, 29, 40, 51, 62, 73, 84, 95, 106, 117, 128, 139, 150, 161, 172, 183, 194, 205, 216, 227, 238, 249, 260, 271, 282, 293, 304, 315, 326, 337, 348, 359 SaveFileDlg() ; Open Case 8, 19, 30, 41, 52, 63, 74, 85, 96, 107, 118, 129, 140, 151, 162, 173, 184, 195, 206, 217, 228, 239, 250, 261, 272, 283, 294, 305, 316, 327, 338, 349, 360 ShellExecute($Active_title) ; OCR - eng Case 10, 21, 32, 43, 54, 65, 76, 87, 98, 109, 120, 131, 142, 153, 164, 175, 186, 197, 208, 219, 230, 241, 252, 263, 274, 285, 296, 307, 318, 329, 340, 351, 362 _Tesserac($Active_title, "eng") ; OCR - eng + ell Case 11, 22, 33, 44, 55, 66, 77, 88, 99, 110, 121, 132, 143, 154, 165, 176, 187, 198, 209, 220, 231, 242, 253, 264, 275, 286, 297, 308, 319, 330, 341, 352, 363 _Tesserac($Active_title, "eng+ell") ; Close Case 13, 24, 35, 46, 57, 68, 79, 90, 101, 112, 123, 134, 145, 156, 167, 178, 189, 200, 211, 222, 233, 244, 255, 266, 277, 288, 299, 310, 321, 332, 343, 354, 365 Local $strLen = StringLen(@ScriptDir & "\tmp\image_") If StringLeft($Active_title, $strLen) = @ScriptDir & "\tmp\image_" Then GUIDelete($Active_hWnd) FileDelete($Active_title) NoteGui_DeleteBy_cMenuClose($aMsg) ConsoleWrite("- WinClose " & $Active_hWnd & " & FileDelete " & $Active_title & @CRLF) EndIf EndSwitch WEnd ;********************************************************************************************* ;-------------------------------------------------------------------------------------------- Func ExitScript() ; exit program Exit EndFunc ;==>ExitScript ;-------------------------------------------------------------------------------------------- Func CreateNew_NoteGui($gPos) ; create new note gui ;~ ;$NoteGui[0][0] = Note_Handle ;~ ;$NoteGui[0][1] = jpgPath ;~ ;$NoteGui[0][2] = ID_PicCtrl ;~ ;$NoteGui[0][3] = ID_ContextMenu ;~ ;$NoteGui[0][4] = ID_cMenuClose ;~ ;$NoteGui[0][5] = ID_cMenuSave ;~ ;$NoteGui[0][6] = ID_ ;~ ;$NoteGui[0][7] = ID_ ;~ ;$NoteGui[0][8] = ID_ ;~ ;$NoteGui[0][9] = ID_ Local $n, $gW, $gH ReDim $NoteGui[UBound($NoteGui) + 1][10] $NoteGui[0][0] += 1 $n = $NoteGui[0][0] $gW = $gPos[2] - $gPos[0] $gH = $gPos[3] - $gPos[1] ; create note GUI $NoteGui[$n][0] = GUICreate($NoteGui[$n][1], $gW, $gH, $gPos[0], $gPos[1], $WS_POPUP, BitOR($WS_EX_TOOLWINDOW, $WS_EX_TOPMOST)) ; jpg Path for _ScreenCapture_Capture $NoteGui[$n][1] = @ScriptDir & "\tmp\image_" & $NoteGui[$n][0] & ".jpg" _ScreenCapture_Capture($NoteGui[$n][1], $gPos[0], $gPos[1], $gPos[2], $gPos[3]) ; set jpg Path as GUI title WinSetTitle($NoteGui[$n][0], "", $NoteGui[$n][1]) $NoteGui[$n][2] = GUICtrlCreatePic($NoteGui[$n][1], 0, 0, 0, 0, -1, $GUI_WS_EX_PARENTDRAG) GUICtrlCreateLabel("", 0, 0, $gW, $gH, $SS_GRAYFRAME) ;just for $SS_GRAYFRAME ; Creates a context menu $NoteGui[$n][3] = GUICtrlCreateContextMenu($NoteGui[$n][2]) ; MenuItem for the context menu $NoteGui[$n][4] = GUICtrlCreateMenuItem("Copy to Clipboard", $NoteGui[$n][3]) $NoteGui[$n][5] = GUICtrlCreateMenuItem("Save as...", $NoteGui[$n][3]) $NoteGui[$n][6] = GUICtrlCreateMenuItem("Open", $NoteGui[$n][3]) GUICtrlCreateMenuItem("", $NoteGui[$n][3]) ; separator $NoteGui[$n][7] = GUICtrlCreateMenuItem("OCR - eng", $NoteGui[$n][3]) $NoteGui[$n][8] = GUICtrlCreateMenuItem("OCR - eng+ell", $NoteGui[$n][3]) GUICtrlCreateMenuItem("", $NoteGui[$n][3]) ; separator $NoteGui[$n][9] = GUICtrlCreateMenuItem("Close", $NoteGui[$n][3]) ; Display the GUI. GUISetState(@SW_SHOW, $NoteGui[$n][0]) Return $NoteGui[$n][0] EndFunc ;==>CreateNew_NoteGui ;-------------------------------------------------------------------------------------------- Func SaveFileDlg() ; Save file Dialog ; Create a constant variable in Local scope of the message to display in FileSaveDialog. Local Const $sMessage = "Choose a filename." ; Display a save dialog to select a file. Local $sFileSaveDialog = FileSaveDialog($sMessage, @ScriptDir & "\SET\", "image (*.jpg)", $FD_PATHMUSTEXIST) If @error Then ; Display the error message. ;MsgBox($MB_SYSTEMMODAL, "", "No file was saved.") Else ; Retrieve the filename from the filepath e.g. Example.jpg Local $sFileName = StringTrimLeft($sFileSaveDialog, StringInStr($sFileSaveDialog, "\", $STR_NOCASESENSEBASIC, -1)) ; Check if the extension .jpg is appended to the end of the filename. Local $iExtension = StringInStr($sFileName, ".", $STR_NOCASESENSEBASIC) ; If a period (dot) is found then check whether or not the extension is equal to .jpg If $iExtension Then ; If the extension isn't equal to .jpg then append to the end of the filepath. If Not (StringTrimLeft($sFileName, $iExtension - 1) = ".jpg") Then $sFileSaveDialog &= ".jpg" Else ; If no period (dot) was found then append to the end of the file. $sFileSaveDialog &= ".jpg" EndIf ; Display the saved file. ConsoleWrite("You saved the following file:" & @CRLF & $sFileSaveDialog & @CRLF) FileCopy($Active_title, $sFileSaveDialog, $FC_OVERWRITE + $FC_CREATEPATH) EndIf EndFunc ;==>SaveFileDlg ;-------------------------------------------------------------------------------------------- Func NoteGui_display() _ArrayDisplay($NoteGui, "$NoteGui") EndFunc ;==>NoteGui_display ;-------------------------------------------------------------------------------------------- Func NoteGui_DeleteBy_cMenuClose($cMenuClose) ; NoteGui_DeleteBy_cMenuClose For $i = 1 To $NoteGui[0][0] If $cMenuClose = $NoteGui[$i][4] Then ExitLoop EndIf Next _ArrayDelete($NoteGui, $i) $NoteGui[0][0] -= 1 EndFunc ;==>NoteGui_DeleteBy_cMenuClose ;-------------------------------------------------------------------------------------------- Func _PicToClip($Path) ; use ms-paint to copy image to clipboard Local $aPos = WinGetPos("[ACTIVE]") ShellExecute(@WindowsDir & "\system32\mspaint.exe", $Path, "", "open", @SW_HIDE) Local $MsPaint $MsPaint = WinWait("[CLASS:MSPaintApp]") WinActivate($MsPaint) Send("^a") Send("^c") WinClose($MsPaint) EndFunc ;==>_PicToClip ;-------------------------------------------------------------------------------------------- Func _Tesserac($ImagePath, $lang) ; perform ocr ; thanks to JohnOne https://www.autoitscript.com/forum/topic/174483-tesseract-simple-example/ ; more info at https://tesseract-ocr.github.io/tessdoc/Command-Line-Usage.html#simplest-invocation-to-ocr-an-image Local $ResultTextPath, $OutPutPath, $TesseractExePath, $Result $ResultTextPath = @ScriptDir & "\Result" $OutPutPath = $ResultTextPath & ".txt" $TesseractExePath = "C:\Program Files (x86)\Tesseract-OCR\tesseract.exe" ShellExecuteWait($TesseractExePath, '"' & $ImagePath & '" "' & $ResultTextPath & '" -l ' & $lang & ' --psm 6', "", "", @SW_HIDE) ConsoleWrite($TesseractExePath & ' "' & $ImagePath & '" "' & $ResultTextPath & '" -l ' & $lang & ' --psm 6' & @CRLF) If @error Then Exit MsgBox($MB_OK + $MB_TOPMOST + $MB_ICONERROR, "Error", @error) EndIf $Result = FileRead($OutPutPath) MsgBox($MB_OK + $MB_TOPMOST, "OCR Result", $Result) ClipPut($Result) $mPos = MouseGetPos() ToolTip("The text was copied to the clipboard", $mPos[0] - 50, $mPos[1] - 20) Sleep(2000) ToolTip("") FileDelete($OutPutPath) EndFunc ;==>_Tesserac  
      the topic from
      was helpful for this. Thanks for sharing it
      I met some issues
      One is that I didn't find out how to put image to clipboard from file
      and I use the ms-paint for this
      and the other is with the context menu array
      I don't know if there is a more efficient way to handle it
      If anyone knows and wants it
      Please, leave your comments and experiences here.
    • By MrKm
      This tiny yet powerful UDF will help you to convert Images to text with the help of  OCRSpace API version 3.50 .
      Detect text from a local file.
      ; ========================================================= ; Example 2 : Gets text from an image from a local path reference ; : Searchable PDF is not requested by default. ; : Processes it using a basic OCR logic. ; ========================================================= $b_Create_Searchable_PDF = True ; Use a table logic for receipt OCR $b_Table = True ; Set your key here. $v_OCRSpaceAPIKey = "" $OCROptions = _OCRSpace_SetUpOCR($v_OCRSpaceAPIKey, 1, $b_Table, True, "eng", True, Default, Default, $b_Create_Searchable_PDF) $sText_Detected = _OCRSpace_ImageGetText($OCROptions, @scriptdir & "\receipt.jpg", 0, "SEARCHABLE_URL") ConsoleWrite( _ " Detected text : " & $sText_Detected & @CRLF & _ " Error Returned : " & @error & @CRLF & _ " PDF URL : " & Eval("SEARCHABLE_URL") & @CRLF)  
      Detect text from a URL reference.
      ; ========================================================= ; Example 1 : Gets text from an image using a url reference ; : Searchable PDF is not requested. ; : Processes it using a basic OCR logic. ; ========================================================= $v_OCRSpaceAPIKey = "" ; SetUp some preferences.. $OCROptions = _OCRSpace_SetUpOCR($v_OCRSpaceAPIKey, 1, False, True, "eng", True, Default, Default, False) ; Make the request.. $sText_Detected = _OCRSpace_ImageGetText($OCROptions, "https://i.imgur.com/vbYXwJm.png", 0) ConsoleWrite( _ " Detected text : " & $sText_Detected & @CRLF & _ " Error Returned : " & @error & @CRLF)    
      Detect text from a URL reference to an array
      #include "OCRSpaceUDF\_OCRSpace_UDF.au3" #include <array.au3> ; Set your key here. $v_OCRSpaceAPIKey = "" $OCROptions = _OCRSpace_SetUpOCR($v_OCRSpaceAPIKey, 1, $b_Table, True, "eng", True, Default, Default, False) ; Below, the return type is set to 1 to return an array containing the coordinates of the bounding boxes for each word detected, ; in the format : #WordDetected , #Left , #Top , 3Height, #Width $aText_Detected = _OCRSpace_ImageGetText($OCROptions, "https://i.imgur.com/Z1enogD.jpeg", 1) _ArrayDisplay($aText_Detected, "")  
      Download Latest Version : 
    • By AutoitMike
      I saw a forum question that asked how to OCR non selectable text from a screen and get its coordinates.
      This intrigued me, as I would like to have this ability in my scripts.
      I found the following VB code and I am having difficulty "Converting" it to Autoit code. It provides a pixel count to a rectangle around a specified word relative to the window it is in.
      Sub TestRects() Dim miSelectRectDoc As MODI.Document Dim miSelectRectWord As MODI.Word Dim miSelectRectRects As MODI.MiRects Dim miSelectRectRect As MODI.MiRect Dim strRectInfo As String ' Load an existing TIFF file. Set miSelectRectDoc = New MODI.Document miSelectRectDoc.Create "C:\document1.tif" ' Perform OCR. miSelectRectDoc.Images(0).OCR ' Retrieve and display bounding rectangle information. Set miSelectRectRects = miSelectRectDoc.Images(0).Layout.Words(2).Rects strRectInfo = "Word falls within " & miSelectRectRects.Count & _ " bounding rectangle(s)." & vbCrLf For Each miSelectRectRect In miSelectRectRects strRectInfo = strRectInfo & _ " Rectangle coordinates: " & vbCrLf & _ " - Left: " & miSelectRectRect.Left & vbCrLf & _ " - Right: " & miSelectRectRect.Right & vbCrLf & _ " - Top: " & miSelectRectRect.Top & vbCrLf & _ " - Bottom: " & miSelectRectRect.Bottom Next MsgBox strRectInfo, vbInformation + vbOKOnly, _ "Rectangle Information" Set miSelectRectRect = Nothing Set miSelectRectRects = Nothing Set miSelectRectWord = Nothing Set miSelectRectDoc = Nothing End Sub  
      I already have an OCR function that closely resembles this code. I would like to insert just the MiRect function into it.
      I get an error when attempting to create the MiRect and MiRects objects:
      Func OCR_Region($x,$y,$width,$height) ;note $height is NOT the height, it is the Y coordinate bottom right corner, width is bottom right corner X. Dim $miDoc, $Doc Dim $str Dim $oWord Dim $sArray[200] Dim $oMyError Dim $HexNumber Dim $msg Dim $i ;Const $miLANG_CZECH = 5 ;Const $miLANG_DANISH = 6 ;Const $miLANG_DUTCH = 19 Const $miLANG_ENGLISH = 9 ;Const $miLANG_FINNISH = 11 ;Const $miLANG_FRENCH = 12 ;Const $miLANG_GERMAN = 7 ;Const $miLANG_GREEK = 8 ;Const $miLANG_HUNGARIAN = 14 ;Const $miLANG_ITALIAN = 16 ;Const $miLANG_JAPANESE = 17 ;Const $miLANG_KOREAN = 18 ;Const $miLANG_NORWEGIAN = 20 ;Const $miLANG_POLISH = 21 ;Const $miLANG_PORTUGUESE = 22 ;Const $miLANG_RUSSIAN = 25 ;Const $miLANG_SPANISH = 10 ;Const $miLANG_SWEDISH = 29 ;Const $miLANG_TURKISH = 31 ;Const $miLANG_SYSDEFAULT = 2048 ;Const $miLANG_CHINESE_SIMPLIFIED = 2052 ;Const $miLANG_CHINESE_TRADITIONAL = 1028 Local $hBitmap1,$hImage1,$temp $temp=@ScriptDir & "\temp.bmp" _GDIPlus_Startup () ; Capture screen region $hBitmap1 = _ScreenCapture_Capture ("",$x, $y, $width, $height, False) $hImage1 = _GDIPlus_BitmapCreateFromHBITMAP ($hBitmap1) _GDIPlus_ImageSaveToFile ($hImage1, $temp) _GDIPlus_ImageDispose ($hImage1) _WinAPI_DeleteObject ($hBitmap1) $miDoc = ObjCreate("MODI.Document") ;=============================================================================== ;These two statements added for the MiRect function, they both produce an error $miSelectRectRects = ObjCreate("MODI.MiRects") $miSelectRectRect = ObjCreate("MODI.MiRect") ;============================================================================== $miDoc.Create($temp) ;MsgBox(0,"",$temp) ;this is the bitmap image which is "temp.bmp" $miDoc.Ocr($miLANG_ENGLISH, True, False) ;=============================================================================== ;These two statements added for the MiRect function, neither produce an error $miSelectRectRects = $miDoc.Images(0).Layout.Words(1).Rects $Left=$miSelectRectRects.count ;I don need ".Count", but it does something ;============================================================================== $i = 0 For $oWord in $miDoc.Images(0).Layout.Words $str = $str & $oWord.text & @CrLf ;ConsoleWrite($oWord.text & @CRLF) $sArray [$i] = $oWord.text $i += 1 Next FileDelete($temp) Return $sArray EndFunc Thanks for your help
    • By matthewjs
      I am looking to code IsRunningAsUwp() detection for AutoIt Apps published via the Windows Bridge to UWP borrowing from code here in C#: DesktopBridgeHelpers/Helpers.cs at master · qmatteoq/DesktopBridgeHelpers · GitHub More info also here: GetCurrentPackageFullName function (appmodel.h) - Win32 apps | Microsoft Docs
      The P/Invoke equivalent looks to be a pain in AutoIt and I am sure that DllStructCreate|GetData|GetPtr etc are required so if anyone one else finds this of interest and useful to them they are most welcome to contribute: I hacked a workaround as IsRunningAsUwp() (I think its only the "\VFS\" that matches!) whereas IsRunningAsUwpToDo() is to be fixed and coded up properly using DLLStruct functions as I mentioned and I figure that there will be a Guru around here with this stuff as I have also heard that the AutoIt Devs are planning a move to UWP and the below is going to be pretty fundamental (at least until then although similar will likely wind up in the libraries eventually anyways..). 
      OutputDebugString() is here:
      #Include-once Func OutputDebugString($lpOutputString)     DllCall("kernel32.dll", "NONE", "OutputDebugString", "STR", $lpOutputString) EndFunc The script to be fixed is here: 
      #Include <OutputDebugString.au3> Const $APPMODEL_ERROR_NO_PACKAGE = 15700 Const $ERROR_INSUFFICIENT_BUFFER = 122 Func IsRunningAsUwp() If IsWindows7OrLower Then Return False EndIf Return StringinStr(@ScriptDir, "\WindowsApps\") > 0 Or StringInStr(@ScriptDir, "\VFS\") > 0 EndFunc Func IsRunningAsUwpToDo() If IsWindows7OrLower Then Return False EndIf Local $packageFullNameLength = 0; Local $packageFullName[$packageFullNameLength]; Local $result = DllCall("kernel32.dll", "LONG", "GetCurrentPackageFullName", "UINT32*", $packageFullNameLength, "PWSTR", $packageFullName) OutputDebugString("$result=" & String($result)) OutputDebugString("packageFullNameLength=" & String($packageFullNameLength)) OutputDebugString("packageFullName=" & String($packageFullName)) Local $packageFullName[$packageFullNameLength]; Local $result = DllCall("kernel32.dll", "LONG", "GetCurrentPackageFullName", "UINT32*", $packageFullNameLength, "PWSTR", $packageFullName) OutputDebugString("$result=" & String($result)) OutputDebugString("packageFullNameLength=" & String($packageFullNameLength)) OutputDebugString("packageFullName=" & String($packageFullName)) Return $result <> $APPMODEL_ERROR_NO_PACKAGE And $packageFullNameLength > 0 EndFunc Func IsWindows7OrLower() Local $objWMIService = ObjGet("winmgmts:\\localhost\root\CIMV2") Local $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_OperatingSystem", "WQL", 0x30) If IsObj($colItems) Then For $objItem In $colItems Local $version = $objItem.Version OutputDebugString("Win32_OperatingSystem.Version=" & $version) Return Number($version) <= 6.1 Next Else Msgbox(0, "", "No WMI Object for Version found in WMI Class Win32_OperatingSystem") Exit(-1) Endif Return False EndFunc Kindest Regards, Matthew 
    • By mLipok
      This is TeamViewer.au3 UDF for TeamViewer API.
      ; #INDEX# ======================================================================== ; Title .........: TeamViewer.au3 ; AutoIt Version : ; Language ......: English ; Description ...: A collection of function for use with TeamViewer API ; Author ........: mLipok ; Modified ......: ; URL ...........: ; URL ...........: https://www.teamviewer.com/ ; URL ...........: https://www.teamviewer.com/en/integrations/ ; URL ...........: https://integrate.teamviewer.com/en/develop/api/get-started/ ; URL ...........: https://downloadeu1.teamviewer.com/integrate/TeamViewer_API_Documentation.pdf ; Remarks .......: This UDF was created based on TeamViewer_API_Documentation.pdf v 1.4.1 ; Remarks .......: This UDF is using Free Chilkat component look here https://www.autoitscript.com/forum/files/file/433-chilkat-udf/ ; Remarks .......: Documentation is "work in progress" ; Date ..........: 2017/02/08 ; Version .......: 0.1.1 BETA - Work in progress ; ================================================================================ in TeamViewer_Example.au3 you can see few examples:

      Func _Example() ; If not exist then create new INI file from template If Not FileExists('TeamViewer_Example.ini') Then FileCopy('TeamViewer_Example — Template.ini', 'TeamViewer_Example.ini') ; Read Access Token from INI Local $sTV_AccessToken = IniRead('TeamViewer_Example.ini', 'Settings', 'AccessToken', '') If $sTV_AccessToken = '' Then ; Your Access Token, can be left empty when OAuth (below) is configured. ; ClientId = <----------------- Create an app in your TeamViewer Management Console and insert the client ID to the INI ; ClientSecret = <------------- Insert your client secret to the INI ; AuthorizationCode = <-------- Visit https://webapi.teamviewer.com/api/v1/oauth2/authorize?response_type=code&client_id=YOUR$i_ClientIdHERE ; Login, grant the permissions (popup) and put the code shown in the AuthorizationCode variable to the INI Local $sTVOAuth_ClientID = IniRead('TeamViewer_Example.ini', 'OAuth2', 'ClientID', '') Local $sTVOAuth_ClientSecret = IniRead('TeamViewer_Example.ini', 'OAuth2', 'ClientSecret', '') _IECreate('https://webapi.teamviewer.com/api/v1/oauth2/authorize?response_type=code&client_id=' & $sTVOAuth_ClientID) ; Local $sTVOAuth_AuthorizationCode = IniRead('TeamViewer_Example.ini', 'OAuth2', 'authorizationCode', '') Local $sTVOAuth_AuthorizationCode = InputBox('AuthorizationCode', 'Please provide TV OAuth2 AuthorizationCode') If @error Then Return If $sTVOAuth_ClientID Then $sTV_AccessToken = _TVAPI_RequestOAuth2_AccessToken($sTVOAuth_ClientID, $sTVOAuth_ClientSecret, $sTVOAuth_AuthorizationCode) EndIf If $sTV_AccessToken Then _TVAPI_AccessToken($sTV_AccessToken) If _TVAPI_Ping() = True Then ; ping API to check connection and $sTV_AccessToken _Example_TeamViewer__1_Devices_SaveToFile() ;~ _Example_TeamViewer__2_Devices_ChangeDetails() ;~ _Example_TeamViewer__3_Devices_GetDevicesSingleID() ;~ _Example_TeamViewer__4_Reports_GetAllConnections() ;~ _Example_TeamViewer__5_Users_GetUserInfomation() ;~ _Example_TeamViewer__6_Groups_ListGroups() ;~ _Example_TeamViewer__7_Devices_AddDeleteDevice() Else MsgBox(0, '_TVAPI_Ping', "$v_Token or connection problem.") EndIf EndFunc ;==>_Example You can download it here:
      I'm using TeamViewer_Example.ini to store my secret tokens/keys.
      [Settings] AccessToken= [OAuth2] ClientID= ClientSecret= authorizationCode=  
  • Create New...