<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title type="html"><![CDATA[Серый форум &mdash; AHK: Оптическое распознавание символов (OCR) с UWP API]]></title>
	<link rel="self" href="http://forum.script-coding.com/extern.php?action=feed&amp;tid=17649&amp;type=atom" />
	<updated>2023-03-12T01:33:46Z</updated>
	<generator>PunBB</generator>
	<id>http://forum.script-coding.com/viewtopic.php?id=17649</id>
		<entry>
			<title type="html"><![CDATA[AHK: Оптическое распознавание символов (OCR) с UWP API]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=157086#p157086" />
			<content type="html"><![CDATA[<p><a href="https://docs.microsoft.com/en-us/uwp/api/windows.media.ocr">https://docs.microsoft.com/en-us/uwp/ap … .media.ocr</a><br />Апи распознает текст 2 способами.<br />1) Через указание языка напрямую<br />2) Берет из списка установленных языков приоритатный и возможный для распознования.<br />msgbox % ocr(&quot;ShowAvailableLanguages&quot;) - показывает этот список (OCR возьмет первый из него).<br />msgbox % ocr(&quot;test.jpg&quot;) - OCR c языком, взятого из списка.<br /></p><div class="codebox"><pre><code>msgbox % ocr(&quot;ShowAvailableLanguages&quot;)
msgbox % ocr(&quot;test.jpg&quot;, &quot;en&quot;)
msgbox % ocr(&quot;test.jpg&quot;, &quot;ru&quot;)
msgbox % ocr(&quot;test.jpg&quot;)
ExitApp

ocr(file, lang := &quot;FirstFromAvailableLanguages&quot;)
{
   static OcrEngineStatics, OcrEngine, MaxDimension, LanguageFactory, Language, CurrentLanguage, BitmapDecoderStatics, GlobalizationPreferencesStatics
   if (OcrEngineStatics = &quot;&quot;)
   {
      CreateClass(&quot;Windows.Globalization.Language&quot;, ILanguageFactory := &quot;{9B0252AC-0C27-44F8-B792-9793FB66C63E}&quot;, LanguageFactory)
      CreateClass(&quot;Windows.Graphics.Imaging.BitmapDecoder&quot;, IBitmapDecoderStatics := &quot;{438CCB26-BCEF-4E95-BAD6-23A822E58D01}&quot;, BitmapDecoderStatics)
      CreateClass(&quot;Windows.Media.Ocr.OcrEngine&quot;, IOcrEngineStatics := &quot;{5BFFA85A-3384-3540-9940-699120D428A8}&quot;, OcrEngineStatics)
      DllCall(NumGet(NumGet(OcrEngineStatics+0)+6*A_PtrSize), &quot;ptr&quot;, OcrEngineStatics, &quot;uint*&quot;, MaxDimension)   ; MaxImageDimension
   }
   if (file = &quot;ShowAvailableLanguages&quot;)
   {
      if (GlobalizationPreferencesStatics = &quot;&quot;)
         CreateClass(&quot;Windows.System.UserProfile.GlobalizationPreferences&quot;, IGlobalizationPreferencesStatics := &quot;{01BF4326-ED37-4E96-B0E9-C1340D1EA158}&quot;, GlobalizationPreferencesStatics)
      DllCall(NumGet(NumGet(GlobalizationPreferencesStatics+0)+9*A_PtrSize), &quot;ptr&quot;, GlobalizationPreferencesStatics, &quot;ptr*&quot;, LanguageList)   ; get_Languages
      DllCall(NumGet(NumGet(LanguageList+0)+7*A_PtrSize), &quot;ptr&quot;, LanguageList, &quot;int*&quot;, count)   ; count
      loop % count
      {
         DllCall(NumGet(NumGet(LanguageList+0)+6*A_PtrSize), &quot;ptr&quot;, LanguageList, &quot;int&quot;, A_Index-1, &quot;ptr*&quot;, hString)   ; get_Item
         DllCall(NumGet(NumGet(LanguageFactory+0)+6*A_PtrSize), &quot;ptr&quot;, LanguageFactory, &quot;ptr&quot;, hString, &quot;ptr*&quot;, LanguageTest)   ; CreateLanguage
         DllCall(NumGet(NumGet(OcrEngineStatics+0)+8*A_PtrSize), &quot;ptr&quot;, OcrEngineStatics, &quot;ptr&quot;, LanguageTest, &quot;int*&quot;, bool)   ; IsLanguageSupported
         if (bool = 1)
         {
            DllCall(NumGet(NumGet(LanguageTest+0)+6*A_PtrSize), &quot;ptr&quot;, LanguageTest, &quot;ptr*&quot;, hText)
            buffer := DllCall(&quot;Combase.dll\WindowsGetStringRawBuffer&quot;, &quot;ptr&quot;, hText, &quot;uint*&quot;, length, &quot;ptr&quot;)
            text .= StrGet(buffer, &quot;UTF-16&quot;) &quot;`n&quot;
         }
         ObjRelease(LanguageTest)
      }
      ObjRelease(LanguageList)
      return text
   }
   if (lang != CurrentLanguage) or (lang = &quot;FirstFromAvailableLanguages&quot;)
   {
      if (OcrEngine != &quot;&quot;)
      {
         ObjRelease(OcrEngine)
         if (CurrentLanguage != &quot;FirstFromAvailableLanguages&quot;)
            ObjRelease(Language)
      }
      if (lang = &quot;FirstFromAvailableLanguages&quot;)
         DllCall(NumGet(NumGet(OcrEngineStatics+0)+10*A_PtrSize), &quot;ptr&quot;, OcrEngineStatics, &quot;ptr*&quot;, OcrEngine)   ; TryCreateFromUserProfileLanguages
      else
      {
         CreateHString(lang, hString)
         DllCall(NumGet(NumGet(LanguageFactory+0)+6*A_PtrSize), &quot;ptr&quot;, LanguageFactory, &quot;ptr&quot;, hString, &quot;ptr*&quot;, Language)   ; CreateLanguage
         DeleteHString(hString)
         DllCall(NumGet(NumGet(OcrEngineStatics+0)+9*A_PtrSize), &quot;ptr&quot;, OcrEngineStatics, ptr, Language, &quot;ptr*&quot;, OcrEngine)   ; TryCreateFromLanguage
      }
      if (OcrEngine = 0)
      {
         msgbox Can not use language &quot;%lang%&quot; for OCR, please install language pack.
         ExitApp
      }
      CurrentLanguage := lang
   }
   if (SubStr(file, 2, 1) != &quot;:&quot;)
      file := A_ScriptDir &quot;\&quot; file
   if !FileExist(file) or InStr(FileExist(file), &quot;D&quot;)
   {
      msgbox File &quot;%file%&quot; does not exist
      ExitApp
   }
   VarSetCapacity(GUID, 16)
   DllCall(&quot;ole32\CLSIDFromString&quot;, &quot;wstr&quot;, IID_RandomAccessStream := &quot;{905A0FE1-BC53-11DF-8C49-001E4FC686DA}&quot;, &quot;ptr&quot;, &amp;GUID)
   DllCall(&quot;ShCore\CreateRandomAccessStreamOnFile&quot;, &quot;wstr&quot;, file, &quot;uint&quot;, Read := 0, &quot;ptr&quot;, &amp;GUID, &quot;ptr*&quot;, IRandomAccessStream)
   DllCall(NumGet(NumGet(BitmapDecoderStatics+0)+14*A_PtrSize), &quot;ptr&quot;, BitmapDecoderStatics, &quot;ptr&quot;, IRandomAccessStream, &quot;ptr*&quot;, BitmapDecoder)   ; CreateAsync
   WaitForAsync(BitmapDecoder)
   BitmapFrame := ComObjQuery(BitmapDecoder, IBitmapFrame := &quot;{72A49A1C-8081-438D-91BC-94ECFC8185C6}&quot;)
   DllCall(NumGet(NumGet(BitmapFrame+0)+12*A_PtrSize), &quot;ptr&quot;, BitmapFrame, &quot;uint*&quot;, width)   ; get_PixelWidth
   DllCall(NumGet(NumGet(BitmapFrame+0)+13*A_PtrSize), &quot;ptr&quot;, BitmapFrame, &quot;uint*&quot;, height)   ; get_PixelHeight
   if (width &gt; MaxDimension) or (height &gt; MaxDimension)
   {
      msgbox Image is to big - %width%x%height%.`nIt should be maximum - %MaxDimension% pixels
      ExitApp
   }
   BitmapFrameWithSoftwareBitmap := ComObjQuery(BitmapDecoder, IBitmapFrameWithSoftwareBitmap := &quot;{FE287C9A-420C-4963-87AD-691436E08383}&quot;)
   DllCall(NumGet(NumGet(BitmapFrameWithSoftwareBitmap+0)+6*A_PtrSize), &quot;ptr&quot;, BitmapFrameWithSoftwareBitmap, &quot;ptr*&quot;, SoftwareBitmap)   ; GetSoftwareBitmapAsync
   WaitForAsync(SoftwareBitmap)
   DllCall(NumGet(NumGet(OcrEngine+0)+6*A_PtrSize), &quot;ptr&quot;, OcrEngine, ptr, SoftwareBitmap, &quot;ptr*&quot;, OcrResult)   ; RecognizeAsync
   WaitForAsync(OcrResult)
   DllCall(NumGet(NumGet(OcrResult+0)+6*A_PtrSize), &quot;ptr&quot;, OcrResult, &quot;ptr*&quot;, LinesList)   ; get_Lines
   DllCall(NumGet(NumGet(LinesList+0)+7*A_PtrSize), &quot;ptr&quot;, LinesList, &quot;int*&quot;, count)   ; count
   loop % count
   {
      DllCall(NumGet(NumGet(LinesList+0)+6*A_PtrSize), &quot;ptr&quot;, LinesList, &quot;int&quot;, A_Index-1, &quot;ptr*&quot;, OcrLine)
      DllCall(NumGet(NumGet(OcrLine+0)+7*A_PtrSize), &quot;ptr&quot;, OcrLine, &quot;ptr*&quot;, hText) 
      buffer := DllCall(&quot;Combase.dll\WindowsGetStringRawBuffer&quot;, &quot;ptr&quot;, hText, &quot;uint*&quot;, length, &quot;ptr&quot;)
      text .= StrGet(buffer, &quot;UTF-16&quot;) &quot;`n&quot;
      ObjRelease(OcrLine)
   }
   Close := ComObjQuery(IRandomAccessStream, IClosable := &quot;{30D5A829-7FA4-4026-83BB-D75BAE4EA99E}&quot;)
   DllCall(NumGet(NumGet(Close+0)+6*A_PtrSize), &quot;ptr&quot;, Close)   ; Close
   ObjRelease(Close)
   Close := ComObjQuery(SoftwareBitmap, IClosable := &quot;{30D5A829-7FA4-4026-83BB-D75BAE4EA99E}&quot;)
   DllCall(NumGet(NumGet(Close+0)+6*A_PtrSize), &quot;ptr&quot;, Close)   ; Close
   ObjRelease(Close)
   ObjRelease(IRandomAccessStream)
   ObjRelease(BitmapDecoder)
   ObjRelease(BitmapFrame)
   ObjRelease(BitmapFrameWithSoftwareBitmap)
   ObjRelease(SoftwareBitmap)
   ObjRelease(OcrResult)
   ObjRelease(LinesList)
   return text
}



CreateClass(string, interface, ByRef Class)
{
   CreateHString(string, hString)
   VarSetCapacity(GUID, 16)
   DllCall(&quot;ole32\CLSIDFromString&quot;, &quot;wstr&quot;, interface, &quot;ptr&quot;, &amp;GUID)
   result := DllCall(&quot;Combase.dll\RoGetActivationFactory&quot;, &quot;ptr&quot;, hString, &quot;ptr&quot;, &amp;GUID, &quot;ptr*&quot;, Class, &quot;uint&quot;)
   if (result != 0)
   {
      if (result = 0x80004002)
         msgbox No such interface supported
      else if (result = 0x80040154)
         msgbox Class not registered
      else
         msgbox error: %result%
      ExitApp
   }
   DeleteHString(hString)
}

CreateHString(string, ByRef hString)
{
    DllCall(&quot;Combase.dll\WindowsCreateString&quot;, &quot;wstr&quot;, string, &quot;uint&quot;, StrLen(string), &quot;ptr*&quot;, hString)
}

DeleteHString(hString)
{
   DllCall(&quot;Combase.dll\WindowsDeleteString&quot;, &quot;ptr&quot;, hString)
}

WaitForAsync(ByRef Object)
{
   AsyncInfo := ComObjQuery(Object, IAsyncInfo := &quot;{00000036-0000-0000-C000-000000000046}&quot;)
   loop
   {
      DllCall(NumGet(NumGet(AsyncInfo+0)+7*A_PtrSize), &quot;ptr&quot;, AsyncInfo, &quot;uint*&quot;, status)   ; IAsyncInfo.Status
      if (status != 0)
      {
         if (status != 1)
         {
            DllCall(NumGet(NumGet(AsyncInfo+0)+8*A_PtrSize), &quot;ptr&quot;, AsyncInfo, &quot;uint*&quot;, ErrorCode)   ; IAsyncInfo.ErrorCode
            msgbox AsyncInfo status error: %ErrorCode%
            ExitApp
         }
         ObjRelease(AsyncInfo)
         break
      }
      sleep 10
   }
   DllCall(NumGet(NumGet(Object+0)+8*A_PtrSize), &quot;ptr&quot;, Object, &quot;ptr*&quot;, ObjectResult)   ; GetResults
   ObjRelease(Object)
   Object := ObjectResult
}</code></pre></div><p>Скрипт для распознавания снимков с экрана by <strong>teadrinker</strong>:<br /></p><div class="codebox"><pre><code>#NoEnv
SetBatchLines, -1
Return

Esc:: ExitApp

^X::
hBitmap := HBitmapFromScreen(GetArea()*)
pIRandomAccessStream := HBitmapToRandomAccessStream(hBitmap)
DllCall(&quot;DeleteObject&quot;, &quot;Ptr&quot;, hBitmap)
text := ocr(pIRandomAccessStream, &quot;ru&quot;)
MsgBox, % text
Return

GetArea() {
   area := []
   StartSelection(area)
   while !area.w
      Sleep, 100
   Return area
}
   
StartSelection(area) {
   handler := Func(&quot;Select&quot;).Bind(area)
   Hotkey, LButton, % handler, On
   ReplaceSystemCursors(&quot;IDC_CROSS&quot;)
}

Select(area) {
   static hGui := CreateSelectionGui()
   Hook := new WindowsHook(WH_MOUSE_LL := 14, &quot;LowLevelMouseProc&quot;, hGui)
   Loop {
      KeyWait, LButton
      WinGetPos, X, Y, W, H, ahk_id %hGui%
   } until w &gt; 0
   ReplaceSystemCursors(&quot;&quot;)
   Hotkey, LButton, Off
   Hook := &quot;&quot;
   Gui, %hGui%:Show, Hide
   for k, v in [&quot;x&quot;, &quot;y&quot;, &quot;w&quot;, &quot;h&quot;]
      area[v] := %v%
}

ReplaceSystemCursors(IDC = &quot;&quot;)
{
   static IMAGE_CURSOR := 2, SPI_SETCURSORS := 0x57
        , exitFunc := Func(&quot;ReplaceSystemCursors&quot;).Bind(&quot;&quot;)
        , SysCursors := { IDC_APPSTARTING: 32650
                        , IDC_ARROW      : 32512
                        , IDC_CROSS      : 32515
                        , IDC_HAND       : 32649
                        , IDC_HELP       : 32651
                        , IDC_IBEAM      : 32513
                        , IDC_NO         : 32648
                        , IDC_SIZEALL    : 32646
                        , IDC_SIZENESW   : 32643
                        , IDC_SIZENWSE   : 32642
                        , IDC_SIZEWE     : 32644
                        , IDC_SIZENS     : 32645 
                        , IDC_UPARROW    : 32516
                        , IDC_WAIT       : 32514 }
   if !IDC {
      DllCall(&quot;SystemParametersInfo&quot;, UInt, SPI_SETCURSORS, UInt, 0, UInt, 0, UInt, 0)
      OnExit(exitFunc, 0)
   }
   else  {
      hCursor := DllCall(&quot;LoadCursor&quot;, Ptr, 0, UInt, SysCursors[IDC], Ptr)
      for k, v in SysCursors  {
         hCopy := DllCall(&quot;CopyImage&quot;, Ptr, hCursor, UInt, IMAGE_CURSOR, Int, 0, Int, 0, UInt, 0, Ptr)
         DllCall(&quot;SetSystemCursor&quot;, Ptr, hCopy, UInt, v)
      }
      OnExit(exitFunc)
   }
}

CreateSelectionGui() {
   Gui, New, +hwndhGui +Alwaysontop -Caption +LastFound +ToolWindow +E0x20 -DPIScale
   WinSet, Transparent, 130
   Gui, Color, FFC800
   Return hGui
}

LowLevelMouseProc(nCode, wParam, lParam) {
   static WM_MOUSEMOVE := 0x200, WM_LBUTTONUP := 0x202
        , coords := [], startMouseX, startMouseY, hGui
        , timer := Func(&quot;LowLevelMouseProc&quot;).Bind(&quot;timer&quot;, &quot;&quot;, &quot;&quot;)
   
   if (nCode = &quot;timer&quot;) {
      while coords[1] {
         point := coords.RemoveAt(1)
         mouseX := point[1], mouseY := point[2]
         x := startMouseX &lt; mouseX ? startMouseX : mouseX
         y := startMouseY &lt; mouseY ? startMouseY : mouseY
         w := Abs(mouseX - startMouseX)
         h := Abs(mouseY - startMouseY)
         try Gui, %hGUi%: Show, x%x% y%y% w%w% h%h% NA
      }
   }
   else {
      (!hGui &amp;&amp; hGui := A_EventInfo)
      if (wParam = WM_LBUTTONUP)
         startMouseX := startMouseY := &quot;&quot;
      if (wParam = WM_MOUSEMOVE)  {
         mouseX := NumGet(lParam + 0, &quot;Int&quot;)
         mouseY := NumGet(lParam + 4, &quot;Int&quot;)
         if (startMouseX = &quot;&quot;) {
            startMouseX := mouseX
            startMouseY := mouseY
         }
         coords.Push([mouseX, mouseY])
         SetTimer, % timer, -10
      }
      Return DllCall(&quot;CallNextHookEx&quot;, Ptr, 0, Int, nCode, UInt, wParam, Ptr, lParam)
   }
}

class WindowsHook {
   __New(type, callback, eventInfo := &quot;&quot;, isGlobal := true) {
      this.callbackPtr := RegisterCallback(callback, &quot;Fast&quot;, 3, eventInfo)
      this.hHook := DllCall(&quot;SetWindowsHookEx&quot;, &quot;Int&quot;, type, &quot;Ptr&quot;, this.callbackPtr
                                              , &quot;Ptr&quot;, !isGlobal ? 0 : DllCall(&quot;GetModuleHandle&quot;, &quot;UInt&quot;, 0, &quot;Ptr&quot;)
                                              , &quot;UInt&quot;, isGlobal ? 0 : DllCall(&quot;GetCurrentThreadId&quot;), &quot;Ptr&quot;)
   }
   __Delete() {
      DllCall(&quot;UnhookWindowsHookEx&quot;, &quot;Ptr&quot;, this.hHook)
      DllCall(&quot;GlobalFree&quot;, &quot;Ptr&quot;, this.callBackPtr, &quot;Ptr&quot;)
   }
}

HBitmapFromScreen(X, Y, W, H) {
   HDC := DllCall(&quot;GetDC&quot;, &quot;Ptr&quot;, 0, &quot;UPtr&quot;)
   HBM := DllCall(&quot;CreateCompatibleBitmap&quot;, &quot;Ptr&quot;, HDC, &quot;Int&quot;, W, &quot;Int&quot;, H, &quot;UPtr&quot;)
   PDC := DllCall(&quot;CreateCompatibleDC&quot;, &quot;Ptr&quot;, HDC, &quot;UPtr&quot;)
   DllCall(&quot;SelectObject&quot;, &quot;Ptr&quot;, PDC, &quot;Ptr&quot;, HBM)
   DllCall(&quot;BitBlt&quot;, &quot;Ptr&quot;, PDC, &quot;Int&quot;, 0, &quot;Int&quot;, 0, &quot;Int&quot;, W, &quot;Int&quot;, H
                   , &quot;Ptr&quot;, HDC, &quot;Int&quot;, X, &quot;Int&quot;, Y, &quot;UInt&quot;, 0x00CC0020)
   DllCall(&quot;DeleteDC&quot;, &quot;Ptr&quot;, PDC)
   DllCall(&quot;ReleaseDC&quot;, &quot;Ptr&quot;, 0, &quot;Ptr&quot;, HDC)
   Return HBM
}

HBitmapToRandomAccessStream(hBitmap) {
   static IID_IRandomAccessStream := &quot;{905A0FE1-BC53-11DF-8C49-001E4FC686DA}&quot;
        , IID_IPicture            := &quot;{7BF80980-BF32-101A-8BBB-00AA00300CAB}&quot;
        , PICTYPE_BITMAP := 1
        , BSOS_DEFAULT   := 0
        
   DllCall(&quot;Ole32\CreateStreamOnHGlobal&quot;, &quot;Ptr&quot;, 0, &quot;UInt&quot;, true, &quot;PtrP&quot;, pIStream, &quot;UInt&quot;)
   
   VarSetCapacity(PICTDESC, sz := 8 + A_PtrSize*2, 0)
   NumPut(sz, PICTDESC)
   NumPut(PICTYPE_BITMAP, PICTDESC, 4)
   NumPut(hBitmap, PICTDESC, 8)
   riid := CLSIDFromString(IID_IPicture, GUID1)
   DllCall(&quot;OleAut32\OleCreatePictureIndirect&quot;, &quot;Ptr&quot;, &amp;PICTDESC, &quot;Ptr&quot;, riid, &quot;UInt&quot;, false, &quot;PtrP&quot;, pIPicture, &quot;UInt&quot;)
   ; IPicture::SaveAsFile
   DllCall(NumGet(NumGet(pIPicture+0) + A_PtrSize*15), &quot;Ptr&quot;, pIPicture, &quot;Ptr&quot;, pIStream, &quot;UInt&quot;, true, &quot;UIntP&quot;, size, &quot;UInt&quot;)
   riid := CLSIDFromString(IID_IRandomAccessStream, GUID2)
   DllCall(&quot;ShCore\CreateRandomAccessStreamOverStream&quot;, &quot;Ptr&quot;, pIStream, &quot;UInt&quot;, BSOS_DEFAULT, &quot;Ptr&quot;, riid, &quot;PtrP&quot;, pIRandomAccessStream, &quot;UInt&quot;)
   ObjRelease(pIPicture)
   ObjRelease(pIStream)
   Return pIRandomAccessStream
}

CLSIDFromString(IID, ByRef CLSID) {
   VarSetCapacity(CLSID, 16, 0)
   if res := DllCall(&quot;ole32\CLSIDFromString&quot;, &quot;WStr&quot;, IID, &quot;Ptr&quot;, &amp;CLSID, &quot;UInt&quot;)
      throw Exception(&quot;CLSIDFromString failed. Error: &quot; . Format(&quot;{:#x}&quot;, res))
   Return &amp;CLSID
}


ocr(file, lang := &quot;FirstFromAvailableLanguages&quot;)
{
   static OcrEngineStatics, OcrEngine, MaxDimension, LanguageFactory, Language, CurrentLanguage, BitmapDecoderStatics, GlobalizationPreferencesStatics
   if (OcrEngineStatics = &quot;&quot;)
   {
      CreateClass(&quot;Windows.Globalization.Language&quot;, ILanguageFactory := &quot;{9B0252AC-0C27-44F8-B792-9793FB66C63E}&quot;, LanguageFactory)
      CreateClass(&quot;Windows.Graphics.Imaging.BitmapDecoder&quot;, IBitmapDecoderStatics := &quot;{438CCB26-BCEF-4E95-BAD6-23A822E58D01}&quot;, BitmapDecoderStatics)
      CreateClass(&quot;Windows.Media.Ocr.OcrEngine&quot;, IOcrEngineStatics := &quot;{5BFFA85A-3384-3540-9940-699120D428A8}&quot;, OcrEngineStatics)
      DllCall(NumGet(NumGet(OcrEngineStatics+0)+6*A_PtrSize), &quot;ptr&quot;, OcrEngineStatics, &quot;uint*&quot;, MaxDimension)   ; MaxImageDimension
   }
   if (file = &quot;ShowAvailableLanguages&quot;)
   {
      if (GlobalizationPreferencesStatics = &quot;&quot;)
         CreateClass(&quot;Windows.System.UserProfile.GlobalizationPreferences&quot;, IGlobalizationPreferencesStatics := &quot;{01BF4326-ED37-4E96-B0E9-C1340D1EA158}&quot;, GlobalizationPreferencesStatics)
      DllCall(NumGet(NumGet(GlobalizationPreferencesStatics+0)+9*A_PtrSize), &quot;ptr&quot;, GlobalizationPreferencesStatics, &quot;ptr*&quot;, LanguageList)   ; get_Languages
      DllCall(NumGet(NumGet(LanguageList+0)+7*A_PtrSize), &quot;ptr&quot;, LanguageList, &quot;int*&quot;, count)   ; count
      loop % count
      {
         DllCall(NumGet(NumGet(LanguageList+0)+6*A_PtrSize), &quot;ptr&quot;, LanguageList, &quot;int&quot;, A_Index-1, &quot;ptr*&quot;, hString)   ; get_Item
         DllCall(NumGet(NumGet(LanguageFactory+0)+6*A_PtrSize), &quot;ptr&quot;, LanguageFactory, &quot;ptr&quot;, hString, &quot;ptr*&quot;, LanguageTest)   ; CreateLanguage
         DllCall(NumGet(NumGet(OcrEngineStatics+0)+8*A_PtrSize), &quot;ptr&quot;, OcrEngineStatics, &quot;ptr&quot;, LanguageTest, &quot;int*&quot;, bool)   ; IsLanguageSupported
         if (bool = 1)
         {
            DllCall(NumGet(NumGet(LanguageTest+0)+6*A_PtrSize), &quot;ptr&quot;, LanguageTest, &quot;ptr*&quot;, hText)
            buffer := DllCall(&quot;Combase.dll\WindowsGetStringRawBuffer&quot;, &quot;ptr&quot;, hText, &quot;uint*&quot;, length, &quot;ptr&quot;)
            text .= StrGet(buffer, &quot;UTF-16&quot;) &quot;`n&quot;
         }
         ObjRelease(LanguageTest)
      }
      ObjRelease(LanguageList)
      return text
   }
   if (lang != CurrentLanguage) or (lang = &quot;FirstFromAvailableLanguages&quot;)
   {
      if (OcrEngine != &quot;&quot;)
      {
         ObjRelease(OcrEngine)
         if (CurrentLanguage != &quot;FirstFromAvailableLanguages&quot;)
            ObjRelease(Language)
      }
      if (lang = &quot;FirstFromAvailableLanguages&quot;)
         DllCall(NumGet(NumGet(OcrEngineStatics+0)+10*A_PtrSize), &quot;ptr&quot;, OcrEngineStatics, &quot;ptr*&quot;, OcrEngine)   ; TryCreateFromUserProfileLanguages
      else
      {
         CreateHString(lang, hString)
         DllCall(NumGet(NumGet(LanguageFactory+0)+6*A_PtrSize), &quot;ptr&quot;, LanguageFactory, &quot;ptr&quot;, hString, &quot;ptr*&quot;, Language)   ; CreateLanguage
         DeleteHString(hString)
         DllCall(NumGet(NumGet(OcrEngineStatics+0)+9*A_PtrSize), &quot;ptr&quot;, OcrEngineStatics, ptr, Language, &quot;ptr*&quot;, OcrEngine)   ; TryCreateFromLanguage
      }
      if (OcrEngine = 0)
      {
         msgbox Can not use language &quot;%lang%&quot; for OCR, please install language pack.
         ExitApp
      }
      CurrentLanguage := lang
   }
   IRandomAccessStream := file
   DllCall(NumGet(NumGet(BitmapDecoderStatics+0)+14*A_PtrSize), &quot;ptr&quot;, BitmapDecoderStatics, &quot;ptr&quot;, IRandomAccessStream, &quot;ptr*&quot;, BitmapDecoder)   ; CreateAsync
   WaitForAsync(BitmapDecoder)
   BitmapFrame := ComObjQuery(BitmapDecoder, IBitmapFrame := &quot;{72A49A1C-8081-438D-91BC-94ECFC8185C6}&quot;)
   DllCall(NumGet(NumGet(BitmapFrame+0)+12*A_PtrSize), &quot;ptr&quot;, BitmapFrame, &quot;uint*&quot;, width)   ; get_PixelWidth
   DllCall(NumGet(NumGet(BitmapFrame+0)+13*A_PtrSize), &quot;ptr&quot;, BitmapFrame, &quot;uint*&quot;, height)   ; get_PixelHeight
   if (width &gt; MaxDimension) or (height &gt; MaxDimension)
   {
      msgbox Image is to big - %width%x%height%.`nIt should be maximum - %MaxDimension% pixels
      ExitApp
   }
   BitmapFrameWithSoftwareBitmap := ComObjQuery(BitmapDecoder, IBitmapFrameWithSoftwareBitmap := &quot;{FE287C9A-420C-4963-87AD-691436E08383}&quot;)
   DllCall(NumGet(NumGet(BitmapFrameWithSoftwareBitmap+0)+6*A_PtrSize), &quot;ptr&quot;, BitmapFrameWithSoftwareBitmap, &quot;ptr*&quot;, SoftwareBitmap)   ; GetSoftwareBitmapAsync
   WaitForAsync(SoftwareBitmap)
   DllCall(NumGet(NumGet(OcrEngine+0)+6*A_PtrSize), &quot;ptr&quot;, OcrEngine, ptr, SoftwareBitmap, &quot;ptr*&quot;, OcrResult)   ; RecognizeAsync
   WaitForAsync(OcrResult)
   DllCall(NumGet(NumGet(OcrResult+0)+6*A_PtrSize), &quot;ptr&quot;, OcrResult, &quot;ptr*&quot;, LinesList)   ; get_Lines
   DllCall(NumGet(NumGet(LinesList+0)+7*A_PtrSize), &quot;ptr&quot;, LinesList, &quot;int*&quot;, count)   ; count
   loop % count
   {
      DllCall(NumGet(NumGet(LinesList+0)+6*A_PtrSize), &quot;ptr&quot;, LinesList, &quot;int&quot;, A_Index-1, &quot;ptr*&quot;, OcrLine)
      DllCall(NumGet(NumGet(OcrLine+0)+7*A_PtrSize), &quot;ptr&quot;, OcrLine, &quot;ptr*&quot;, hText) 
      buffer := DllCall(&quot;Combase.dll\WindowsGetStringRawBuffer&quot;, &quot;ptr&quot;, hText, &quot;uint*&quot;, length, &quot;ptr&quot;)
      text .= StrGet(buffer, &quot;UTF-16&quot;) &quot;`n&quot;
      ObjRelease(OcrLine)
   }
   Close := ComObjQuery(IRandomAccessStream, IClosable := &quot;{30D5A829-7FA4-4026-83BB-D75BAE4EA99E}&quot;)
   DllCall(NumGet(NumGet(Close+0)+6*A_PtrSize), &quot;ptr&quot;, Close)   ; Close
   ObjRelease(Close)
   Close := ComObjQuery(SoftwareBitmap, IClosable := &quot;{30D5A829-7FA4-4026-83BB-D75BAE4EA99E}&quot;)
   DllCall(NumGet(NumGet(Close+0)+6*A_PtrSize), &quot;ptr&quot;, Close)   ; Close
   ObjRelease(Close)
   ObjRelease(IRandomAccessStream)
   ObjRelease(BitmapDecoder)
   ObjRelease(BitmapFrame)
   ObjRelease(BitmapFrameWithSoftwareBitmap)
   ObjRelease(SoftwareBitmap)
   ObjRelease(OcrResult)
   ObjRelease(LinesList)
   return text
}



CreateClass(string, interface, ByRef Class)
{
   CreateHString(string, hString)
   VarSetCapacity(GUID, 16)
   DllCall(&quot;ole32\CLSIDFromString&quot;, &quot;wstr&quot;, interface, &quot;ptr&quot;, &amp;GUID)
   result := DllCall(&quot;Combase.dll\RoGetActivationFactory&quot;, &quot;ptr&quot;, hString, &quot;ptr&quot;, &amp;GUID, &quot;ptr*&quot;, Class, &quot;uint&quot;)
   if (result != 0)
   {
      if (result = 0x80004002)
         msgbox No such interface supported
      else if (result = 0x80040154)
         msgbox Class not registered
      else
         msgbox error: %result%
      ExitApp
   }
   DeleteHString(hString)
}

CreateHString(string, ByRef hString)
{
    DllCall(&quot;Combase.dll\WindowsCreateString&quot;, &quot;wstr&quot;, string, &quot;uint&quot;, StrLen(string), &quot;ptr*&quot;, hString)
}

DeleteHString(hString)
{
   DllCall(&quot;Combase.dll\WindowsDeleteString&quot;, &quot;ptr&quot;, hString)
}

WaitForAsync(ByRef Object)
{
   AsyncInfo := ComObjQuery(Object, IAsyncInfo := &quot;{00000036-0000-0000-C000-000000000046}&quot;)
   loop
   {
      DllCall(NumGet(NumGet(AsyncInfo+0)+7*A_PtrSize), &quot;ptr&quot;, AsyncInfo, &quot;uint*&quot;, status)   ; IAsyncInfo.Status
      if (status != 0)
      {
         if (status != 1)
         {
            DllCall(NumGet(NumGet(AsyncInfo+0)+8*A_PtrSize), &quot;ptr&quot;, AsyncInfo, &quot;uint*&quot;, ErrorCode)   ; IAsyncInfo.ErrorCode
            msgbox AsyncInfo status error: %ErrorCode%
            ExitApp
         }
         ObjRelease(AsyncInfo)
         break
      }
      sleep 10
   }
   DllCall(NumGet(NumGet(Object+0)+8*A_PtrSize), &quot;ptr&quot;, Object, &quot;ptr*&quot;, ObjectResult)   ; GetResults
   ObjRelease(Object)
   Object := ObjectResult
}</code></pre></div><p><a href="http://forum.script-coding.com/viewtopic.php?id=15195">Тема для обсуждения</a></p>]]></content>
			<author>
				<name><![CDATA[Malcev]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=26930</uri>
			</author>
			<updated>2023-03-12T01:33:46Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=157086#p157086</id>
		</entry>
</feed>
