IRONSOFTWAREHOME
FILMY

Migracja z AWS Textract do IronOCR

Kannaopat Udonpant
Kannapat Udonpant
Updated: 20 czerwca 2026

Ten przewodnik przedstawia kompletną migrację zAWS Textractdo IronOCR dla .NET dla programistów .NET, którzy potrzebują lokalnego przetwarzania dokumentów bez zależności od chmury. Obejmuje to usuwanie danych uwierzytelniających, usuwanie potoku asynchronicznego, eliminację S3 oraz konkretne zamiany kodu wymagane do przeniesienia każdej operacji Textract do jej odpowiednika w IronOCR.

Dlaczego warto przejść z AWS Textract

AWS Textract to wydajna usługa zarządzana, ale jej architektura wiąże się z kosztami — finansowymi i operacyjnymi — które rosną wraz ze wzrostem obciążenia dokumentami. Zespoły tworzące zaawansowane procesy przetwarzania dokumentów w końcu napotykają wszystkie te przeszkody.

Infrastruktura poświadczeń AWS komplikuje każde wdrożenie. Każde środowisko, w którym działa kod Textract, wymaga poświadczeń AWS: użytkownika lub roli IAM, klucza dostępu i sekretu, konfiguracji regionu, a w przypadku przetwarzania plików PDF dodatkowo uprawnień do zasobnika S3. Oznacza to pięć odrębnych kroków konfiguracyjnych przed przetworzeniem pierwszej strony. Produkcja wdrożeń wymaga zasad rotacji poświadczeń, bezpiecznego wstrzykiwania do kontenerów Docker lub podów Kubernetes oraz monitorowania dla AccessDeniedException, gdy IAM policy drift powoduje ciche awarie.IronOCR wymaga jednego ciągu znaków: klucza licencyjnego, ustawianego jednorazowo podczas uruchamiania.

Opłata za stronę nie ma ograniczeń. Podstawowa stawka $0,0015 za stronę dla DetectDocumentText to dolna granica, a nie koszt. Każdy dokument z tabelami uruchamia AnalyzeDocument za $0,015 za stronę — dziesięć razy więcej niż stawka podstawowa. Formularze zwiększają cenę o kolejne 0,05 USD za stronę. Mieszany przepływ dokumentów wynoszący 100 000 stron miesięcznie z ekstrakcją tabel kosztuje 18 000 USD rocznie, a kwota ta jest resetowana każdego stycznia. Licencja IronOCR Professional kosztuje jednorazowo 2999 USD. Następnie koszt za stronę wynosi zero, niezależnie od objętości.

Asynchroniczny potok PDF jest obciążeniem utrzymaniowym. Przetwarzanie dowolnego dokumentu PDF wielostronicowego przez Textract wymaga pięciu odrębnych faz: przesłania do S3, StartDocumentTextDetection, pętli ankietowej, pobierania wyników ze stronicowaniem oraz czyszczenia S3. Każda faza to niezależny tryb awarii wymagający własnej obsługi błędów, strategii ponownych prób i zarządzania czasem oczekiwania. Zespoły, które wdrażają ten proces do produkcji, konsekwentnie zgłaszają, że poświęcają więcej czasu na jego utrzymanie niż na jego stworzenie.IronOCR odczytuje plik PDF za pomocą dwóch wierszy kodu.

Brak dostępu do Internetu oznacza brak Textract. Kontenery Docker w izolowanych segmentach sieci, serwery lokalne, środowiska odizolowane oraz systemy przemysłowe z ograniczeniami ruchu wychodzącego mają jedną wspólną cechę: Textract jest niedostępny.IronOCR instaluje się jako pakiet NuGet i działa bez żadnych połączeń sieciowych po początkowym pobraniu pakietu.

Dane opuszczają Twoją infrastrukturę przy każdym wywołaniu. Każda operacja OCR w Textract przesyła zawartość dokumentu na serwery Amazon. Dla organizacji opieki zdrowotnej przetwarzających dane medyczne (PHI), wykonawców z sektóra obronnego zajmujących się informacjami o znaczeniu krytycznym (CUI), zespołów prawnych przetwarzających poufną korespondencję oraz instytucji finansowych przetwarzających obrazy kart płatniczych nie jest to opcja konfiguracyjna — jest to ograniczenie architektoniczne, które całkowicie uniemożliwia stosowanie Textract w środowiskach podlegających regulacjom.IronOCR działa na Twoim sprzęcie. Nie ma trybu chmury, który można by wyłączyć; Jedynym trybem jest przetwarzanie lokalne.

Limity stawki ograniczają przepustowość zgrupowań. Domyślny limit StartDocumentTextDetection TPS wynosi 5 żądań na sekundę. Prace wsadowe przetwarzające setki dokumentów wymagają SemaphoreSlim throttlingu, wykładniczego cofania się na ProvisionedThroughputExceededException oraz liczników odzyskiwania stawki. Wniosek o zwiększenie limitu TPS wymaga złożenia formalnego zgłoszenia do pomocy technicznej AWS, przy czym nie ma gwarancji pozytywnego rozpatrzenia.IronOCR przetwarza tak szybko, jak pozwala lokalna CPU — serwer z 16 rdzeniami przetwarza 16 dokumentów jednocześnie przy użyciu zwykłego Parallel.ForEach, bez konieczności negocjacji poziomów usług.

Podstawowy problem

Każde wdrożenie Textract rozpoczyna się od tej ceremonii — zanim będzie można przetworzyć choćby jedną stronę:

// Textract: five environment variables, an IAM role, and an S3 bucket
// — all required before the first OCR call

// Environment must have:
//   AWS_ACCESS_KEY_ID=AKIA...
//   AWS_SECRET_ACCESS_KEY=...
//   AWS_DEFAULT_REGION=us-east-1
//   IAM role: textract:DetectDocumentText, textract:AnalyzeDocument
//   IAM role: s3:PutObject, s3:DeleteObject (for any PDF processing)
//   S3 bucket: my-textract-staging-bucket (with lifecycle policy to prevent cost accumulation)

public class TextractOcrService
{
    private readonly AmazonTextractClient _textractClient;
    private readonly AmazonS3Client _s3Client; // required for PDFs

    public TextractOcrService()
    {
        // Fails with AmazonClientException if credentials not found in chain
        _textractClient = new AmazonTextractClient(Amazon.RegionEndpoint.USEast1);
        _s3Client = new AmazonS3Client(Amazon.RegionEndpoint.USEast1);
    }
}
C#

IronOCR zastępuje cały łańcuch poświadczeń pojedynczym przypisaniem:

// IronOCR: one line, one string, done
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";

// Or from environment (no IAM, no rotation, no S3)
IronOcr.License.LicenseKey = Environment.GetEnvironmentVariable("IRONOCR_LICENSE");
C#

##IronOCR a AWS Textract: porównanie funkcji

Poniższa tabela przedstawia możliwości obu bibliotek w aspektach najbardziej istotnych dla decyzji dotyczących migracji.

FunkcjaAWS TextractIronOCR
Miejsce przetwarzaniaAmazon Cloud (obowiązkowe)Tylko lokalnie / na miejscu
Wymagane połączenie z InternetemZawszeNigdy
Konfiguracja poświadczeńUżytkownik/rola IAM + opcjonalny zasób S3Pojedynczy ciąg klucza licencyjnego
Wielostronicowy plik PDFWymagane jest środowisko testowe S3 + zadanie asynchroniczneBezpośredni synchroniczny input.LoadPdf()
Plik PDF chroniony hasłemNieobsługiwaneinput.LoadPdf(path, Password: "x")
TIFF wieloklatkowyNieobsługiwaneinput.LoadImageFrames("multi.tiff")
Wymagane asynchroniczne odpytywanieTak (dla wszystkich plików PDF)Nie — domyślnie synchroniczne
Limity częstotliwości5 TPS domyślnie (StartDocumentTextDetection)Brak — tylko obciążenie procesora
Koszt za stronę0,0015–0,065 USD za stronę0 USD po zakupie licencji
Automatyczne przetwarzanie wstępneWewnętrzne, niekonfigurowalneWyrównanie, usuwanie szumów, kontrast, binarizacja, wyostrzanie, skalowanie
Wyjście w formacie PDF z możliwością wyszukiwaniaNiedostępneresult.SaveAsSearchablePdf()
Eksport hOCRNiedostępneresult.SaveAsHocrFile()
Odczytywanie BarCodeNiedostępneocr.Configuration.ReadBarCodes = true
OCR oparte na regionieZa pomocą AnalyzeDocument + relacje blokoweCropRectangle(x, y, width, height)
Wyniki uporządkowanePłaski List<Block> filtrowany przez BlockTypeTypowany Pages, Paragraphs, Lines, Words
Obsługiwane językiDominujący język angielski (wybierz dodatkowy)Ponad 125 pakietów językowych dostępnych za pośrednictwem NuGet
Wielojęzyczne tłumaczenie symultaniczneNieobsługiwaneOcrLanguage.French + OcrLanguage.German
Wdrożenie w środowisku izolowanymNiemożliweW pełni obsługiwane
HIPAA bez BAANiemożliweBrak zewnętrznego procesora — wyłącznie lokalnie
Wdrażanie DockerWymagane są wstrzyknięte poświadczenia AWSBrak poświadczeń — zwykły pakiet NuGet
WielopłatformoweZarządzane przez AWS (tylko Linux)Windows, Linux, macOS, Docker, Azure, AWS EC2
Model licencyjnyRozliczenie według liczby stron (wydatki bieżące)Wieczysta jednorazowa ($999 / $1 499 / $2 999)

Szybki start: Migracja zAWS Textractdo IronOCR

Krok 1: Zastąp pakiet NuGet

Usuń pakiety AWS SDK:

dotnet remove package AWSSDK.Textract
dotnet remove package AWSSDK.S3
dotnet remove package AWSSDK.Core
SHELL

Zainstaluj IronOCR z NuGet:

dotnet add package IronOcr

Krok 2: Aktualizacja przestrzeni nazw

Zastąp wszystkie importy przestrzeni nazw AWS pojedynczą przestrzenią nazw IronOCR:

// Before (AWS Textract)
using Amazon.Textract;
using Amazon.Textract.Model;
using Amazon.S3;
using Amazon.S3.Model;
using Amazon.Runtime;

// After (IronOCR)
using IronOcr;
C#

Krok 3: Inicjalizacja licencji

Dodaj inicjalizację licencji jednorazowo podczas uruchamiania aplikacji. Usuń wszystkie ustawienia zmiennych środowiskowych poświadczeń AWS:

// Remove from startup:
//   AWS_ACCESS_KEY_ID environment variable
//   AWS_SECRET_ACCESS_KEY environment variable
//   AWS_DEFAULT_REGION environment variable
//   ~/.aws/credentials file entries
//   IAM role bindings on the execution context

// Add instead:
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
C#

Przykłady migracji kodu

Zastąpienie konstruktóra AmazonTextractClient i konfiguracji IAM

Najbardziej widoczną zmianą związaną z migracją jest inicjalizacja klienta. Textract wymaga klienta z wstrzykiwaniem zależności i podstawową obsługą uwierzytelniania — oznacza to, że zarówno klient, jak i wszystkie jego zależności muszą być wstępnie skonfigurowane w każdym środowisku wdrożeniowym. Każda błędna konfiguracja zawiedzie cicho, dopóki pierwsze wywołanie OCR nie wyrzuci AmazonClientException.

Podejście AWS Textract:

// Requires: NuGet AWSSDK.Textract, AWSSDK.S3
// Requires: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_DEFAULT_REGION in environment
// Requires: IAM policy with textract:* and s3:PutObject, s3:DeleteObject

using Amazon.S3;
using Amazon.Textract;

public class DocumentOcrService
{
    private readonly AmazonTextractClient _textractClient;
    private readonly AmazonS3Client _s3Client;
    private readonly string _stagingBucket;

    public DocumentOcrService(IConfiguration config)
    {
        // Credential chain: environment → ~/.aws/credentials → EC2 instance profile
        // Fails if none found — runtime exception, not compile-time
        _textractClient = new AmazonTextractClient(Amazon.RegionEndpoint.USEast1);
        _s3Client = new AmazonS3Client(Amazon.RegionEndpoint.USEast1);
        _stagingBucket = config["Textract:StagingBucket"]; // bucket must exist and have permissions
    }

    public async Task<string> ReadImageAsync(string imagePath)
    {
        var bytes = File.ReadAllBytes(imagePath);
        var response = await _textractClient.DetectDocumentTextAsync(
            new DetectDocumentTextRequest
            {
                Document = new Document { Bytes = new MemoryStream(bytes) }
            });

        return string.Join("\n", response.Blocks
            .Where(b => b.BlockType == BlockType.LINE)
            .Select(b => b.Text));
    }
}
C#

Podejście IronOCR:

// Requires: NuGet IronOcr
// Requires: one license key string — nothing else

using IronOcr;

public class DocumentOcrService
{
    private readonly IronTesseract _ocr;

    public DocumentOcrService()
    {
        IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"; // or set at Program.cs startup
        _ocr = new IronTesseract();
    }

    public string ReadImage(string imagePath)
    {
        // No credential chain, no region, no bucket — just read
        return _ocr.Read(imagePath).Text;
    }
}
C#

Cała infrastruktura poświadczeń AWS — role IAM, zmienne środowiskowe, pliki ~/.aws/credentials, polityki okresu życia bucketów S3 oraz konfiguracja regionu — jest usuwana. Konstruktor DocumentOcrService przechodzi z 3-miejscowej wstrzykiwanego miejsca zależności z trybami awarii w czasie wykonywania do pojedynczego przypisania licencji. Szczegółowe informacje na temat wzorców wdrażania można znaleźć w przewodniku konfiguracji IronTesseract.

Zastąpienie funkcji StartDocumentTextDetection przetwarzaniem wieloklatkowym TIFF

Asynchroniczne API zadań Textract (StartDocumentTextDetection) jest wymagane dla dowolnego dokumentu wielostronicowego. Typowym schematem w procesach digitalizacji dokumentów jest otrzymywanie zeskanowanych dokumentów w postaci wielo-ramkowych plików TIFF — jedna ramka na każdą zeskanowaną stronę. Textract w ogóle nie akceptuje plików TIFF jako danych wejściowych; Przed rozpoczęciem zadania dokument musi zostać przekonwertowany do formatu PDF i przesłany do S3.IronOCR natywnie odczytuje pliki TIFF zawierające wiele klatek.

Podejście AWS Textract:

// Textract cannot accept TIFF directly — requires PDF conversion + S3 + async job
// This shows the conversion overhead plus the minimum async pipeline

using Amazon.S3;
using Amazon.S3.Model;
using Amazon.Textract;
using Amazon.Textract.Model;

public async Task<string> ProcessScannedTiffAsync(string tiffPath, string s3Bucket)
{
    // Step 0: Convert TIFF to PDF first (Textract does not accept TIFF for async jobs)
    // Requires a separate PDF conversion library — not shown here
    var pdfPath = Path.ChangeExtension(tiffPath, ".pdf");
    ConvertTiffToPdf(tiffPath, pdfPath); // external dependency required

    // Step 1: Upload converted PDF to S3
    var s3Key = $"staging/{Guid.NewGuid()}.pdf";
    using (var stream = File.OpenRead(pdfPath))
    {
        await _s3Client.PutObjectAsync(new PutObjectRequest
        {
            BucketName = s3Bucket,
            Key = s3Key,
            InputStream = stream
        });
    }

    try
    {
        // Step 2: Start async detection job
        var startResp = await _textractClient.StartDocumentTextDetectionAsync(
            new StartDocumentTextDetectionRequest
            {
                DocumentLocation = new DocumentLocation
                {
                    S3Object = new S3Object { Bucket = s3Bucket, Name = s3Key }
                }
            });

        // Step 3: Poll every 5 seconds — can block for 30–120 seconds on large files
        GetDocumentTextDetectionResponse pollResp;
        do
        {
            await Task.Delay(5000);
            pollResp = await _textractClient.GetDocumentTextDetectionAsync(
                new GetDocumentTextDetectionRequest { JobId = startResp.JobId });
        } while (pollResp.JobStatus == JobStatus.IN_PROGRESS);

        if (pollResp.JobStatus != JobStatus.SUCCEEDED)
            throw new Exception($"Job failed: {pollResp.StatusMessage}");

        // Step 4: Collect paginated results
        var text = new StringBuilder();
        string token = null;
        do
        {
            var page = await _textractClient.GetDocumentTextDetectionAsync(
                new GetDocumentTextDetectionRequest
                {
                    JobId = startResp.JobId,
                    NextToken = token
                });
            foreach (var block in page.Blocks.Where(b => b.BlockType == BlockType.LINE))
                text.AppendLine(block.Text);
            token = page.NextToken;
        } while (token != null);

        return text.ToString();
    }
    finally
    {
        // Step 5: Clean up S3 — orphaned objects accumulate storage costs
        await _s3Client.DeleteObjectAsync(s3Bucket, s3Key);
        File.Delete(pdfPath); // clean up intermediate PDF
    }
}
C#

Podejście IronOCR:

//IronOCR reads multi-frame TIFF directly — no conversion, no S3, no polling

using IronOcr;

public string ProcessScannedTiff(string tiffPath)
{
    using var input = new OcrInput();
    input.LoadImageFrames(tiffPath); // reads all frames natively

    var ocr = new IronTesseract();
    var result = ocr.Read(input);

    // Access per-page results if needed
    foreach (var page in result.Pages)
        Console.WriteLine($"Page {page.PageNumber}: {page.Words.Length} words detected");

    return result.Text;
}
C#

Eliminuje się etap konwersji plików TIFF do formatu PDF, przesyłanie do S3, asynchroniczną pętlę odpytywania, gromadzenie wyników w postaci stron oraz czyszczenie S3. Implementacja IronOCR odczytuje ramki bezpośrednio i zapewnia dostęp do każdej strony przez result.Pages bez żadnej pośredniej konwersji formatu. Przewodnik dotyczący plików wejściowych TIFF i GIF obejmuje wybór klatek w przypadkach, gdy potrzebny jest tylko podzbiór klatek.

Zastąpienie S3 Staging przez pliki PDF z funkcją wyszukiwania

Typowym zastosowaniem Textract jest konwersja zeskanowanych archiwów PDF do formatu umożliwiającego wyszukiwanie. Podejście Textract wymaga przesłania każdego pliku PDF do S3, uruchomienia zadania asynchronicznego, zebrania wyodrębnionego tekstu, a następnie użycia oddzielnej biblioteki PDF do osadzenia tego tekstu jako warstwy z możliwością wyszukiwania.IronOCR skanuje i tworzy plik PDF z możliwością wyszukiwania w ramach jednego wywołania.

Podejście AWS Textract:

// Textract extracts text but cannot produce searchable PDFs
// Requires: S3 upload + async job + separate PDF library to embed the text layer

using Amazon.S3;
using Amazon.S3.Model;
using Amazon.Textract;
using Amazon.Textract.Model;

public async Task<string> ExtractTextForSearchableLayerAsync(
    string scannedPdfPath,
    string s3Bucket)
{
    // Must upload to S3 — cannot pass PDF bytes directly for async jobs
    var key = $"ocr-input/{Guid.NewGuid()}.pdf";

    await using (var fs = File.OpenRead(scannedPdfPath))
    {
        await _s3Client.PutObjectAsync(new PutObjectRequest
        {
            BucketName = s3Bucket,
            Key = key,
            InputStream = fs,
            ContentType = "application/pdf"
        });
    }

    string jobId;
    try
    {
        var startResp = await _textractClient.StartDocumentTextDetectionAsync(
            new StartDocumentTextDetectionRequest
            {
                DocumentLocation = new DocumentLocation
                {
                    S3Object = new S3Object { Bucket = s3Bucket, Name = key }
                }
            });
        jobId = startResp.JobId;
    }
    catch
    {
        await _s3Client.DeleteObjectAsync(s3Bucket, key);
        throw;
    }

    // Poll — minimum 5s wait; typical 15–60s for a 10-page PDF
    GetDocumentTextDetectionResponse pollResp;
    int pollAttempts = 0;
    const int maxAttempts = 120; // 10 minute timeout

    do
    {
        await Task.Delay(5000);
        pollResp = await _textractClient.GetDocumentTextDetectionAsync(
            new GetDocumentTextDetectionRequest { JobId = jobId });

        if (++pollAttempts >= maxAttempts)
            throw new TimeoutException("Textract job timed out after 10 minutes");

    } while (pollResp.JobStatus == JobStatus.IN_PROGRESS);

    await _s3Client.DeleteObjectAsync(s3Bucket, key); // cleanup regardless of outcome

    if (pollResp.JobStatus != JobStatus.SUCCEEDED)
        throw new Exception($"Textract job status: {pollResp.JobStatus}{pollResp.StatusMessage}");

    // Return extracted text — caller must use a separate library to produce searchable PDF
    return string.Join("\n", pollResp.Blocks
        .Where(b => b.BlockType == BlockType.LINE)
        .Select(b => b.Text));

    // Caller still needs: iTextSharp, PdfSharp, or similar to embed text layer
}
C#

Podejście IronOCR:

//IronOCR reads the PDF and produces a searchable PDF output directly
// No S3, no polling, no external PDF library needed

using IronOcr;

public void ConvertToSearchablePdf(string scannedPdfPath, string outputPath)
{
    var ocr = new IronTesseract();

    using var input = new OcrInput();
    input.LoadPdf(scannedPdfPath);

    var result = ocr.Read(input);

    // Embed extracted text as searchable layer in one call
    result.SaveAsSearchablePdf(outputPath);

    Console.WriteLine($"Pages processed: {result.Pages.Length}");
    Console.WriteLine($"Overall confidence: {result.Confidence:F1}%");
}
C#

Logika limitu czasu odpytywania, wzorzec przesyłania i czyszczenia S3 oraz zależność od zewnętrznej biblioteki PDF zostały usunięte. SaveAsSearchablePdf bezpośrednio osadza rozpoznany tekst w pliku wyjściowym, dzięki czemu każda zeskanowana strona jest pełnotekstowo przeszukiwana bez potrzeby drugiej biblioteki. Przewodnik w formacie PDF z funkcją wyszukiwania obejmuje wybór stron, opcje kompresji oraz osadzanie metadanych. Szerszy kontekst procesów OCR plików PDF można znaleźć w przewodniku dotyczącym plików PDF.

Zastąpienie analizy dokumentu poprzez przeglądanie grafu bloków wynikami stron ustrukturyzowanych

Textract's AnalyzeDocument z TABLES i FORMS zwraca płaski List<Block>, gdzie każdy element — linie, słowa, komórki, nagłówki tabel, klucze formularzy, wartości formularzy — jest tego samego Block typu rozróżnianego tylko przez BlockType i połączonego przez tablice ID RelationshipType.CHILD. Odtworzenie struktury logicznej dokumentu wymaga przejścia przez ten graf relacji.IronOCR zwraca hierarchię tekstową: strony, akapity, wiersze, słowa, z których każdy ma dostęp do współrzędnych.

Podejście AWS Textract:

// AnalyzeDocument with TABLES returns blocks that must be graph-traversed
// to determine which words belong to which paragraphs

using Amazon.Textract;
using Amazon.Textract.Model;

public async Task<List<DocumentSection>> ExtractDocumentStructureAsync(string imagePath)
{
    var bytes = File.ReadAllBytes(imagePath);

    var response = await _textractClient.AnalyzeDocumentAsync(
        new AnalyzeDocumentRequest
        {
            Document = new Document { Bytes = new MemoryStream(bytes) },
            FeatureTypes = new List<string> { "TABLES", "FORMS" }
            // Note: AnalyzeDocument (TABLES) costs $0.015/page — 10x DetectDocumentText
        });

    var sections = new List<DocumentSection>();

    // Filter LINE blocks for paragraph reconstruction
    // LINE blocks are not grouped into paragraphs — must infer from Y proximity
    var lineBlocks = response.Blocks
        .Where(b => b.BlockType == BlockType.LINE)
        .OrderBy(b => b.Geometry?.BoundingBox?.Top ?? 0)
        .ToList();

    // Group lines into pseudo-paragraphs by vertical gap heuristic
    var currentParagraph = new List<Block>();
    float? lastBottom = null;
    const float paragraphGapThreshold = 0.02f; // 2% of page height

    foreach (var line in lineBlocks)
    {
        var top = line.Geometry?.BoundingBox?.Top ?? 0;
        var height = line.Geometry?.BoundingBox?.Height ?? 0;

        if (lastBottom.HasValue && (top - lastBottom.Value) > paragraphGapThreshold)
        {
            if (currentParagraph.Any())
            {
                sections.Add(new DocumentSection
                {
                    Text = string.Join(" ", currentParagraph.Select(b => b.Text)),
                    LineCount = currentParagraph.Count,
                    // Confidence: average of all LINE block confidence values
                    Confidence = (float)currentParagraph.Average(b => b.Confidence ?? 0)
                });
                currentParagraph.Clear();
            }
        }

        currentParagraph.Add(line);
        lastBottom = top + height;
    }

    if (currentParagraph.Any())
        sections.Add(new DocumentSection
        {
            Text = string.Join(" ", currentParagraph.Select(b => b.Text)),
            LineCount = currentParagraph.Count,
            Confidence = (float)currentParagraph.Average(b => b.Confidence ?? 0)
        });

    return sections;
}

public class DocumentSection
{
    public string Text { get; set; }
    public int LineCount { get; set; }
    public float Confidence { get; set; }
}
C#

Podejście IronOCR:

//IronOCR returns a typed hierarchy — paragraphs are first-class objects
// No block graph, no heuristic gap detection, no confidence averaging

using IronOcr;

public List<DocumentSection> ExtractDocumentStructure(string imagePath)
{
    var ocr = new IronTesseract();
    var result = ocr.Read(imagePath);

    var sections = new List<DocumentSection>();

    foreach (var page in result.Pages)
    {
        foreach (var paragraph in page.Paragraphs)
        {
            sections.Add(new DocumentSection
            {
                Text = paragraph.Text,
                LineCount = paragraph.Lines.Length,
                // Coordinate access: exact pixel position on the page
                LocationX = paragraph.X,
                LocationY = paragraph.Y,
                Width = paragraph.Width,
                Height = paragraph.Height,
                Confidence = paragraph.Confidence
            });
        }
    }

    return sections;
}

public class DocumentSection
{
    public string Text { get; set; }
    public int LineCount { get; set; }
    public int LocationX { get; set; }
    public int LocationY { get; set; }
    public int Width { get; set; }
    public int Height { get; set; }
    public double Confidence { get; set; }
}
C#

Akapity, linie i słowa są bezpośrednio dostępne jako typowane kolekcje z .X, .Y, .Width, .Height, i .Confidence właściwościami. Bez normalizacji BoundingBox, bez heurystyki progu odstępów, bez filtrowania typów bloków. Przewodnik po wynikach odczytu dokumentuje pełną hierarchię OcrResult, w tym dostęp do współrzędnych na poziomie znaku. W przypadku procesów związanych z fakturami i paragonami, które opierają się na tej strukturze, zapoznaj się z samouczkiem dotyczącym OCR faktur.

Zastąpienie przetwarzania wsadowego z ograniczeniami szybkości nieograniczonym wykonywaniem równoległym

Przetwarzanie wsadowe obrazów to miejsce, gdzie limity TPS Textract generują najbardziej widoczne koszty operacyjne. Synchronous API DetectDocumentText jest ograniczone przez stawkę; wysyłanie więcej niż 5 żądań na sekundę generuje ProvisionedThroughputExceededException. Poprawna obsługa wsadów wymaga SemaphoreSlim throttlingu, logiki powtórzeń z cofnięciem oraz starannego księgowania dla będących w toku żądań.IronOCR nie ma ograniczeń szybkości — przepustowość jest ograniczona jedynie dostępnymi rdzeniami procesora.

Podejście AWS Textract:

// Batch processing requires SemaphoreSlim throttle + retry on rate limit exceeded

using Amazon.Textract;
using Amazon.Textract.Model;
using System.Collections.Concurrent;

public async Task<Dictionary<string, string>> ProcessImageBatchAsync(
    IReadOnlyList<string> imagePaths,
    IProgress<(int Completed, int Total)> progress = null)
{
    var results = new ConcurrentDictionary<string, string>();
    var semaphore = new SemaphoreSlim(5); // 5 concurrent — Textract default TPS limit
    var tasks = new List<Task>();
    int completed = 0;

    foreach (var path in imagePaths)
    {
        await semaphore.WaitAsync();

        tasks.Add(Task.Run(async () =>
        {
            try
            {
                string text = null;
                int retryCount = 0;

                while (text == null && retryCount < 3)
                {
                    try
                    {
                        var bytes = await File.ReadAllBytesAsync(path);
                        var response = await _textractClient.DetectDocumentTextAsync(
                            new DetectDocumentTextRequest
                            {
                                Document = new Document { Bytes = new MemoryStream(bytes) }
                            });

                        text = string.Join("\n", response.Blocks
                            .Where(b => b.BlockType == BlockType.LINE)
                            .Select(b => b.Text));
                    }
                    catch (AmazonTextractException ex)
                        when (ex.ErrorCode == "ProvisionedThroughputExceededException")
                    {
                        // Exponential backoff on rate limit — blocks the entire thread
                        await Task.Delay(TimeSpan.FromSeconds(Math.Pow(2, retryCount)));
                        retryCount++;
                    }
                }

                results[path] = text ?? string.Empty;
                var done = Interlocked.Increment(ref completed);
                progress?.Report((done, imagePaths.Count));
            }
            finally
            {
                semaphore.Release();
            }
        }));
    }

    await Task.WhenAll(tasks);
    return results.ToDictionary(x => x.Key, x => x.Value);
}
C#

Podejście IronOCR:

// No rate limits, no semaphore, no retry logic — Parallel.ForEach saturates all cores

using IronOcr;
using System.Collections.Concurrent;

public Dictionary<string, string> ProcessImageBatch(
    IReadOnlyList<string> imagePaths,
    IProgress<(int Completed, int Total)> progress = null)
{
    var ocr = new IronTesseract();
    var results = new ConcurrentDictionary<string, string>();
    int completed = 0;

    Parallel.ForEach(imagePaths, path =>
    {
        var result = ocr.Read(path);
        results[path] = result.Text;

        var done = Interlocked.Increment(ref completed);
        progress?.Report((done, imagePaths.Count));
    });

    return results.ToDictionary(x => x.Key, x => x.Value);
}
C#

The SemaphoreSlim, pętla powtórzeń, wykładnicze cofnięcie i bloki przechwytywania ProvisionedThroughputExceededException są usunięte. IronTesseract jest bezpieczny w kontekście wątków, a pojedyncza instancja udostępniona między wątkami obsługuje pełne obciążenie równoległe bez blokad. Na komputerze z 8 rdzeniami przetwarza to 8 dokumentów jednocześnie bez żadnej konfiguracji; na 32 rdzeniach, 32 jednocześnie. Przykład wielowątkowości pokazuje kompletny wzorzec, a przewodnik po optymalizacji szybkości obejmuje dostosowanie konfiguracji silnika dla wdrożeń zorientowanych na przepustowość.

Zastąpienie funkcji AnalyzeDocument Form Extraction funkcją Region-Based CropRectangle OCR

Textract's AnalyzeDocument z FORMS zwraca bloki KEY_VALUE_SET, połączone relacjami RelationshipType.VALUE. Odtwarzanie par klucz-wartość pól formularzy wymaga filtrowania przez EntityTypes.Contains("KEY"), podążania według identyfikatorów relacji VALUE, a następnie pobierania bloków potomnych WORD w celu złożenia tekstu. W przypadku formularzy o stałym formacie, gdzie pozycje pól są znane, CropRectangleIronOCR wyodrębnia każdy element bezpośrednio, bez konieczności przeglądania grafów relacji — i kosztuje zero za stronę.

Podejście AWS Textract:

// FORMS mode costs $0.05/page — the most expensive Textract tier
// Relationship graph traversal required to reconstruct key-value pairs

using Amazon.Textract;
using Amazon.Textract.Model;

public async Task<Dictionary<string, string>> ExtractInvoiceFieldsAsync(string imagePath)
{
    var bytes = File.ReadAllBytes(imagePath);

    // $0.05/page for FORMS analysis
    var response = await _textractClient.AnalyzeDocumentAsync(
        new AnalyzeDocumentRequest
        {
            Document = new Document { Bytes = new MemoryStream(bytes) },
            FeatureTypes = new List<string> { "FORMS" }
        });

    var allBlocks = response.Blocks;
    var fields = new Dictionary<string, string>();

    // Find KEY blocks only
    var keyBlocks = allBlocks.Where(b =>
        b.BlockType == BlockType.KEY_VALUE_SET &&
        b.EntityTypes?.Contains("KEY") == true);

    foreach (var keyBlock in keyBlocks)
    {
        // Assemble key text from CHILD WORD blocks
        var keyText = GetTextFromBlock(allBlocks, keyBlock);

        // Find associated VALUE block via VALUE relationship
        var valueBlockId = keyBlock.Relationships?
            .FirstOrDefault(r => r.Type == RelationshipType.VALUE)?
            .Ids.FirstOrDefault();

        if (valueBlockId == null) continue;

        var valueBlock = allBlocks.FirstOrDefault(b => b.Id == valueBlockId);
        if (valueBlock == null) continue;

        var valueText = GetTextFromBlock(allBlocks, valueBlock);
        fields[keyText.TrimEnd(':')] = valueText;
    }

    return fields;
}

private string GetTextFromBlock(IList<Block> allBlocks, Block block)
{
    if (block.Relationships == null) return string.Empty;

    var childWordIds = block.Relationships
        .Where(r => r.Type == RelationshipType.CHILD)
        .SelectMany(r => r.Ids);

    return string.Join(" ", allBlocks
        .Where(b => b.BlockType == BlockType.WORD && childWordIds.Contains(b.Id))
        .Select(b => b.Text));
}
C#

Podejście IronOCR:

// CropRectangle extracts each field zone directly — no relationship graph
// Works for any fixed-format form where field positions are known

using IronOcr;

// Define the field zones for your form template once
private static readonly Dictionary<string, CropRectangle> InvoiceFieldZones =
    new Dictionary<string, CropRectangle>
    {
        { "InvoiceNumber", new CropRectangle(450, 80,  300, 35) },
        { "InvoiceDate",   new CropRectangle(450, 120, 300, 35) },
        { "VendorName",    new CropRectangle(50,  160, 400, 35) },
        { "TotalAmount",   new CropRectangle(450, 680, 200, 35) },
        { "DueDate",       new CropRectangle(450, 720, 200, 35) }
    };

public Dictionary<string, string> ExtractInvoiceFields(string imagePath)
{
    var ocr = new IronTesseract();
    var fields = new Dictionary<string, string>();

    foreach (var zone in InvoiceFieldZones)
    {
        using var input = new OcrInput();
        input.LoadImage(imagePath, zone.Value); // load only the defined region

        var result = ocr.Read(input);
        fields[zone.Key] = result.Text.Trim();
    }

    return fields;
}
C#

Filtrowanie bloków KEY_VALUE_SET, przechodzenie z RelationshipType.VALUE oraz GetTextFromBlock pomocnicze są eliminowane. Każde pole odczytuje dokładnie ten obszar pikseli, który je zawiera — ani więcej, ani mniej. Przewodnik po OCR bazującym na regionie obejmuje współrzędne CropRectangle oraz jak definiować strefy z wymiarów szablonów. W przypadku procesów związanych z fakturami, wpis na blogu o OCR faktur oraz samouczek skanowania paragonów pokazują pełne procesy ekstrakcji danych z pól.

Dokumentacja APIAWS Textractdo IronOCR

AWS TextractOdpowiednik IronOCR
AmazonTextractClientIronTesseract
AmazonS3ClientNie jest wymagane
DetectDocumentTextRequestOcrInput z input.LoadImage()
DetectDocumentTextResponseOcrResult
AnalyzeDocumentRequest (TABLES/FORMS)OcrInput z opcjonalnym CropRectangle
StartDocumentTextDetectionRequestOcrInput z input.LoadPdf() — synchroniczne, bez uruchamiania zadań
GetDocumentTextDetectionRequestNie dotyczy — wyniki są natychmiastowe
Document.Bytesinput.LoadImage(byteArray) lub input.LoadImage(stream)
S3Object (staging dokumentów)Ścieżka pliku lub strumień — nie jest wymagane przygotowanie
Block (BlockType.LINE)result.Lines (typowana kolekcja)
Block (BlockType.WORD)result.Words (typowana kolekcja)
Block (BlockType.TABLE)result.Words pogrupowane według bliskości współrzędnych
Block (BlockType.KEY_VALUE_SET)CropRectangle wyodrębnianie regionu na pole
Block.Confidenceword.Confidence / result.Confidence
Block.Geometry.BoundingBoxword.X, word.Y, word.Width, word.Height
RelationshipType.CHILD przeglądBezpośredni dostęp do właściwości w obiektach wynikowych typu
JobStatus.IN_PROGRESSNie dotyczy — brak stanu asynchronicznego
JobStatus.SUCCEEDEDNie dotyczy — zwrot synchroniczny
response.NextToken (stronicowanie)Nie dotyczy — wyniki nie są podzielone na strony
ProvisionedThroughputExceededExceptionNie dotyczy — brak limitów TPS
AccessDeniedExceptionNie dotyczy — brak łańcucha poświadczeń
input.LoadImageFrames()Bezpośrednia obsługa plików TIFF z wieloma ramkami (bez odpowiednika Textract)
result.SaveAsSearchablePdf()Wynik w formacie PDF z możliwością wyszukiwania (bez odpowiednika Textract)

Typowe problemy związane z migracją i ich rozwiązania

Problem 1: Nieprawidłowa konfiguracja poświadczeń w nowych środowiskach wdrożeniowych

AWS Textract: Konstruktor AmazonTextractClient rozwiązuje poświadczenia z łańcucha: zmienne środowiskowe, ~/.aws/credentials, profil instancji EC2, rola zadania ECS. W nowym kontenerze Docker lub środowisku CI, jeśli żadne z tych elementów nie są skonfigurowane, klient skonstruuje się bez błędu, ale każde wywołanie API wyrzuci AmazonClientException: No credentials specified. Błąd jest niewidoczny aż do momentu uruchomienia.

Rozwiązanie: Całkowicie usuń łańcuch poświadczeń. Ustaw klucz licencyjny IronOCR w zmiennej środowiskowej, która jest łatwiejsza w konfiguracji i nie wymaga zarządzania uprawnieniami IAM:

// Single environment variable — no IAM, no rotation, no chain resolution
var key = Environment.GetEnvironmentVariable("IRONOCR_LICENSE");
if (string.IsNullOrEmpty(key))
    throw new InvalidOperationException("IRONOCR_LICENSE environment variable is not set");

IronOcr.License.LicenseKey = key;
C#

Problem 2: Miejsca wywołań asynchronicznych w całym kodzie źródłowym

AWS Textract: Ponieważ całe SDK jest wyłącznie asynchroniczne (DetectDocumentTextAsync, StartDocumentTextDetectionAsync, GetDocumentTextDetectionAsync), wszystkie miejsca wywołania Textract propagują async Task<t> przez stos wywołań. Przejście na synchroniczne API IronOCR wymaga podjęcia decyzji w każdej lokalizacji.

Rozwiązanie: W przypadku usług przetwarzania w tle i akcji kontrolera synchroniczne wywołania IronOCRsą bezpieczne w wątkach działających w tle. Opakuj w Task.Run tylko wtedy, gdy istniejący łańcuch wywołań musi pozostać asynchroniczny:

// If the call site must remain async (e.g., an ASP.NET controller action):
public async Task<IActionResult> ProcessUpload(IFormFile file)
{
    using var ms = new MemoryStream();
    await file.CopyToAsync(ms);

    // Offload synchronous OCR to thread pool — keeps controller non-blocking
    var text = await Task.Run(() =>
    {
        var ocr = new IronTesseract();
        using var input = new OcrInput();
        input.LoadImage(ms.ToArray());
        return ocr.Read(input).Text;
    });

    return Ok(text);
}
C#

Dla przetworników wsadowych i usług działających w tle, które już uruchomione są na wątkach nie-UI, bezpośrednio wywołaj ocr.Read() synchronicznie — Task.Run dodaje obciążenie bez korzyści w tych kontekstach. Przewodnik po asynchronicznym OCR zawiera zalecane wzorce.

Problem 3: Logika czyszczenia zasobników S3 rozproszona w kodzie

AWS Textract: Każdy kod przesyłany do S3 w celu przetworzenia przez Textract musi zostać usunięty z S3 po zakończeniu zadania. To czyszczenie często żyje w blokach finally i czasami jest pomijane na ścieżkach błędów, powodując osierocone obiekty, które gromadzą koszty przechowywania. Podczas migracji łatwo przeoczyć kod czyszczący S3, ponieważ nie jest on koncepcyjnie powiązany z OCR.

Rozwiązanie: Cały wzorzec przesyłania i czyszczenia w S3 nie ma odpowiednika w IronOCR. Usuń całkowicie wszystkie bloki PutObjectAsync, DeleteObjectAsync, i S3 związane z blokami try/finally.IronOCR odczytuje dane bezpośrednio z lokalnych ścieżek lub strumieni:

// Before: upload → job → poll → extract → cleanup (50+ lines)
// After: two lines, no cleanup required

using var input = new OcrInput();
input.LoadPdf(localPdfPath);
var text = new IronTesseract().Read(input).Text;
C#

Po migracji należy wyłączyć zasób S3 staging bucket. Przewodnik po danych wejściowych w formacie PDF oraz przewodnik po danych wejściowych strumieniowych obejmują wszystkie wzorce danych wejściowych, które zastępują dostęp do dokumentów w fazie S3.

Problem 4: Kod przechodzenia przez wykres blokowy nie ma bezpośredniego odpowiednika

AWS Textract: Kod przechodzący przez Block.Relationships aby odtworzyć komórki tabel, pola formularzy lub grupowania akapitów z tablic ID RelationshipType.CHILD jest najbardziej czasochłonnym kodem do zmigrowania. Nie ma jednoznacznego zamiennika, ponieważIronOCR zwraca kolekcje typów zamiast grafu relacji.

Rozwiązanie: Zastąp każdy wzorzec traversal odpowiednią właściwością typu. Wyszukiwanie identyfikatorów relacji staje się bezpośrednim dostępem do właściwości:

// Before: filter by BlockType + traverse relationship IDs
var paragraphText = string.Join(" ", allBlocks
    .Where(b => b.BlockType == BlockType.WORD &&
                childIds.Contains(b.Id))
    .Select(b => b.Text));

// After: direct paragraph text (no filtering, no relationship lookup)
foreach (var page in result.Pages)
    foreach (var para in page.Paragraphs)
        Console.WriteLine(para.Text); // already assembled
C#

Do rekonstrukcji tabel, które polegały na BlockType.CELL oraz właściwościach ColumnIndex, należy użyć grupowania według współrzędnych słów na result.Words. Przewodnik po czytaniu tabeli obejmuje podejście oparte na współrzędnych.

Problem 5: Bloki przechwytujące wyjątek ProvisionedThroughputExceededException

AWS Textract: Solidny kod przetwarzania wsadowego przechwytuje AmazonTextractException z ErrorCode == "ProvisionedThroughputExceededException" i implementuje ponowne próby z cofnięciem. Ten kod błędu jest pojęciem specyficznym dla Textract i nie ma jego odpowiednika w IronOCR.

Rozwiązanie: Usuń wszystkie bloki przechwytywania ProvisionedThroughputExceededException.IronOCR nie ma ograniczeń dotyczących TPS. Zastąp cały wzorzec ograniczonej partii z Parallel.ForEach:

// Delete: SemaphoreSlim, retry loops, ProvisionedThroughputExceededException handlers
// Replace with:
Parallel.ForEach(imagePaths, path =>
{
    var result = new IronTesseract().Read(path);
    results[path] = result.Text;
});
C#

Problem 6: Konfiguracja regionu wbudowana w konstruktory klienta

AWS Textract: new AmazonTextractClient(Amazon.RegionEndpoint.USEast1) hardcodes a region. Wdrożenia wieloregionalne wymagają wielu instancji klienta lub dynamicznego wyboru regionu. Gdy Textract rozszerzy obsługę o nowe regiony, kod musi zostać zaktualizowany.

**Rozwiązanie:**IronOCR nie ma pojęcia regionu. Usuń wszystkie referencje Amazon.RegionEndpoint. Konstruktor IronTesseract nie przyjmuje żadnej konfiguracji sieciowej — przetwarzanie jest lokalne. W przypadku wdrożeń wieloregionalnych w infrastrukturze AWS, gdzie każdy region obsługuje własne zasoby obliczeniowe, każda instancja IronOCR przetwarza dokumenty lokalnie w obrębie tych zasobów, bez wywołań międzyregionowych.

Lista kontrolna migracji AWS Textract

Przed migracją

Sprawdź wszystkie użycia Textract i S3 SDK w kodzie źródłowym:

grep -rn "Amazon.Textract\|AmazonTextractClient\|DetectDocumentText" --include="*.cs" .
grep -rn "StartDocumentTextDetection\|GetDocumentTextDetection\|JobStatus" --include="*.cs" .
grep -rn "AmazonS3Client\|PutObjectRequest\|DeleteObjectAsync" --include="*.cs" .
grep -rn "BlockType\|RelationshipType\|KEY_VALUE_SET" --include="*.cs" .
grep -rn "ProvisionedThroughputExceededException\|AmazonTextractException" --include="*.cs" .
grep -rn "AWSSDK\|Amazon.RegionEndpoint" --include="*.csproj" .
SHELL

Przed napisaniem jakiegokolwiek kodu zastępczego należy:

  • Policz wszystkie pliki zawierające AmazonTextractClient — każde to cel zastąpienia
  • Lista wszystkich miejsc wywołań AnalyzeDocument — zanotuj, czy używane są TABLES, FORMS, czy oba
  • Zidentyfikuj wszystkie asynchroniczne pętle ankietowe (do { await Task.Delay } while JobStatus == IN_PROGRESS)
  • Znajdź wszystkie bloki czyszczenia S3 finally — te są usuwane hurtowo, a nie zastępowane
  • Policz wszystkie bloki przechwytywania ProvisionedThroughputExceededException — usunięte, nie zastępowane
  • Zanotuj całą logikę przeglądania BlockType.TABLE, BlockType.CELL, BlockType.KEY_VALUE_SET — każdy potrzebuje strukturalnego zastąpienia danych wyjściowych

Migracja kodu

  1. Usuń AWSSDK.Textract, AWSSDK.S3, i AWSSDK.Core ze wszystkich plików .csproj
  2. Uruchom dotnet add package IronOcr w każdym projekcie, który wykonuje OCR
  3. Dodaj IronOcr.License.LicenseKey = ... raz przy uruchomieniu aplikacji (Program.cs lub równoważny)
  4. Usuń wszystkie instrukcje using Amazon.Textract;, using Amazon.Textract.Model;, using Amazon.S3;, using Amazon.Runtime;
  5. Dodaj using IronOcr; do każdego pliku, który wcześniej importował przestrzenie nazw Textract
  6. Zamień wywołania konstruktora AmazonTextractClient wywołaniami new IronTesseract()
  7. Zamień instancjonowanie AmazonS3Client i wszystkie wywołania PutObjectAsync / DeleteObjectAsync bezpośrednimi odczytami ścieżek do plików lub strumieni
  8. Zamień wszystkie wywołania DetectDocumentTextAsync: var text = ocr.Read(path).Text
  9. Zamień wszystkie StartDocumentTextDetectionAsync + pętle ankietowe na input.LoadPdf(path) + ocr.Read(input)
  10. Zamień wszystkie złożone potoki TIFF (TIFF → PDF → S3 → async) na input.LoadImageFrames(tiffPath)
  11. Zamień łańcuchy filtrów BlockType.LINE / BlockType.WORD na result.Lines / result.Words
  12. Zamień przegląd relacji BlockType.KEY_VALUE_SET na wyodrębnianie strefy CropRectangle
  13. Usuń wszystkie bloki przechwytywania ProvisionedThroughputExceededException i ograniczenia SemaphoreSlim
  14. Zamień wzorce wsadowe ograniczeń na Parallel.ForEach używając wspólnego IronTesseract instancji
  15. Usuń wszystkie konfiguracje zmiennych środowiskowych poświadczeń AWS z manifestów wdrożeniowych i potoków CI
  16. Wyłącz z użycia tymczasowe zasoby S3 po migracji i weryfikacji całego kodu przetwarzającego

Po migracji

  • Zweryfikuj, czy aplikacja uruchamia się poprawnie tylko z IRONOCR_LICENSE ustawionym i wszystkie zmienne środowiskowe AWS są usunięte
  • Uruchom OCR na tych samych przykładowych obrazach, które zostały wcześniej przetworzone przez Textract, i porównaj dokładność wyodrębnionego tekstu
  • Bezpośrednio przetwarzaj wielostronicowe pliki PDF i sprawdzaj, czy wszystkie strony zostały wyodrębnione bez korzystania z S3 lub asynchronicznego odpytywania
  • Przetwarzaj plik TIFF zawierający wiele ramek i sprawdź, czy liczba stron zgadza się z wynikami Textract dla tego samego dokumentu
  • Przetestuj przetwarzanie wsadowe z zestawem 50+ obrazów i potwierdź, że nie występuje równoważnik ProvisionedThroughputExceededException
  • Uruchom aplikację w kontenerze Docker bez dostępu do Internetu i sprawdź, czy OCR zakończyło się pomyślnie
  • Sprawdź, czy plik PDF z możliwością wyszukiwania otwiera się poprawnie w programie Adobe Reader i umożliwia wyszukiwanie pełnotekstowe
  • Potwierdź, że usunięcie AWS_ACCESS_KEY_ID i AWS_SECRET_ACCESS_KEY z środowiska wdrażania niczego nie zepsuje
  • Przetestuj wszystkie procesy wyodrębniania formularzy lub faktur w oparciu o znane wyniki z Textract, aby zweryfikować poprawność pól
  • Zmierz opóźnienie przetwarzania dla reprezentatywnego zestawu dokumentów i potwierdź wyeliminowanie minimalnego 5-sekundowego czasu oczekiwania na odpytanie

Kluczowe korzyści z migracji do IronOCR

Konsolidacja infrastruktury w jednym pakiecie NuGet. Trzy pakiety AWS SDK, zasób S3 z zasadami cyklu życia, role IAM we wszystkich środowiskach wdrożeniowych oraz procedury rotacji poświadczeń AWS zostały zastąpione jednym pakietem NuGet. Zmiana .csproj jest dotnet remove package AWSSDK.Textract, a następnie dotnet add package IronOcr. Wraz z tym znikają wszystkie dalsze konsekwencje zarządzania poświadczeniami AWS — audyty bezpieczeństwa, harmonogramy rotacji, higiena zmiennych środowiskowych, konfiguracja sekretów Docker.

Przewidywalny całkowity koszt posiadania. Model rozliczeń za stronę generuje koszty zmienne, które rosną w nieskończoność wraz z objętością dokumentów. Po migracji do IronOCR koszt przetworzenia każdej dodatkowej strony wynosi zero, niezależnie od ilości. Zespół przetwarzający 200 000 stron miesięcznie po stawce Textract AnalyzeDocument dla tabel wydaje $36 000 rocznie tylko na OCR. Licencja IronOCR Enterprise w cenie 2999 USD zwraca ten koszt w mniej niż 31 dni dzięki uniknięciu kosztów. Pełne informacje na temat poziomów licencji oraz warunków redystrybucji SaaS można znaleźć na stronie licencyjnej IronOCR.

Przetwarzanie synchroniczne eliminuje złożoność pięciofazowego przetwarzania asynchronicznego. Przesyłanie do S3, uruchomienie zadania, pętla odpytywania, zbieranie wyników w formacie paginowanym oraz blok końcowy czyszczenia reprezentują pięć niezależnych trybów awarii w potoku przetwarzania plików PDF w Textract. Po migracji kod dotyczący pliku PDF zajmuje zaledwie dwa wiersze. Obsługa błędów sprowadza się do pojedynczego try/catch wokół wywołania ocr.Read(). Logika czasu oczekiwania na pętlę, pętla do/while JobStatus == IN_PROGRESS, akumulator stronicowania nextToken — żadna z tych koncepcji nie istnieje w kodzie bazującym na IronOCR. Obciążenie związane z utrzymaniem kodu zmniejsza się proporcjonalnie do ilości usuniętego kodu.

Pełna elastyczność wdrożenia. Textract wymaga dostępu do Internetu przy każdym wywołaniu funkcji OCR.IronOCR wymaga dostępu do Internetu wyłącznie w celu pobrania pakietu NuGet podczas instalacji. Następnie działa w sieciach typu air-gapped, kontenerach Docker bez reguł wychodzących, serwerach lokalnych oraz instancjach AWS EC2 bez dostępu do Textract. Ten sam plik binarny, który działa w środowisku produkcyjnym na serwerze Windows Server, działa również w kontenerze Linux. Przewodnik wdrażania Docker oraz przewodnik wdrażania Linux obejmują konkretną konfigurację dla środowisk kontenerowych, które wcześniej nie mogły korzystać z Textract.

**Suwerenność danych osiągnięta dzięki architekturze, a nie konfiguracji.**IronOCR nie posiada trybu transmisji sieciowej, który można wyłączyć — jedynym trybem jest przetwarzanie lokalne. Dokumenty przetwarzane przez IronOCR nigdy nie opuszczają komputera hosta. W przypadku aplikacji medycznych przetwarzających dane PHI, aplikacji obronnych przetwarzających dane CUI oraz aplikacji finansowych przetwarzających obrazy kart płatniczych jest to podejście zgodne z przepisami, które nie wymaga negocjacji umowy BAA, konfiguracji regionalnej lokalizacji danych ani audytu zasad przetwarzania danych przez Amazon. Zakres zgodności to granice Twojej własnej infrastruktury, nad którą już sprawujesz kontrolę. Strona produktu IronOCR zawiera pełne podsumowanie funkcji oraz dokumentację wdrożeniową dla zespołów przeprowadzających przegląd zgodności.

Konfigurowalne przetwarzanie wstępne do kontroli jakości dokumentów. Wewnętrzne przetwarzanie wstępne Textract nie jest dostępne ani konfigurowalne. Gdy zeskanowany dokument daje słabe wyniki, jedynym rozwiązaniem jest zaakceptowanie wyniku lub ponowne skanowanie.IronOCR eksponuje pełny potok przetwarzania wstępnego: Deskew(), DeNoise(), Contrast(), Binarize(), Sharpen(), Scale(), Dilate(), Erode(), i DeepCleanBackgroundNoise(). Zespoły, które przeniosły dokumenty z Textract z powodu wyników o niskim poziomie pewności w przypadku trudnych skanów, mogą bezpośrednio zająć się przyczyną źródłową, stosując filtry dopasowane do konkretnej wady — obrotu, szumu, niskiego kontrastu lub niewystarczającej rozdzielczości. Strona poświęcona funkcjom przetwarzania wstępnego oraz przewodnik po korekcji jakości obrazu zawierają informacje na temat dostępnych filtrów i ich odpowiednich zastosowań.

Zwróć uwagę: AWS Textract, PDFSharp, Tesseract i iText są zarejestrowanymi znakami towarowymi swoich odpowiednich właścicieli. Ta strona nie jest powiązana, akceptowana ani sponsorowana przez Amazon Web Services, Google, empira Software GmbH lub iText Group. Wszystkie nazwy produktów, logotypy i marki są własnością ich odpowiednich właścicieli. Porównania mają charakter wyłącznie informacyjny i odzwierciedlają informacje dostępne publicznie w momencie pisania.

Powiązane artykuły

Key in blue circle

Uzyskaj natychmiast swój darmowy 30-dniowy Klucz Testowy.

Your trial license will be sent to your email address

Brak ograniczeń. 100% dostępności. Bez karty kredytowej.

bullet_checkedNie wymaga karty kredytowej ani tworzenia kontaBrak ograniczeń. 100% dostępności. Bez karty kredytowej.
  • Logo Aetna
  • Logo NASA
  • Logo GE
  • Logo Porsche
  • Logo USDA
  • Logo Qatar
Join Millions of Engineers who’ve tried IronPDF
Otrzymaj swoją Konsultację Bez Zobowiązań
Wypełnij poniższy formularz lub wyślij e-mail na sales@ironsoftware.com
Twoje dane zawsze będą utrzymywane w tajemnicy.
Zaufane przez miliony inżynierów na całym świecie
Logotypy klientów Iron Software
Otrzymaj swój darmowy Klucz Próbny na 30 dni natychmiast.
Nie wymaga karty kredytowej ani tworzenia konta