Tekninen artikkeli

HotPDF in-process RapidOCR: natiivi DLL-OCR Delphissä

HotPDF tekee skannatuista PDF-sivuista haettavia in-process RapidOCR:lla funktion HPDFCreateRapidOCRDLLOCREngine kautta, versiossa v2.774.0 lisätty tehdas, joka lataa HotPDFRapidOCR.dllin, pitää ONNX-detektointi-, kulmaluokittelu- ja tunnistusmallit muistissa ja palauttaa IHPDFOCREnginen. Annat kyseisen moottorin funktiolle THotPDF.ApplyLoadedOCRTextLayer, joka renderöi jokaisen sivun, ajaa CPU-inferenssin ilman Pythonia tai lapsiprosessia ja vahvistaa näkymättömän Unicode-tekstitason

Perustelu on kustannus sivua kohden. Aiemmin toimitettu RapidOCR-prosessisovitin, HPDFCreateRapidOCREngine, käynnistää Python-työläisen jokaiselle Recognize-kutsulle, ja kyseinen työläinen tuo ajonympäristönsä ja lataa ONNX-mallinsa ennen kuin lukee yhtään pikseliä. 500 sivun arkistossa kyseinen käynnistysvero toistuu 500 kertaa, ja käyttöönotto tarkoittaa Python-ympäristön toimittamista Delphi-suoritettavan viereen. Natiivi DLL lataa mallit kerran, kun luot moottorin, ja käyttöönotto kutistuu DLL:ään, sen mallitiedostoihin ja merkistösanakirjaan. Se, mistä luoput vastineeksi, on mahdollisuus tappaa jumiutunut tunnistin, ja suurin osa tämän sovittimen suunnittelusta on siitä selviämistä rehellisesti

Miten skannatusta PDF:stä tehdään haettava RapidOCR-DLL:llä?

Haettavan PDF:n luominen natiivilla RapidOCR-DLL:llä vie yhden tehdaskutsun ja saman ApplyLoadedOCRTextLayer-kutsun, jota jokainen HotPDF-OCR-moottori käyttää. Tehdas asuu yksikössä HPDFRapidOCRRecognition ja validoi innokkaasti: DLL:n ja mallikansion on oltava olemassa, jokaisen mallin ja sanakirjatiedoston on ratkeava, ABI-version on oltava 1, ja kaikkien vaadittujen vientien on oltava läsnä ennen kuin yksikään malli alustetaan. Määritysvirheet nostavat EArgumentExceptionn; latautumista epäonnistuva malli nostaa EInvalidOperationin, joka kantaa DLL:n kirjoittaman diagnostiikkatekstin

HotPDF RapidOCR DLL -tehtaan validointijakso funktiolle HPDFCreateRapidOCRDLLOCREngine: polkujen ja mallitiedostojen on oltava olemassa, HPDFRapidOCRAbiVersionin on palautettava 1, vaadittujen vientien on ratkeava, ja HPDFRapidOCRCreaten on alustettava mallit, jolloin EArgumentException tai EInvalidOperation nostetaan innokkaasti ennen minkään tunnistuksen alkamista, jälkimmäinen kantaen natiivia diagnostiikkatekstiä
Validointi on innokasta tahallaan: määritysongelmat nostavat virheen ennen minkään mallin alustumista, joten huono polku tai ABI ei koskaan yletä tunnistustakarajaan
uses
  SysUtils, HPDFTypes, HPDFDoc, HPDFRapidOCRRecognition;

procedure MakeSearchable(const SourceFile, TargetFile: string);
var
  Doc: THotPDF;
  Engine: IHPDFOCREngine;
  Options: THPDFOCRTextLayerOptions;
  Info: THPDFOCRTextLayerInfo;
begin
  // Mallit latautuvat tässä, minkään tunnistustakarajan ulkopuolella.
  // THPDFRapidOCRDLLOptions.Defaultin suhteelliset mallinimet ratkeavat
  // mallikansiota vasten.
  Engine := HPDFCreateRapidOCRDLLOCREngine(
    'C:\OCR\Win64\HotPDFRapidOCR.dll', 'C:\OCR\models');
  Doc := THotPDF.Create(nil);
  try
    Doc.AutoLaunch := False;
    if Doc.LoadFromFile(SourceFile) < 1 then
      raise Exception.Create('Cannot load ' + SourceFile);
    Options := THPDFOCRTextLayerOptions.Default;  // 300 DPI, MinimumConfidence 0.5
    // tyhjä sivuluettelo tarkoittaa jokaista sivua; sivut, joilla on jo tekstiä, ohitetaan
    if not Doc.ApplyLoadedOCRTextLayer([], Engine, Options, Info) then
      raise Exception.Create(string(Info.Diagnostic));
    Writeln(string(Info.EngineName), ': ', Info.AcceptedWordCount,
      ' lines accepted, ', Info.DroppedWordCount, ' dropped');
    Doc.SaveLoadedDocument(TargetFile);
  finally
    Doc.Free;
  end;
end;

THPDFRapidOCRDLLOptions.Default nimeää tiedostot ch_PP-OCRv3_det_infer.onnx, ch_PP-OCRv3_rec_infer.onnx, ch_ppocr_mobile_v2.0_cls_infer.onnx ja ppocr_keys_v1.txt, yhdellä CPU-säikeellä, 16 777 216 pikselin syöttörajalla ja 60 000 ms tunnistustakarajalla. Versiosta v2.775.0 alkaen THPDFRapidOCRDLLOptions.ForLanguage vaihtaa paikalleen vastaavan tunnistusmallin ja sanakirjan perinteiselle kiinalaiselle, venäjälle, japanille, arabiaksi ja muille profiileille; miksi mallin ja sanakirjan on vaihduttava yhdessä, käsitellään artikkelissa RapidOCR-monikieliset mallit ja CTC-sanakirjat HotPDF:ssä. Moottori ilmoittaa itsensä muodossa RapidOCR (native DLL) kentässä Info.EngineName, mikä pitää lokit yksiselitteisinä artikkelin ulkoisen Tesseract-OCR-prosessisovittimen ja artikkelin sisäänrakennetun mallivertailu-OCR-moottorin vieressä

Miksi C ABI puhuu vain int32_t:tä ja UTF-8-tavuja?

HotPDFRapidOCR.dllin ABI käyttää vain kiinteän levyisiä kokonaislukuja, raakoja osoittimia ja eksplisiittisiä tavumääriä, koska Delphi, C++Builder ja Free Pascal eivät jaa mitään MSVC:n kanssa C-kutsukäytännön ulkopuolelta. std::stringillä, std::vectorilla tai C++-poikkeuksella on asettelu ja purkumalli, jotka kuuluvat yhdelle kääntäjälle ja yhdelle ajokirjastolle. Anna minkä tahansa niistä ylittää rajan, ja vika on korruptoitunut pino tai väärän allokaattorin vapauttama heap-lohko, ei siisti virhe

ABI-versio 1 noudattaa siksi lyhyttä sääntöluetteloa. Jokainen vienti on cdecl ja palauttaa int32_t-tilan, jossa 1 merkitsee onnistumista ja 0 epäonnistumista. Jokainen epäonnistua voiva funktio ottaa kutsujan omistaman diagnostiikkapuskurin ja sen kapasiteetin tavuina; DLL kirjoittaa NUL-päätteisen UTF-8-viestin, katkaistuna mahtumaan, ja sovitin dekoodaa sen kovalla päätemerkillä oman 4 096-tavuisen puskurinsa viimeisessä tavussa. Jokaisen vientirungon ympärillä on try sekä catch (const std::exception &) että catch (...), joten ONNX Runtime -virhe, OpenCV-assertion tai epäkelpo sanakirja muuttuu tilaksi 0 plus teksti, ei koskaan Pascal-koodiin pakenevaksi poikkeukseksi

VientiRooliMilloin sovitin ratkaisee sen
HPDFRapidOCRAbiVersionPalauttaa arvon 1; mikä tahansa muu arvo hylätäänEnsin, ennen kaikkea muuta
HPDFRapidOCRCreateLataa detektointi-, valinnaisen luokittelun ja tunnistusmallit sekä sanakirjanTehtaassa
HPDFRapidOCRRecognizeAjaa yhden bittikartan ja emittoi yhden callbackin tekstiriviä kohdenTehtaassa
HPDFRapidOCRDestroyVapauttaa malli-instanssinTehtaassa
HPDFRapidOCRSetReadingDirectionValinnainen oikealta vasemmalle -rivijärjestys, lisätty versiossa v2.775.0Vain kun RightToLeft on asetettu

Valinnainen vienti ratkaistaan laiskasti tahallaan: v2.774.0-DLL, jolta se puuttuu, palvelee yhä vasemmalta oikealle -pyyntöjä. DLL ladataan funktiolla LoadLibraryEx, jonka hakuflagit kattavat DLL:n oman kansion plus oletusturvalliset hakemistot, joten HotPDFRapidOCR.dllin viereen sijoitetut ONNX Runtime- tai OpenCV-riippuvuudet löytyvät koskematta muuttujaan PATH. Malli- ja sanakirjapolut kulkevat UTF-8:nä, ja DLL muuntaa ne funktiolla MultiByteToWideChar tiukassa tilassa ennen tiedostojen avaamista leveämerkkisten API:jen kautta, joten kiinalaisen tai kyrillisen käyttäjänimen alla oleva mallikansio toimii sen sijaan, että levennettäisiin tavu tavulta hölynpölyksi

Yksi sääntö elää koostuuversiossa, ei otsikkotiedostossa. DLL linkittää ONNX Runtime:n ja OpenCV:n staattisesti, ja oletusarvoinen CMake-määritys käyttää staattista release-CRT:tä (/MT). /MDä vasten käännetyt staattiset kirjastot, sekoitettuna /MT-DLL:ään, tuottavat parhaimmillaan linkitysvirheitä ja pahimmillaan kaksi itsenäistä heapia, joten hankittujen kirjastojen on vastattava sitä CRT-tilaa, jota DLL käyttää

Mitä tapahtuu TBitmapin ja tekstirivin välillä?

HotPDF ojentaa DLL:lle itsenäisen ylhäältä alas -suuntautuisen BGR-snapshotin renderöidystä sivusta, ja DLL ojentaa takaisin yhden callbackin kutakin tunnistettua tekstiriviä kohden lainatulla UTF-8-tekstillä, jonka sovittimen on kopioitava ennen paluuta

Delphissä sovitin sijoittaa sivubittikartan yksityiseen TBitmapiin, pakottaa muodon pf24bit ja lukee rivit funktiolla GetDIBits negatiivisella biHeightillä, mikä antaa ylhäältä alas -rivit, täytettyinä neljän tavun tasaukseen; kyseinen stride annetaan eksplisiittisesti. FPC:llä se lukee funktion CreateIntfImage kautta, koska LCL-scanline-kirjoitukset voivat päivittää raakakuvaa päivittämättä GDI-kahvaa. Kutsujan bittikarttaa ei koskaan muokata, ja pikselibudjetti (MaxPixels, oletus 16 777 216 ja säädettävissä arvoon 67 108 864 asti) sekä 32 767 pikselin raja per dimensio tarkistetaan ennen snapshot-puskurin varaamista

HotPDF RapidOCR DLL -putki bittikartasta tekstitasoon: sovitin ottaa sivusta ylhäältä alas -suuntautuisen pf24bit BGR -snapshotin, DLL täyttää, detektoi, järjestää ja tunnistaa rajaukset, toimittaa yhden callbackin riviä kohden lainatulla UTF-8-tekstillä, laatikolla ja luottamusarvolla, ja sovitin validoi jokaisen rivin ennen tekstitason vahvistamista
Pikselit ylittävät ABI:n kerran snapshotina, rivit palaavat yksi callback kerrallaan, eikä mikään yletä haettavaan tasoon ennen kuin jokainen tarkistus täyttyy

DLL:n sisällä snapshot täytetään 50 valkoisella pikselillä, tekstialueet detektoidaan 1 024 pikselin maksimisivulla, laatikot järjestetään vaakariveiksi, ja jokainen rajaus kiertyy tarvittaessa kulmaluokittelijan toimesta ennen tunnistusta. Jokainen tekstirivi kulkee sitten callbackin läpi, joka vastaanottaa osoittimen const char*, tavumäärän, kokonaislukulaatikon alkuperäisen kuvan pikseleinä ja keskimääräisen merkkiluottamusarvon. Tekstiosoitin on kelvollinen vain callbackin aikana, joten sovitin kopioi sen heti, ja se on tiukka siinä, mitä hyväksyy:

  • UTF-8 dekoodataan lipulla MB_ERR_INVALID_CHARS; epäkelpo jakso kaataa sivun korvausmerkkien tuottamisen sijaan haettavaan tasoon
  • C0- ja C1-ohjausmerkit hylätään, ja pelkkiä välilyöntejä sisältävät rivit ohitetaan
  • Laatikon on oltava bittikartan sisällä, ja luottamusarvon on oltava äärellinen arvo väliltä 0–1
  • Tekstiä lasketaan pyynnön MaxTextCodeUnitsia vasten kovalla 1 048 576 UTF-16-yksikön katolla per kutsu, ja täydentävän tason merkit maksavat kaksi yksikköä
  • Mikä tahansa Pascal-poikkeus callbackin sisällä napataan sinne, talletetaan ja muutetaan paluuarvoksi 0, mikä saa DLL:n pysähtymään ja raportoimaan epäonnistumisen; talletettu viesti muuttuu sitten diagnostiikaksi

Kaksi seurausta merkitsee viritykselle. Ensinnäkin tulosteen yksikkö on rivi, ei sana: jokainen rivi kuluttaa yhden MaxWords-paikan, kentät Info.AcceptedWordCount ja Info.DroppedWordCount laskevat rivejä, ja hakukorostus ulottuu rivilaatikon yli. Toiseksi MinimumConfidence (oletus 0.5) verrataan rivin keskimääräiseen merkkiluottamusarvoon, joten rivi, jossa on yksi lukukelvoton merkki kahdenkymmenen puhtaan joukossa, selviää yleensä. DLL ei toimita perusviivaa, joten tekstitasoputki estimoi yhden laatikosta. Tyhjä sivu onnistuu nollalla rivillä, ja mikä tahansa epäonnistuminen tyhjentää osittaiset tulokset, joten monisivuinen vahvistus pysyy kaikki-tai-ei mitään -periaatteella

Mallien omistajuus ja säieturvallisuus

Jokainen RapidOCR-DLL-moottori omistaa täsmälleen yhden malli-instanssin koko elinaikansa, ja kyseisen moottorin Recognize-kutsut sarjoitetaan kriittisellä osiolla. Rajapinnan IHPDFOCREngine pitäminen hallussa pitää mallit lämpiminä, joten oikea kaava erätyölle on luoda moottori kerran ja käyttää sitä asiakirjojen yli

procedure OcrBatch(const Files: TStrings; const OutputDir: string);
var
  Models: THPDFRapidOCRDLLOptions;
  Engine: IHPDFOCREngine;
  Doc: THotPDF;
  Options: THPDFOCRTextLayerOptions;
  Info: THPDFOCRTextLayerInfo;
  I: Integer;
begin
  Models := THPDFRapidOCRDLLOptions.Default;
  Models.UseAngleClassifier := False;    // pystysuorat skannaukset: luokittelijamallia ei ladata
  Models.Threads := 4;                   // 1..64, katkaistu loogisten prosessorien määrään
  Models.TimeoutMilliseconds := 120000;  // per Recognize-kutsu, yhteistoiminnallinen
  Engine := HPDFCreateRapidOCRDLLOCREngine(
    'C:\OCR\Win64\HotPDFRapidOCR.dll', 'C:\OCR\models', Models);
  Options := THPDFOCRTextLayerOptions.Default;
  for I := 0 to Files.Count - 1 do
  begin
    Doc := THotPDF.Create(nil);
    try
      Doc.AutoLaunch := False;
      if (Doc.LoadFromFile(Files[I]) > 0) and
        Doc.ApplyLoadedOCRTextLayer([], Engine, Options, Info) then
        Doc.SaveLoadedDocument(IncludeTrailingPathDelimiter(OutputDir) +
          ExtractFileName(Files[I]))
      else
        Writeln(Files[I], ': ', string(Info.Diagnostic));
    finally
      Doc.Free;
    end;
  end;
end;  // viimeinen viittaus vapautettu: mallit tuhotaan, sitten DLL puretaan

Arvo Threads asettaa sekä jokaisen ONNX-istunnon intra-op- että inter-op-säiemäärät, ja DLL katkaisee sen aktiivisten prosessorien määrään. Kaksi säiettä, jotka jakavat yhden moottorin, eivät aja rinnakkain; toinen odottaa lukkoa. Kyseinen odotus ei ole sokea EnterCriticalSection: sovitin kutsuu funktiota TryEnterCriticalSection 25 ms välein ja tarkistaa peruutustokenin ja takarajan yritysten välillä, joten jonossa olevan pyynnön voi yhä peruuttaa tai se voi aikakatkeaa. Jos tarvitset aitoa rinnakkaisuutta, luo yksi moottori työläistä kohden ja hyväksy, että jokainen moottori pitää omat mallikopionsa muistissa

Purkujärjestys on kiinteä moottorin tuhoajassa: HPDFRapidOCRDestroy vapauttaa malli-instanssin ensin, sitten FreeLibrary purkaa DLL:n latauksen. Natiivilla puolella mallin alustus on yhtä huolellinen; kun tunnistusmalli epäonnistuu sen jälkeen, kun detektorin ja luokittelijan istunnot oli jo rakennettu, kyseiset istunnot vapautetaan ennen virheen raportoimista, ja sanakirjan luokkamäärä tarkistetaan mallin tulostusta vasten alustuksen yhteydessä ensimmäisen sivun sijaan

Miksi natiivia OCR-kutsua ei voi tappaa inferenssin keskellä?

Natiivia RapidOCR-kutsua ei voi tappaa inferenssin keskellä, koska se ajaa omalla säikeelläsi, prosessisi sisällä, ONNX Runtime -istunnon keskellä, joka ei hyväksy keskeytystä. Peruuttaminen HotPDF:n DLL-sovittimessa on siksi yhteistoiminnallista: DLL kutsuu abortti-callbackia ennen ja jälkeen detektoinnin, luokittelun jälkeen ja jokaisen tunnistetun rivin jälkeen, ja pysähtyy ensimmäisessä tarkistuspisteessä, jossa callback palauttaa arvon 0. Yksi aloitettu ONNX Run päättyy ensin

Vaihtoehdot ovat huonompia kuin odottaminen. TerminateThread jättäisi CRT-heaplukon, ONNX Runtimen säiepuolan ja minkä tahansa OpenCV-tilan siihen kuntoon, jossa ne sattuivat olemaan, myrkyttäen prosessin loput. FreeLibrary kutsun ollessa yhä kesken purkaa koodia, joka on pinossa. Kumpaakaan ei voi tehdä turvalliseksi, joten sovitin ei koskaan yritä niitä. Takaraja funktiossa TimeoutMilliseconds on siten yhteistoiminnallinen takaraja, ja vanhentunut takaraja ilmestyy moottorivirheenä aikakatkaisudiagnostiikalla, kun taas peruutettu tokeni ilmestyy arvona otlsCancelled:

// Tokenin luo kutsuja ja se on jaettu käyttöliittymäsäikeen kanssa,
// joka kutsuu Token.Cancelia, kun käyttäjä painaa Stop-painiketta
Options := THPDFOCRTextLayerOptions.Default;
Options.CancellationToken := Token;
if not Doc.ApplyLoadedOCRTextLayer([], Engine, Options, Info) then
  case Info.Status of
    otlsCancelled:
      // palautetaan seuraavassa vaiheessa tai rivirajassa; asiakirja muuttumaton
      Writeln('Cancelled');
    otlsEngineError:
      // sisältää yhteistoiminnallisen takarajan umpeutumisen ja natiivit diagnostiikat
      Writeln('Engine: ', string(Info.Diagnostic));
    otlsBudgetExceeded:
      Writeln('Budget: ', string(Info.Diagnostic));
  else
    Writeln(string(Info.Diagnostic));
  end;

Kyse on ydinkompromissi HotPDF:n prosessisovittimien ja in-process-DLL:n välillä, eikä kumpikaan puoli voita jokaista riviä:

HotPDF-OCR-sovittimien kompromissit: prosessisovittimet käynnistävät työläisen ja lataavat mallit jokaiselle sivulle mutta voidaan tappaa ja eristävät kaatumiset, kun taas in-process RapidOCR -DLL lataa mallit kerran, pysähtyy vain yhteistoiminnallisissa tarkistuspisteissä, jakaa osoiteavaruuden ja otetaan käyttöön DLL:nä malleineen ja sanakirjoineen
Valitse työmäärän mukaan: sivu kerrallaan -työskentelevä työpöytäsovellus hyötyy lämpimästä DLL:stä, kun taas luottamattomia skannauksia nielevän palvelimen kannattaa maksaa prosessiseinästä
  • Käynnistyskustannus: Tesseract- ja Python RapidOCR -sovittimet käynnistävät prosessin ja lataavat mallit jokaiselle sivulle; DLL lataa mallit kerran moottoria kohden
  • Pysäyttäminen: lapsiprosessin voi lopettaa suoraan, ja Python-työläinen ajaa kill-on-close Job Objectin sisällä, joten sen koko prosessipuu lähtee mukaan; DLL voi pysähtyä vain vaihe- ja rivirajoissa
  • Vikojen eristys: kaatuminen tiedostossa tesseract.exe epäonnistaa yhden sivun; access violation DLL:n sisällä vie prosessisi alas
  • Käyttöönotto: prosessisovittimet tarvitsevat asennetun ohjelman tai Python-ympäristön; DLL tarvitsee itsensä, mallinsa ja sanakirjansa, sovitettuna sovelluksen bittisyyteen
  • Muisti: prosessisovittimet vapauttavat kaiken, kun lapsi poistuu; DLL-moottori pitää mallinsa muistissa, kunnes viimeinen rajapintaviittaus vapautetaan

Interaktiiviselle työpöytäsovellukselle, joka OCR-aa sivun kerrallaan, DLL:n responsiivisuus voittaa yleensä. Palvelimelle, joka nielee luottamattomia skannauksia ympäri vuorokauden, prosessiraja on maksamisen arvoinen käynnistyskustannuksensa takia

HotPDFRapidOCR.dllin koostaminen ja käyttöönotto

HotPDFRapidOCR.dll koostetaan C++-lähteistä kohteessa Native/RapidOCR MSVC:llä, C++17:llä, Windows SDK:lla ja CMake 3.20:llä tai uudemmalla, käyttäen apuskriptiä, joka ottaa natiivin verkkolähteet sekä ONNX Runtime- ja OpenCV-hakemistot plus Win32- tai Win64-alustan. Koosta molemmat, jos toimitat molemmat, koska 32-bittinen Delphi-sovellus ei voi ladata 64-bittistä DLL:ää, ja hankkimiesi staattisten kirjastojen on vastattava kohdearkkitehtuuria samoin kuin CRT-tilaa

Mallipuolella on omat yhteensopivuusrajansa. Detektori on DB-tekstidetektori; tunnistin hyväksyy CTC-mallit NCHW-asettelussa kiinteällä 32:n tai 48:n syöttökorkeudella ja käyttää arvoa 48 malleille, joilla on dynaaminen korkeus. Mukana toimitettu staattinen ONNX Runtime ei voi ladata uudemmalla IR-versiolla tallennettuja malleja, joten tuoreet PP-OCRv5-viennit epäonnistuvat alustuksessa diagnostiikalla osittaisen lataamisen sijaan. Sanakirjan on oltava UTF-8:aa ilman BOM:ia, täsmälleen mallin merkkijärjestyksessä, ja sen luokkamäärän on vastattava mallin tulostusta; CRLF-rivinvaihdot hyväksytään. Tunnistus on offline-toimintoa: DLL ei koskaan lataa puuttuvaa mallia

Pikamuistio

  • Tehdas: HPDFCreateRapidOCRDLLOCREngine(LibraryPath, ModelDirectory[, Options]) yksikössä HPDFRapidOCRRecognition, saatavilla versiosta v2.774.0 alkaen Delphi-, C++Builder- ja Windows FPC/Lazarus -koosteissa
  • Pidä palautettu IHPDFOCREngine elossa sivujen ja asiakirjojen yli; sen vapauttaminen tuhoaa mallit ja purkaa DLL:n latauksen
  • Yksi moottori ajaa yhden tunnistuksen kerrallaan; luo useita moottoreita rinnakkaisille työläisille ja budjetoi muisti kullekin mallikopiolle
  • Tuotos on yksi merkintä tekstiriviä kohden keskimääräisellä merkkiluottamusarvolla, suodatettuna arvolla THPDFOCRTextLayerOptions.MinimumConfidence
  • Peruuttaminen ja TimeoutMilliseconds ovat yhteistoiminnallisia; kesken oleva ONNX-ajo päättyy aina loppuun
  • Sovita DLL:n bittisyys sovellukseen sekä staattisten ONNX Runtime- ja OpenCV-kirjastojen CRT-tila DLL:ään
  • Valitse kieliprofiili moottoria kohden funktiolla THPDFRapidOCRDLLOptions.ForLanguage (v2.775.0); yksi moottori ei itse tunnista kieliä

Natiivi RapidOCR-sovitin, prosessipohjaiset OCR-sovittimet, niitä ruokkiva sivurenderöijä ja näkymätön Unicode-tekstitason kirjoittaja toimitetaan yhdessä HotPDF:ssä, natiivina VCL-PDF-komponenttina Delphille ja C++Builderille. Jos asiakirjojen kaappaus- tai arkistointisovelluksesi tarvitsee haettavaa tuotosta ilman Python-ajonympäristöä kohdekoneella, artikkeli HotPDF Delphi PDF component tarjoaa koko putken, jolloin käyttöönotettavaksi jää vain DLL ja sen mallit