to Windows 10 Optical Character Recognition and Face Detection.
The Windows Runtime needs MULTITHREADED thread initialization.
But your main (GUI) thread needs SINGLETHREADED initialization.
So this example uses a temporary thread.
If you want to use it in your program, you should use a worker thread instead.
Code: Select all
EnableExplicit
DeclareModule WinOCR
  Declare.s get_Languages()  
  Declare.s get_TextFromFile(sFile.s, sLanguage.s = "")
  Declare.s get_TextFromImageID(ImageID, sLanguage.s = "")
  Declare.s get_TextFromHWND(ImageID, sLanguage.s = "")
  ;
  Declare get_FacesFromFile(sFile.s, List rcList.rect())
  Declare get_FacesFromImageID(ImageID, List rcList.rect())
  Declare get_FacesFromHWND(hWNd, List rcList.rect())
EndDeclareModule
Module WinOCR
  
  
  ;Credits - Malcev @autohotkey.com
  
  ;https://www.autohotkey.com/boards/viewtopic.php?t=72674
  ;https://www.autohotkey.com/boards/viewtopic.php?t=72797
  
  EnableExplicit
  
  
  #MyRoDebug = 0
  
  ;- Interfaces
  
  Interface IInspectable Extends IUnknown
    GetIids(*iidCount, *iids)
    GetRuntimeClassName(*className)
    GetTrustLevel(*trustLevel)
  EndInterface
  
  Interface IClosable Extends IInspectable
    Close()
  EndInterface
  
  Interface ILanguageFactory Extends IInspectable
    createLanguage(*string, *out)
  EndInterface
  
  Interface ILanguage Extends IInspectable
    get_LanguageTag(*value)
    get_DisplayName(*value)
    get_NativeName(*value)
    get_Script(*value)
  EndInterface
  
  Interface IBitmapDecoderStatics Extends IInspectable
    BmpDecoderId(*value.guid)
    JpegDecoderId(*value.guid)
    PngDecoderId(*value.guid)  
    TiffDecoderId(*value.guid)
    GifDecoderId(*value.guid)
    JpegXRDecoderId(*value.guid)
    IcoDecoderId(*value.guid)  
    GetDecoderInformationEnumerator(*out)
    CreateAsync(*in, *out)
    CreateWithIdAsync(*decoderId.guid, *in, *out)
  EndInterface
  
  Interface IBitmapDecoder Extends IInspectable
    BitmapContainerProperties(*value)
    DecoderInformation(*value)
    FrameCount(*value)
    GetPreviewAsync(*value)
    GetFrameAsync(frameIndex, *value)
  EndInterface
  
  Interface IBitmapFrameWithSoftwareBitmap Extends IInspectable
    GetSoftwareBitmapAsync(*value)
    GetSoftwareBitmapConvertedAsync(pixelFormat, alphaMode, *value)
    GetSoftwareBitmapTransformedAsync(pixelFormat, alphaMode, transform, exifOrientationMode, colorManagementMode, *value)
  EndInterface
  
  Interface IBitmapFrame Extends IInspectable
    GetThumbnailAsync(*asyncInfo)
    BitmapProperties(*value)
    BitmapPixelFormat(*value)
    BitmapAlphaMode(*value)
    DpiX(*value)
    DpiY(*value)
    PixelWidth(*value)
    PixelHeight(*value)
    OrientedPixelWidth(*value)
    OrientedPixelHeight(*value)
    GetPixelDataAsync(*asyncInfo)
    GetPixelDataTransformedAsync(pixelFormat, alphaMode, transform, exifOrientationMode, colorManagementMode, *asyncInfo)
  EndInterface
  
  Interface ISoftwareBitmap Extends IInspectable
    get_BitmapPixelFormat(*value)
    get_BitmapAlphaMode(*value)
    get_PixelWidth(*value)
    get_PixelHeight(*value)
    get_IsReadOnly(*value)
    put_DpiX(*value)
    get_DpiX(*value)
    put_DpiY(*value)
    get_DpiY(*value)
    LockBuffer(mode, *value)
    CopyTo(*bitmap)
    CopyFromBuffer(*buffer)
    GetReadOnlyView(*value)
  EndInterface
  
  Interface IOcrEngineStatics Extends IInspectable
    MaxDimensions(*value)
    AvailableRecognizerLanguages(*value)
    IsLanguageSupported(*Language,*Result)
    TryCreateFromLanguage(*Language,*Result)
    TryCreateFromUserProfileLanguages(*Result)
  EndInterface
  
  Interface IOcrEngine Extends IInspectable
    RecognizeAsync(*bitmap, *result)
    RecognizerLanguage(*value)
  EndInterface
  
  Interface IOcrResult Extends IInspectable
    Lines(*value)
    TextAngle(*value)
    Text(*value)
  EndInterface
  
  Interface IRandomAccessStream Extends IInspectable 
    get_Size(*value)
    put_Size(*value)
    GetInputStreamAt(position.q, *stream)
    GetOutputStreamAt(position.q, *stream)
    get_Position(*value)
    Seek(position.q)
    CloneStream(*stream)
    get_CanRead(*value)
    get_CanWrite(*value)
  EndInterface
  
  Interface IAsyncInfo Extends IInspectable 
    Id(*id)
    Status(*status)
    ErrorCode(*errorCode)
    Cancel()
    Close()
  EndInterface
  
  Interface IAsyncOperationWithProgress Extends IInspectable 
    Completed(asyncInfo, asyncStatus)
    Progress(asyncInfo, progressInfo)
    GetResults(*Object)
  EndInterface
  
  
  Interface IGlobalizationPreferencesStatics Extends IInspectable
    get_Calendars(*value)
    get_Clocks(*value)
    get_Currencies(*value)
    get_Languages(*value)
    get_HomeGeographicRegion(*value)
    get_WeekStartsOn(*value)
  EndInterface
  
  Interface IReadOnlyList Extends IInspectable
    get_Item(index, *hString)
    count(*value)  
  EndInterface
  
  
  Interface IFaceDetectorStatics Extends IInspectable
    CreateAsync(*returnValue)
    GetSupportedBitmapPixelFormats(*result)
    IsBitmapPixelFormatSupported(bitmapPixelFormat, *result)
    IsSupported(*returnValue)
  EndInterface
  
  Interface IFaceDetector Extends IInspectable
    DetectFacesAsync(image, *returnValue)
    DetectFacesWithSearchAreaAsync(image, searchArea, *returnValue)
    MinDetectableFaceSize(*value)
    MaxDetectableFaceSize(*value)
  EndInterface
  
  Interface IBitmapEncoderStatics Extends IInspectable
    get_BmpEncoderId(*value)
    get_JpegEncoderId(*value)
    get_PngEncoderId(*value)
    get_TiffEncoderId(*value)    
    get_GifEncoderId(*value)
    get_JpegXREncoderId(*value)
    GetEncoderInformationEnumerator(*encoderInformationEnumerator)
    CreateAsync(encoderId, *stream, *asyncInfo)
    CreateWithEncodingOptionsAsync(encoderId, stream, *encodingOptions, *asyncInfo)
    CreateForTranscodingAsync(stream, bitmapDecoder, *asyncInfo)
    CreateForInPlacePropertyEncodingAsync(stream, bitmapDecoder, *asyncInfo)
  EndInterface
  
  Interface ISoftwareBitmapStatics Extends IInspectable
    Copy(*source, *value)
    Convert(*source, format, *value)
    ConvertWithAlpha(*source, format, alpha, *value)
    CreateCopyFromBuffer(*source, format, width, height, *value)
    CreateCopyWithAlphaFromBuffer(*source, format, width, height, alpha, *value)
    CreateCopyFromSurfaceAsync(surface, *value)
    CreateCopyWithAlphaFromSurfaceAsync(surface, alpha, *value)
  EndInterface
  
  Interface IBitmapEncoder Extends IInspectable
    EncoderInformation(*value)
    BitmapProperties(*value)
    BitmapContainerProperties(*value)
    IsThumbnailGenerated(*value)
    GeneratedThumbnailWidth(*value)
    GeneratedThumbnailHeight(*value)
    BitmapTransform(*value)
    SetPixelData(pixelFormat, alphaMode, width, height, dpiX.d, dpiY.d, __pixelsSize, *pixels)
    GoToNextFrameAsync(*asyncInfo)
    GoToNextFrameWithEncodingOptionsAsync(encodingOptions, *asyncInfo)
    FlushAsync(*asyncInfo)
  EndInterface
  
  Interface IBitmapTransform Extends IInspectable
    ScaledWidth(*value)
    ScaledHeight(*value)
    InterpolationMode(*value)
    Flip(*value)
    Rotation(*value)
    Bounds(*value)
  EndInterface
  
  Interface IDetectedFace Extends IInspectable
    FaceBox(*returnValue)  
  EndInterface
  
  ;-
  ;- DataSection
  
  DataSection
    IID_IBitmapFrame:
    Data.l $72A49A1C
    Data.w $8081, $438D
    Data.b $91, $BC, $94, $EC, $FC, $81, $85, $C6
    
    IID_IRandomAccessStream:
    Data.l $905A0FE1
    Data.w $BC53, $11DF
    Data.b $8C, $49, $0, $1E, $4F, $C6, $86, $DA
    
    IID_IClosable:
    Data.l $30D5A829
    Data.w $7FA4, $4026
    Data.b $83, $BB, $D7, $5B, $AE, $4E, $A9, $9E
    
    IID_IBitmapFrameWithSoftwareBitmap:
    Data.l $FE287C9A
    Data.w $420C, $4963
    Data.b $87, $AD, $69, $14, $36, $E0, $83, $83
    
    IID_IAsyncInfo:
    Data.l $00000036
    Data.w $00, $00
    Data.b $C0, $00, $00, $00, $00, $00, $00, $46
    
    IID_IPicture:
    Data.l $7BF80980
    Data.w $BF32, $101A
    Data.b $8B, $BB, $00, $AA, $0, $30, $0C, $AB
    
    IID_ILanguageFactory:
    Data.l $9B0252AC
    Data.w $C27, $44F8
    Data.b $B7, $92, $97, $93, $FB, $66, $C6, $3E
    
    IID_IBitmapDecoderStatics:
    Data.l $438CCB26
    Data.w $BCEF, $4E95
    Data.b $BA, $D6, $23, $A8, $22, $E5, $8D, $01
    
    IID_IOcrEngineStatics:
    Data.l $5BFFA85A
    Data.w $3384, $3540
    Data.b $99, $40, $69, $91, $20, $D4, $28, $A8
    
    IID_IGlobalizationPreferencesStatics:
    Data.l $1BF4326
    Data.w $ED37, $4E96
    Data.b $B0, $E9, $C1, $34, $0D, $1E, $A1, $58
    
  EndDataSection
  
  
  Prototype pRoInitialize(initType)
  Prototype pWindowsCreateString(a, b, c)
  Prototype pRoGetActivationFactory(a, b, c)
  Prototype pWindowsDeleteString(a)
  Prototype pWindowsGetStringRawBuffer(a, length)  
  Prototype pCreateRandomAccessStreamOnFile(file, iRead, *GUID, *out)
  Prototype pCreateRandomAccessStreamOverStream(*stream, options, *riid, *ppv)
  
  Structure DynamicRuntimeFuncs
    WindowsCreateString.pWindowsCreateString
    WindowsDeleteString.pWindowsDeleteString
    RoGetActivationFactory.pRoGetActivationFactory
    WindowsGetStringRawBuffer.pWindowsGetStringRawBuffer
    CreateRandomAccessStreamOnFile.pCreateRandomAccessStreamOnFile
    CreateRandomAccessStreamOverStream.pCreateRandomAccessStreamOverStream
    RoInitialize.pRoInitialize
  EndStructure
  
  Global RT_Funcs.DynamicRuntimeFuncs
  Global RT_INIT_DONE
  
  Structure MyRTIntArray
    i.i[0]
  EndStructure
  
  ;-
  ;- HelperFuncs
  ;-
  
  Procedure RT_Init()
    
    Protected hr.l
    
    #RO_INIT_SINGLETHREADED = 0
    #RO_INIT_MULTITHREADED = 1
    
    Protected hCombase = OpenLibrary(#PB_Any, "combase.dll")
    If Not hCombase
      ProcedureReturn 0
    EndIf
    
    RT_Funcs\WindowsCreateString = GetFunction(hCombase, "WindowsCreateString")
    RT_Funcs\WindowsDeleteString = GetFunction(hCombase, "WindowsDeleteString")
    RT_Funcs\RoGetActivationFactory = GetFunction(hCombase, "RoGetActivationFactory")
    RT_Funcs\WindowsGetStringRawBuffer = GetFunction(hCombase, "WindowsGetStringRawBuffer")
    RT_Funcs\RoInitialize = GetFunction(hCombase, "RoInitialize")
    
    hCombase = OpenLibrary(#PB_Any, "SHCore.dll")
    If Not hCombase
      ProcedureReturn 0
    EndIf
    
    RT_Funcs\CreateRandomAccessStreamOnFile = GetFunction(hCombase, "CreateRandomAccessStreamOnFile")
    RT_Funcs\CreateRandomAccessStreamOverStream = GetFunction(hCombase, "CreateRandomAccessStreamOverStream")
    
    
    RT_INIT_DONE = 1
    
    Protected *i.MyRTIntArray = @RT_Funcs, i
    For i = 0 To (SizeOf(RT_Funcs) / SizeOf(Integer)) - 1
      If Not *i\i[i]
        RT_INIT_DONE = 0
        Break
      EndIf
    Next
    
    If RT_INIT_DONE
      hr = RT_Funcs\RoInitialize(#RO_INIT_MULTITHREADED)
      CompilerIf #MyRoDebug : Debug "RoInitialize = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
      ;RPC_E_CHANGED_MODE = $80010106
    EndIf
    
    ProcedureReturn RT_INIT_DONE
  EndProcedure
  
  
  
  Procedure CreateHString(sString.s, *hString)
    ProcedureReturn RT_Funcs\WindowsCreateString(@sString, Len(sString), *hString)
  EndProcedure
  
  Procedure DeleteHString(*hString)
    ProcedureReturn RT_Funcs\WindowsDeleteString(*hString)
  EndProcedure
  
  Procedure CreateClass(sString.s, sGUID.s, *OutClass)
    
    Protected hString, GUID.GUID, iReturn
    CreateHString(sString, @hString)
    CLSIDFromString_(@sGUID, @GUID)
    
    iReturn = RT_Funcs\RoGetActivationFactory(hString, @GUID, *OutClass)
    RT_Funcs\WindowsDeleteString(hString)
    ProcedureReturn iReturn
    
  EndProcedure
  
  
  
  Procedure WaitForAsync(*InOut.Integer)
    
    Protected *Object.IAsyncOperationWithProgress = *InOut\i  
    Protected IAsyncInfo.IAsyncInfo, status.l, ErrorCode.l, hr.l
    
    hr = *Object\QueryInterface(?IID_IAsyncInfo, @IAsyncInfo)
    ;Debug "WaitForAsync QueryInterface = 0x" + Hex(hr)
    
    If Not IAsyncInfo
      Debug "ER QueryInterface IID_IAsyncInfo failed!"
      ProcedureReturn 0
    EndIf
    
    While 1    
      hr = IAsyncInfo\Status(@status)
      ;     Debug "IAsyncInfo::Status = 0x" + Hex(hr) + " - " + Hex(status)
      
      If (status <> 0)
        If (status <> 1)
          IAsyncInfo\ErrorCode(@ErrorCode)
          Debug "ER IAsyncInfo status error 0x" + Hex(ErrorCode, #PB_Long)
          End
        EndIf      
        IAsyncInfo\Release()
        Break
      EndIf
      Sleep_(10)
    Wend
    
    Protected ObjectResult
    
    *Object\GetResults(@ObjectResult)
    If ObjectResult
      *Object\Release()
      
      *InOut\i = ObjectResult
    EndIf
    ProcedureReturn ObjectResult
    
  EndProcedure
  
  
  Procedure FileToRandomAccessStream(sFile.s)
    
    If Not RT_INIT_DONE
      RT_Init()
      If Not RT_INIT_DONE
        ProcedureReturn 0
      EndIf
    EndIf
    
    Protected IRandomAccessStream.IRandomAccessStream
    Protected hr.l = RT_Funcs\CreateRandomAccessStreamOnFile(@sFile, 0, ?IID_IRandomAccessStream, @IRandomAccessStream)
    CompilerIf #MyRoDebug : Debug "CreateRandomAccessStreamOnFile = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
    
    ProcedureReturn IRandomAccessStream
    
  EndProcedure
  
  
  Structure PICTDESC_bmp
    hbitmap.i
    hpal.i
  EndStructure
  
  Structure PICTDESC_wmf
    hmete.i
    xExt.l
    yExt.l
  EndStructure
  
  Structure PICTDESC_icon
    hicon.i
  EndStructure
  
  Structure PICTDESC_emf
    hemf.i
  EndStructure
  
  Structure PICTDESC
    cbSizeofstruct.l
    picType.l
    StructureUnion
      bmp.PICTDESC_bmp
      wmf.PICTDESC_wmf
      icon.PICTDESC_icon
      emf.PICTDESC_emf    
    EndStructureUnion
  EndStructure
  
  
  Procedure HBitmapToRandomAccessStream(hBitmap)
    
    If Not RT_INIT_DONE
      RT_Init()
      If Not RT_INIT_DONE
        ProcedureReturn 0
      EndIf
    EndIf
    
    Protected pIStream.IStream, pIPicture.IPicture, hr.l
    hr = CreateStreamOnHGlobal_(0, #True, @pIStream)
    If pIStream
      
      #PICTYPE_BITMAP = 1
      
      Protected PD.PICTDESC
      PD\cbSizeofstruct = SizeOf(PICTDESC)
      PD\picType = #PICTYPE_BITMAP
      PD\bmp\hbitmap = hBitmap
      
      hr = OleCreatePictureIndirect_(@PD, ?IID_IPicture, #False, @pIPicture)
      If pIPicture
        
        Protected cbSize
        hr = pIPicture\SaveAsFile(pIStream, #True, 0)
        
        Protected pIRandomAccessStream.IRandomAccessStream
        #BSOS_DEFAULT = 0
        hr = RT_Funcs\CreateRandomAccessStreamOverStream(pIStream, #BSOS_DEFAULT, ?IID_IRandomAccessStream, @pIRandomAccessStream)
        pIPicture\Release()
      EndIf
      
      pIStream\Release()
    EndIf
    
    ProcedureReturn pIRandomAccessStream
    
  EndProcedure
  
  
  
  Procedure HBitmapFromHWND(hWnd, x = 0, y = 0, w = 0, h = 0)
    
    Protected HDC, rc.rect, HBM, PDC
    
    HDC = GetDC_(hWnd)
    If HDC
      GetWindowRect_(hWnd, @rc)
      If w = 0 : w = rc\right - rc\left : EndIf
      If h = 0 : h = rc\bottom - rc\top : EndIf
      
      HBM = CreateCompatibleBitmap_(HDC, W, H)
      If HBM
        PDC = CreateCompatibleDC_(HDC)
        If PDC
          SelectObject_(PDC, HBM)
          BitBlt_(PDC, 0, 0, W, H, HDC, X, Y, #SRCCOPY)
          DeleteDC_(PDC)
        EndIf
      EndIf
      ReleaseDC_(hWnd, HDC)
    EndIf
    ProcedureReturn HBM
  EndProcedure
  
  
  ;-
  ;- WorkerFuncs
  ;-
  
  Procedure.s GetOCRFromImage(IRandomAccessStream.IRandomAccessStream, sLanguage.s = "", bReturnLanguages = 0)
    
    If Not RT_INIT_DONE
      RT_Init()
      If Not RT_INIT_DONE
        ProcedureReturn ""
      EndIf
    EndIf
    
    Static ILanguageFactory.ILanguageFactory
    Static IBitmapDecoderStatics.IBitmapDecoderStatics
    Static IOcrEngineStatics.IOcrEngineStatics
    Static IGlobalizationPreferencesStatics.IGlobalizationPreferencesStatics
    Static MaxDimension
    
    Protected hString, hr.l, bSupported, i, sOCRText.s
    Protected hText, length, *p, count, hLanguage, iFrames, width, height, iUsedLanguage
    
    Protected IOcrEngine.IOcrEngine
    Protected ILanguageList.IReadOnlyList
    Protected ILanguageTest.ILanguage
    
    Protected IBitmapDecoder.IBitmapDecoder
    Protected IBitmapFrame.IBitmapFrame
    Protected IClosable.IClosable
    Protected IOcrResult.IOcrResult
    
    Protected ILinesList.IReadOnlyList
    Protected IBitmapFrameWithSoftwareBitmap.IBitmapFrameWithSoftwareBitmap
    Protected ISoftwareBitmap.ISoftwareBitmap
    Protected IOCRLine.ILanguage
    
    If ILanguageFactory = 0 Or
       IBitmapDecoderStatics = 0 Or
       IOcrEngineStatics = 0 Or
       IGlobalizationPreferencesStatics = 0
      hr = CreateClass("Windows.Globalization.Language", "{9B0252AC-0C27-44F8-B792-9793FB66C63E}", @ILanguageFactory)    
      CompilerIf #MyRoDebug : Debug "CreateClass Windows.Globalization.Language = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
      
      hr = CreateClass("Windows.Graphics.Imaging.BitmapDecoder", "{438CCB26-BCEF-4E95-BAD6-23A822E58D01}", @IBitmapDecoderStatics)
      CompilerIf #MyRoDebug : Debug "CreateClass Windows.Graphics.Imaging.BitmapDecoder = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
      
      hr = CreateClass("Windows.Media.Ocr.OcrEngine", "{5BFFA85A-3384-3540-9940-699120D428A8}", @IOcrEngineStatics)
      CompilerIf #MyRoDebug : Debug "CreateClass Windows.Media.Ocr.OcrEngine = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
      
      hr = CreateClass("Windows.System.UserProfile.GlobalizationPreferences", "{01BF4326-ED37-4E96-B0E9-C1340D1EA158}", @IGlobalizationPreferencesStatics)
      CompilerIf #MyRoDebug : Debug "CreateClass Windows.System.UserProfile.GlobalizationPreferences = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
    EndIf
    
    
    If ILanguageFactory = 0 Or
       IBitmapDecoderStatics = 0 Or
       IOcrEngineStatics = 0 Or
       IGlobalizationPreferencesStatics = 0
      Goto Release
    EndIf
    
    If Not MaxDimension
      IOcrEngineStatics\MaxDimensions(@MaxDimension)
    EndIf
    
  
    
    If sLanguage = ""
      
      hr = IGlobalizationPreferencesStatics\get_Languages(@ILanguageList)
      CompilerIf #MyRoDebug : Debug "IGlobalizationPreferencesStatics::get_Languages = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
      
      
      
      If ILanguageList
        hr = ILanguageList\count(@count)
        CompilerIf #MyRoDebug : Debug "ILanguageList::count = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
        
        For i = 0 To count -1
          hr = ILanguageList\get_Item(0, @hString)
          CompilerIf #MyRoDebug : Debug "ILanguageList::get_Item = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
          
          hr = ILanguageFactory\createLanguage(hString, @ILanguageTest)
          CompilerIf #MyRoDebug : Debug "ILanguageFactory::createLanguage = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
          
          If ILanguageTest
            hr = IOcrEngineStatics\IsLanguageSupported(ILanguageTest, @bSupported)
            CompilerIf #MyRoDebug : Debug "IOcrEngineStatics::IsLanguageSupported = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
            
            If bSupported
              hText = 0
              ILanguageTest\get_LanguageTag(@hText)
              CompilerIf #MyRoDebug : Debug "ILanguageTest::get_LanguageTag = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
              
              If hText
                *p = RT_Funcs\WindowsGetStringRawBuffer(hText, @length)
                If *p
                  sLanguage = PeekS(*p)
                  If bReturnLanguages
                    sOCRText + sLanguage + #CRLF$
                  EndIf
                  ;Debug sLanguage
                EndIf
                
              EndIf
              
            EndIf
            
            ILanguageTest\Release()
          EndIf
        Next
        
        ILanguageList\Release()
      EndIf
      
    EndIf
    
    
    If bReturnLanguages
      Goto Release
    EndIf
    
    hString = 0
    CreateHString(sLanguage, @hString)
    If hString
      hr = ILanguageFactory\createLanguage(hString, @iUsedLanguage)
      CompilerIf #MyRoDebug : Debug "ILanguageFactory::createLanguage = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
      
      hr = RT_Funcs\WindowsDeleteString(hString)
      CompilerIf #MyRoDebug : Debug "WindowsDeleteString = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
      
      hr = IOcrEngineStatics\TryCreateFromLanguage(iUsedLanguage, @IOcrEngine)
      CompilerIf #MyRoDebug : Debug "IOcrEngineStatics::TryCreateFromLanguage = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
      
      If IOcrEngine
        
        If IRandomAccessStream
          hr = IBitmapDecoderStatics\CreateAsync(IRandomAccessStream, @IBitmapDecoder)
          CompilerIf #MyRoDebug : Debug "IBitmapDecoderStatics::CreateAsync = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
          
          If IBitmapDecoder
            WaitForAsync(@IBitmapDecoder)
            
            hr = IBitmapDecoder\FrameCount(@iFrames)
            CompilerIf #MyRoDebug : Debug "IBitmapDecoder::FrameCount = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
            
            hr = IBitmapDecoder\QueryInterface(?IID_IBitmapFrame, @IBitmapFrame)
            CompilerIf #MyRoDebug : Debug "IBitmapDecoder::QueryInterface = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
            
            If IBitmapFrame
              hr = IBitmapFrame\PixelWidth(@width)
              CompilerIf #MyRoDebug : Debug "IBitmapFrame::PixelWidth = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
              
              hr = IBitmapFrame\PixelHeight(@height)
              CompilerIf #MyRoDebug : Debug "IBitmapFrame::PixelHeight = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
              
              If width > MaxDimension Or height > MaxDimension
                Debug "ER: Image is to big"
              Else
               
                hr = IBitmapDecoder\QueryInterface(?IID_IBitmapFrameWithSoftwareBitmap, @IBitmapFrameWithSoftwareBitmap)
                CompilerIf #MyRoDebug : Debug "IBitmapDecoder::QueryInterface = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
                
                If IBitmapFrameWithSoftwareBitmap
                  hr = IBitmapFrameWithSoftwareBitmap\GetSoftwareBitmapAsync(@ISoftwareBitmap)
                  CompilerIf #MyRoDebug : Debug "IBitmapFrameWithSoftwareBitmap::GetSoftwareBitmapAsync = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
                  
                  If ISoftwareBitmap
                    WaitForAsync(@ISoftwareBitmap)
                    
                    IOcrEngine\RecognizeAsync(ISoftwareBitmap, @IOcrResult)
                    CompilerIf #MyRoDebug : Debug "IOcrEngine::RecognizeAsync = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
                    
                    If IOcrResult
                      WaitForAsync(@IOcrResult)
                      
                      hr = IOcrResult\Lines(@ILinesList)
                      CompilerIf #MyRoDebug : Debug "IOcrResult::Lines = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
                      
                      If ILinesList
                        count = 0
                        hr = ILinesList\count(@count)
                        CompilerIf #MyRoDebug : Debug "ILinesList::count = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
                        
                        For i = 0 To count -1
                          hText = 0
                          hr = ILinesList\get_Item(i, @IOCRLine)
                          CompilerIf #MyRoDebug : Debug "ILinesList::get_Item = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
                          
                          hr = IOCRLine\get_DisplayName(@hText)
                          CompilerIf #MyRoDebug : Debug "IOCRLine::get_DisplayName = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
                          
                          If hText
                            *p = RT_Funcs\WindowsGetStringRawBuffer(hText, 0)
                            If *p
                              sOCRText + PeekS(*p) + #CRLF$
                            EndIf
                          EndIf
                          IOCRLine\Release()
                          
                        Next
                        
                      EndIf
                    EndIf
                  EndIf
                EndIf
                
                
              EndIf
            EndIf
            
          EndIf
          If ISoftwareBitmap
            hr = ISoftwareBitmap\QueryInterface(?IID_IClosable, @IClosable)
            CompilerIf #MyRoDebug : Debug "ISoftwareBitmap::QueryInterface = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
            If IClosable
              IClosable\Close()
              IClosable\Release()
              IClosable = 0
            EndIf
          EndIf
          
        EndIf
        
        IOcrEngine\Release()
        
      EndIf
      
    EndIf
    
    Release:
    
    If IBitmapDecoder : IBitmapDecoder\Release() : EndIf
    If IBitmapFrame : IBitmapFrame\Release() : EndIf
    If IBitmapFrameWithSoftwareBitmap : IBitmapFrameWithSoftwareBitmap\Release() : EndIf
    If ISoftwareBitmap : ISoftwareBitmap\Release() : EndIf
    If IOcrResult : IOcrResult\Release() : EndIf
    If ILinesList : ILinesList\Release() : EndIf
    
    CompilerIf #MyRoDebug : Debug "### Func End ###" + #CRLF$ : CompilerEndIf
    
    ProcedureReturn sOCRText
    
  EndProcedure
  
  
  
  Procedure FaceDetect(IRandomAccessStream, List rcList.rect(), maxheight = 2000)
    
    Static IBitmapDecoderStatics.IBitmapDecoderStatics
    Static IBitmapEncoderStatics.IBitmapEncoderStatics
    Static ISoftwareBitmapStatics.ISoftwareBitmapStatics
    Static IFaceDetectorStatics.IFaceDetectorStatics
    
    Protected IFaceDetector.IFaceDetector
    Protected IReadOnlyList.IReadOnlyList
    Protected IBitmapDecoder.IBitmapDecoder
    Protected IBitmapEncoder.IBitmapEncoder
    Protected IBitmapFrame.IBitmapFrame
    Protected IBitmapFrameWithSoftwareBitmap.IBitmapFrameWithSoftwareBitmap
    Protected IBitmapTransform.IBitmapTransform
    Protected ISoftwareBitmap.ISoftwareBitmap, ISoftwareBitmapTemp.ISoftwareBitmap
    Protected IClosable.IClosable
    Protected IDetectedFaceList.IReadOnlyList
    Protected IDetectedFace.IDetectedFace
    
    Protected hr.l, iCount, i, hString, *p
    Protected BitmapPixelFormat
    Protected sSupportedBitmapPixelFormats.s
    Protected width, height, rc.rect
    
    If Not RT_INIT_DONE
      RT_Init()
      If Not RT_INIT_DONE
        ProcedureReturn 0
      EndIf
    EndIf
    
    If IBitmapDecoderStatics = 0 Or
       IBitmapEncoderStatics = 0 Or
       ISoftwareBitmapStatics = 0 Or
       IFaceDetectorStatics = 0
      
      hr = CreateClass("Windows.Graphics.Imaging.BitmapDecoder", "{438CCB26-BCEF-4E95-BAD6-23A822E58D01}", @IBitmapDecoderStatics)    
      CompilerIf #MyRoDebug : Debug "CreateClass Windows.Graphics.Imaging.BitmapDecoder = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
      
      hr = CreateClass("Windows.Graphics.Imaging.BitmapEncoder", "{A74356A7-A4E4-4EB9-8E40-564DE7E1CCB2}", @IBitmapEncoderStatics)
      CompilerIf #MyRoDebug : Debug "CreateClass Windows.Graphics.Imaging.BitmapEncoder = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
      
      hr = CreateClass("Windows.Graphics.Imaging.SoftwareBitmap", "{DF0385DB-672F-4A9D-806E-C2442F343E86}", @ISoftwareBitmapStatics)
      CompilerIf #MyRoDebug : Debug "CreateClass Windows.Graphics.Imaging.SoftwareBitmap = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
      
      hr = CreateClass("Windows.Media.FaceAnalysis.FaceDetector", "{BC042D67-9047-33F6-881B-6746C1B218B8}", @IFaceDetectorStatics)
      CompilerIf #MyRoDebug : Debug "CreateClass Windows.Media.FaceAnalysis.FaceDetector = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
      
    EndIf
    
    
    If IBitmapDecoderStatics = 0 Or
       IBitmapEncoderStatics = 0 Or
       ISoftwareBitmapStatics = 0 Or
       IFaceDetectorStatics = 0
      Goto Release
    EndIf
    
    
    hr = IFaceDetectorStatics\CreateAsync(@IFaceDetector)
    CompilerIf #MyRoDebug : Debug "IFaceDetectorStatics::CreateAsync = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
    
    If IFaceDetector
      
      WaitForAsync(@IFaceDetector)
      hr = IFaceDetectorStatics\GetSupportedBitmapPixelFormats(@IReadOnlyList)
      CompilerIf #MyRoDebug : Debug "IFaceDetectorStatics::GetSupportedBitmapPixelFormats = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
      
      If IReadOnlyList
        hr = IReadOnlyList\count(@iCount)
        CompilerIf #MyRoDebug : Debug "IReadOnlyList::count = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
        
        For i = 0 To iCount -1
          hr = IReadOnlyList\get_Item(i, @BitmapPixelFormat)
          CompilerIf #MyRoDebug : Debug "ILanguageList::get_Item = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
          
          sSupportedBitmapPixelFormats + "|" + Str(BitmapPixelFormat) + "|"
          
        Next
        
        IReadOnlyList\Release()
        
      EndIf
      
      IFaceDetectorStatics\Release()
      
    EndIf
    
    
    
    hr = IBitmapDecoderStatics\CreateAsync(IRandomAccessStream, @IBitmapDecoder)
    CompilerIf #MyRoDebug : Debug "IBitmapDecoderStatics::CreateAsync = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
    
    If IBitmapDecoder
      WaitForAsync(@IBitmapDecoder)
      hr = IBitmapDecoder\QueryInterface(?IID_IBitmapFrame, @IBitmapFrame)
      CompilerIf #MyRoDebug : Debug "IBitmapDecoder::QueryInterface = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
      
      If IBitmapFrame
        hr = IBitmapFrame\PixelWidth(@width)
        CompilerIf #MyRoDebug : Debug "IBitmapFrame::PixelWidth = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
        
        hr = IBitmapFrame\PixelHeight(@height)
        CompilerIf #MyRoDebug : Debug "IBitmapFrame::PixelHeight = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
        
        hr = IBitmapFrame\BitmapPixelFormat(@BitmapPixelFormat)
        CompilerIf #MyRoDebug : Debug "IBitmapFrame::BitmapPixelFormat = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
        
        hr = IBitmapDecoder\QueryInterface(?IID_IBitmapFrameWithSoftwareBitmap, @IBitmapFrameWithSoftwareBitmap)
        CompilerIf #MyRoDebug : Debug "IBitmapDecoder::QueryInterface = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
        
        If IBitmapFrameWithSoftwareBitmap
          
          If (height > maxheight)
            hr = IBitmapEncoderStatics\CreateForTranscodingAsync(IRandomAccessStream, IBitmapDecoder, @IBitmapEncoder)
            CompilerIf #MyRoDebug : Debug "IBitmapEncoderStatics::CreateForTranscodingAsync = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
            
            If IBitmapEncoder
              WaitForAsync(@IBitmapEncoder)
              hr = IBitmapEncoder\BitmapTransform(@IBitmapTransform)
              CompilerIf #MyRoDebug : Debug "IBitmapEncoder::BitmapTransform = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
              
              If IBitmapTransform
                hr = IBitmapTransform\ScaledWidth((maxheight/height*width))
                CompilerIf #MyRoDebug : Debug "IBitmapTransform::ScaledWidth = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
                
                hr = IBitmapTransform\ScaledHeight(maxheight)
                CompilerIf #MyRoDebug : Debug "IBitmapTransform::ScaledHeight = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
                
                hr = IBitmapFrameWithSoftwareBitmap\GetSoftwareBitmapTransformedAsync(BitmapPixelFormat, 0, IBitmapTransform, 0, 0, @ISoftwareBitmap)
                CompilerIf #MyRoDebug : Debug "IBitmapFrameWithSoftwareBitmap::GetSoftwareBitmapTransformedAsync = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
                
              EndIf
              
            EndIf
            
          Else
            hr = IBitmapFrameWithSoftwareBitmap\GetSoftwareBitmapAsync(@ISoftwareBitmap)
            CompilerIf #MyRoDebug : Debug "IBitmapFrameWithSoftwareBitmap::GetSoftwareBitmapTransformedAsync = 0x" + Hex(hr, #PB_Long) : CompilerEndIf            
          EndIf
          
          If ISoftwareBitmap
            WaitForAsync(@ISoftwareBitmap)
            
            If Not FindString(sSupportedBitmapPixelFormats, "|" + BitmapPixelFormat + "|")
              hr = ISoftwareBitmapStatics\Convert(ISoftwareBitmap, 62, @ISoftwareBitmapTemp)
              CompilerIf #MyRoDebug : Debug "ISoftwareBitmapStatics::Convert = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
              hr = ISoftwareBitmap\QueryInterface(?IID_IClosable, @IClosable)
              
              If IClosable
                IClosable\Close()
                IClosable\Release()
              EndIf
              
              ISoftwareBitmap\Release()
              
              ISoftwareBitmap = ISoftwareBitmapTemp
              
            EndIf
            
            hr = IFaceDetector\DetectFacesAsync(ISoftwareBitmap, @IDetectedFaceList)
            CompilerIf #MyRoDebug : Debug "IFaceDetector\DetectFacesAsync = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
            
            If IDetectedFaceList
              WaitForAsync(@IDetectedFaceList)
              
              hr = IDetectedFaceList\count(@iCount)
              CompilerIf #MyRoDebug : Debug "IDetectedFaceList::count = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
              
              For i = 0 To iCount -1
                
                hr = IDetectedFaceList\get_Item(i, @IDetectedFace)
                CompilerIf #MyRoDebug : Debug "IDetectedFaceList::get_Item = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
                
                If IDetectedFace
                  AddElement(rcList())
                  hr = IDetectedFace\FaceBox(@rcList())
                  CompilerIf #MyRoDebug : Debug "IDetectedFace::FaceBox = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
                  
                  IDetectedFace\Release()
                  IDetectedFace = 0
                EndIf
                
              Next
              
            EndIf
            
            
            hr = ISoftwareBitmap\QueryInterface(?IID_IClosable, @IClosable)
            CompilerIf #MyRoDebug : Debug "ISoftwareBitmap::QueryInterface = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
            If IClosable
              IClosable\Close()
              IClosable\Release()
              IClosable = 0
            EndIf
            
            
          EndIf
          
        EndIf
        
      EndIf
      
    EndIf
    
    Release:
    
    
    If IBitmapDecoder : IBitmapDecoder\Release() : EndIf
    If IBitmapFrame : IBitmapFrame\Release() : EndIf
    
    If (height > maxheight)
      If IBitmapEncoder : IBitmapEncoder\Release() : EndIf
      If IBitmapTransform : IBitmapTransform\Release() : EndIf
    EndIf
    
    If IBitmapFrameWithSoftwareBitmap : IBitmapFrameWithSoftwareBitmap\Release() : EndIf
    If IDetectedFaceList : IDetectedFaceList\Release() : EndIf
    
    If IFaceDetector : IFaceDetector\Release() : EndIf
    
  EndProcedure
  
  ;-
  ;- Module Exports
  ;-
  
  Procedure.s get_Languages()
    ProcedureReturn GetOCRFromImage(0, "", 1)
  EndProcedure
  
  
  
  
  
  
  Procedure.s get_TextFromFile(sFile.s, sLanguage.s = "")
    
    Protected sOutPut.s
    Protected IRandomAccessStream.IRandomAccessStream = FileToRandomAccessStream(sFile)
    If IRandomAccessStream
      sOutPut = GetOCRFromImage(IRandomAccessStream, sLanguage, 0)
      
      Protected IClosable.IClosable
      Protected hr.l = IRandomAccessStream\QueryInterface(?IID_IClosable, @IClosable)
      CompilerIf #MyRoDebug : Debug "IRandomAccessStream::QueryInterface = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
      
      If IClosable
        IClosable\Close()
        IClosable\Release()
        IClosable = 0
      EndIf
      IRandomAccessStream\Release()
      
    EndIf
    ProcedureReturn sOutPut
    
  EndProcedure
  
  
  
  Procedure.s get_TextFromImageID(ImageID, sLanguage.s = "")
    
    Protected sOutPut.s
    Protected IRandomAccessStream.IRandomAccessStream = HBitmapToRandomAccessStream(ImageID)
    If IRandomAccessStream
      sOutPut = GetOCRFromImage(IRandomAccessStream, sLanguage, 0)
      
      Protected IClosable.IClosable
      Protected hr.l = IRandomAccessStream\QueryInterface(?IID_IClosable, @IClosable)
      CompilerIf #MyRoDebug : Debug "IRandomAccessStream::QueryInterface = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
      
      If IClosable
        IClosable\Close()
        IClosable\Release()
        IClosable = 0
      EndIf
      IRandomAccessStream\Release()
      
    EndIf
    ProcedureReturn sOutPut
  EndProcedure
  
  
  Procedure.s get_TextFromHWND(hWND, sLanguage.s = "")
    
    Protected sOutPut.s
    Protected ImageID = HBitmapFromHWND(hWND)
    If ImageID
      Protected IRandomAccessStream.IRandomAccessStream = HBitmapToRandomAccessStream(ImageID)
      If IRandomAccessStream
        sOutPut = GetOCRFromImage(IRandomAccessStream, sLanguage, 0)
        
        Protected IClosable.IClosable
        Protected hr.l = IRandomAccessStream\QueryInterface(?IID_IClosable, @IClosable)
        CompilerIf #MyRoDebug : Debug "IRandomAccessStream::QueryInterface = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
        
        If IClosable
          IClosable\Close()
          IClosable\Release()
          IClosable = 0
        EndIf
        IRandomAccessStream\Release()
        
      EndIf
      DeleteObject_(ImageID)
    EndIf
    ProcedureReturn sOutPut
  EndProcedure
  
  ;-
  
  Procedure get_FacesFromFile(sFile.s, List rcList.rect())
    
    Protected iCount
    Protected IRandomAccessStream.IRandomAccessStream = FileToRandomAccessStream(sFile)
    If IRandomAccessStream
      iCount = facedetect(IRandomAccessStream, rcList())
      
      Protected IClosable.IClosable
      Protected hr = IRandomAccessStream\QueryInterface(?IID_IClosable, @IClosable)
      CompilerIf #MyRoDebug : Debug "IRandomAccessStream::QueryInterface = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
      
      If IClosable
        IClosable\Close()
        IClosable\Release()
        IClosable = 0
      EndIf
      IRandomAccessStream\Release()
      
    EndIf
    ProcedureReturn iCount
    
  EndProcedure
  
  
  Procedure get_FacesFromImageID(ImageID, List rcList.rect())
    
    Protected iCount
    Protected IRandomAccessStream.IRandomAccessStream = HBitmapToRandomAccessStream(ImageID)
    If IRandomAccessStream
      iCount = facedetect(IRandomAccessStream, rcList())
      
      Protected IClosable.IClosable
      Protected hr = IRandomAccessStream\QueryInterface(?IID_IClosable, @IClosable)
      CompilerIf #MyRoDebug : Debug "IRandomAccessStream::QueryInterface = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
      
      If IClosable
        IClosable\Close()
        IClosable\Release()
        IClosable = 0
      EndIf
      IRandomAccessStream\Release()
      
    EndIf
    ProcedureReturn iCount
    
  EndProcedure
  
  
  Procedure get_FacesFromHWND(hWND, List rcList.rect())
    
    Protected iCount
    Protected ImageID = HBitmapFromHWND(hWND)
    If ImageID
      Protected IRandomAccessStream.IRandomAccessStream = HBitmapToRandomAccessStream(ImageID)
      If IRandomAccessStream
        iCount = facedetect(IRandomAccessStream, rcList())
        
        Protected IClosable.IClosable
        Protected hr = IRandomAccessStream\QueryInterface(?IID_IClosable, @IClosable)
        CompilerIf #MyRoDebug : Debug "IRandomAccessStream::QueryInterface = 0x" + Hex(hr, #PB_Long) : CompilerEndIf
        
        If IClosable
          IClosable\Close()
          IClosable\Release()
          IClosable = 0
        EndIf
        IRandomAccessStream\Release()
        
      EndIf
      
      DeleteObject_(ImageID)
    EndIf
    
    ProcedureReturn iCount
    
  EndProcedure
  
EndModule
CompilerIf #PB_Compiler_IsMainFile
  
  
  Structure tOCR_DEMO
    sFile.s
    ImageID.i
    ;
    sLanguages.s  
    sFromFile.s
    sFromImage.s
    
    List rcFaces.Rect()
    
  EndStructure
  
  ;-
  
  Procedure OCR_DEMO(*OCR_DEMO.tOCR_DEMO)
    *OCR_DEMO\sLanguages = WinOCR::get_Languages()
    If *OCR_DEMO\sFile <> ""
      *OCR_DEMO\sFromFile = WinOCR::get_TextFromFile(*OCR_DEMO\sFile)
    EndIf
    If *OCR_DEMO\ImageID
      *OCR_DEMO\sFromImage = WinOCR::get_TextFromImageID(*OCR_DEMO\ImageID)
    EndIf
    
    WinOCR::get_FacesFromFile(*OCR_DEMO\sFile, *OCR_DEMO\rcFaces())
    
  EndProcedure
  
  
  
  Procedure HBitmapFromScreen(X, Y, W, H)
    Protected HDC = GetDC_(0)
    Protected HBM = CreateCompatibleBitmap_(HDC, W, H)
    Protected PDC = CreateCompatibleDC_(HDC)
    SelectObject_(PDC, HBM)
    BitBlt_(PDC, 0, 0, W, H, HDC, X, Y, #SRCCOPY)
    DeleteDC_(PDC)
    ReleaseDC_(0, HDC)
    ProcedureReturn HBM
  EndProcedure
  
  
  
  
  Define tOCR_DEMO.tOCR_DEMO
  
  tOCR_DEMO\sFile = OpenFileRequester("Choose Image File", "Image.png", "ImageFiles (*.png;jpg;gif;bmp;tif;tiff)|*.png;*.jpg;*.gif;*.bmp;*.tif;*.tiff", 0)
  If tOCR_DEMO\sFile
    
    ;UsePNGImageDecoder()
    ;UseJPEGImageDecoder()
    ;UseTIFFImageDecoder()
    ;LoadImage(0, tOCR_DEMO\sFile)
    ;tOCR_DEMO\ImageID = ImageID(0)
    
    tOCR_DEMO\ImageID = HBitmapFromScreen(0, 0, 800, 600)
    
    Define thread = CreateThread(@OCR_DEMO(), @tOCR_DEMO)
    If thread
      WaitThread(thread)
      
      Define sFaces.s = "Detected Faces = " + Str(ListSize(tOCR_DEMO\rcFaces())) + #CRLF$
      ForEach tOCR_DEMO\rcFaces()
        sFaces + #CRLF$ + Str(tOCR_DEMO\rcFaces()\left) + ", " + Str(tOCR_DEMO\rcFaces()\top) + ", " + Str(tOCR_DEMO\rcFaces()\right) + ", " + Str(tOCR_DEMO\rcFaces()\bottom)    
      Next
      
      MessageRequester("Available Languages", tOCR_DEMO\sLanguages)
      MessageRequester("TextFromFile", tOCR_DEMO\sFromFile)
      MessageRequester("TextFromImageID", tOCR_DEMO\sFromImage)
      
      MessageRequester("Faces", sFaces)
      
    EndIf
  EndIf
  
CompilerEndIfUpdated Version: Windows 10 OCR and Face detection



 
 











