Przejdź do treści stopki
PORóWNAJ Z INNYMI KOMPONENTAMI

Porównanie pomiędzy IronOCR a Nanonets OCR

Model wycenyAWS Textractza strone moze wydawac sie niedrogi przy małej objętości, ale koszty nieustannie rosną na dużą skalę. Każdy dokument przetwarzany przez aplikację opuszcza twoją sieć, podróżuje do centrum danych Amazon, jest przetwarzany przez infrastrukturę Amazon, a rachunek nieustannie rośnie. Dla zespołów oceniających opcje OCR w .NET pytanie nie dotyczy tylko tego, czy Textract zapewnia dokładne wyniki — bo zapewnia — ale czy model kosztów na stronę, obowiązkowa transmisja do chmury i architektura asynchronicznego odpytywania dla dokumentów wielostronicowych odpowiadają rzeczywistym potrzebom aplikacji.

Zrozumienie AWS Textract

AWS Textract to zarządzana usługa analizy dokumentów Amazona, dostępna przez AWS SDK dla .NET za pośrednictwem pakietu AWSSDK.Textract NuGet. Działa jako interfejs API w chmurze: aplikacja wysyła dane dokumentu do infrastruktury Amazon i otrzymuje ustrukturyzowane wyniki. Usługa wymaga konta AWS, poświadczeń IAM z uprawnieniami Textract oraz połączenia internetowego dla każdej operacji OCR.

Textract oferuje kilka różnych trybów analizy, z których każdy jest wyceniany osobno:

  • DetectDocumentText: Podstawowe wyodrębnianie tekstu (zobacz AWS Textract cennik dla bieżących stawek za stronę)
  • AnalyzeDocument (Tabele): Podwyższony poziom za strone dla wyodrębniania strukturalnego tabel
  • AnalyzeDocument (Formularze): Wyższy poziom za stronę dla wyodrębniania par klucz-wartość niż wyodrębnianie tabel
  • AnalyzeExpense: Analiza faktur i paragonów za 0,01 USD za stronę
  • AnalyzeID: Pobieranie danych z dokumentów tożsamości za 0,025 USD za stronę
  • StartDocumentTextDetection / StartDocumentAnalysis: Asynchroniczny interfejs API wymagany dla dowolnego wielostronicowego pliku PDF, wymagający kontenera przejściowego S3, odpytywania zadań i paginacji wyników

Model wyników używa płaskiej listy obiektów Block z identyfikatorami relacji, które muszą być przeszukane, aby odtworzyć tabele, formularze lub dowolny ustrukturyzowany wynik. Proste wyodrębnianie tabeli wymaga iteracji przez bloki BlockType.TABLE, znalezienia bloków potomnych BlockType.CELL poprzez identyfikatory relacji RelationshipType.CHILD, a następnie pobrania bloków BlockType.WORD dla tekstu każdej komórki. Ten model grafu relacji obsługuje złożone struktury dokumentów, ale nie jest lekki.

Pipeline S3-Async

Pojedyncze obrazy OCR przez DetectDocumentTextAsync mogą przesyłać bajty dokumentu bezpośrednio w żądaniu. Dokumenty wielostronicowe nie mogą. Każdy plik PDF wymaga pełnego asynchronicznego potoku:

// AWS Textract: Wielostronicowy plik PDF requires S3 + async job
public async Task<string> ProcessPdfAsync(string pdfPath)
{
    // Step 1: Upload to S3 — credentials for two services required
    var key = $"uploads/{Guid.NewGuid()}.pdf";
    using (var fileStream = File.OpenRead(pdfPath))
    {
        await _s3Client.PutObjectAsync(new PutObjectRequest
        {
            BucketName = _bucketName,
            Key = key,
            InputStream = fileStream
        });
    }

    try
    {
        // Step 2: Start async Textract job
        var startResponse = await _textractClient.StartDocumentTextDetectionAsync(
            new StartDocumentTextDetectionRequest
            {
                DocumentLocation = new DocumentLocation
                {
                    S3Object = new S3Object { Bucket = _bucketName, Name = key }
                }
            });

        var jobId = startResponse.JobId;

        // Step 3: Poll every 5 seconds until complete
        GetDocumentTextDetectionResponse getResponse;
        do
        {
            await Task.Delay(5000);
            getResponse = await _textractClient.GetDocumentTextDetectionAsync(
                new GetDocumentTextDetectionRequest { JobId = jobId });
        } while (getResponse.JobStatus == JobStatus.IN_PROGRESS);

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

        // Step 4: Paginate through result blocks
        var allText = new StringBuilder();
        string nextToken = null;
        do
        {
            var pageResponse = await _textractClient.GetDocumentTextDetectionAsync(
                new GetDocumentTextDetectionRequest
                {
                    JobId = jobId,
                    NextToken = nextToken
                });

            foreach (var block in pageResponse.Blocks.Where(b => b.BlockType == BlockType.LINE))
                allText.AppendLine(block.Text);

            nextToken = pageResponse.NextToken;
        } while (nextToken != null);

        return allText.ToString();
    }
    finally
    {
        // Step 5: Zawsze clean up S3
        await _s3Client.DeleteObjectAsync(_bucketName, key);
    }
}
// AWS Textract: Wielostronicowy plik PDF requires S3 + async job
public async Task<string> ProcessPdfAsync(string pdfPath)
{
    // Step 1: Upload to S3 — credentials for two services required
    var key = $"uploads/{Guid.NewGuid()}.pdf";
    using (var fileStream = File.OpenRead(pdfPath))
    {
        await _s3Client.PutObjectAsync(new PutObjectRequest
        {
            BucketName = _bucketName,
            Key = key,
            InputStream = fileStream
        });
    }

    try
    {
        // Step 2: Start async Textract job
        var startResponse = await _textractClient.StartDocumentTextDetectionAsync(
            new StartDocumentTextDetectionRequest
            {
                DocumentLocation = new DocumentLocation
                {
                    S3Object = new S3Object { Bucket = _bucketName, Name = key }
                }
            });

        var jobId = startResponse.JobId;

        // Step 3: Poll every 5 seconds until complete
        GetDocumentTextDetectionResponse getResponse;
        do
        {
            await Task.Delay(5000);
            getResponse = await _textractClient.GetDocumentTextDetectionAsync(
                new GetDocumentTextDetectionRequest { JobId = jobId });
        } while (getResponse.JobStatus == JobStatus.IN_PROGRESS);

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

        // Step 4: Paginate through result blocks
        var allText = new StringBuilder();
        string nextToken = null;
        do
        {
            var pageResponse = await _textractClient.GetDocumentTextDetectionAsync(
                new GetDocumentTextDetectionRequest
                {
                    JobId = jobId,
                    NextToken = nextToken
                });

            foreach (var block in pageResponse.Blocks.Where(b => b.BlockType == BlockType.LINE))
                allText.AppendLine(block.Text);

            nextToken = pageResponse.NextToken;
        } while (nextToken != null);

        return allText.ToString();
    }
    finally
    {
        // Step 5: Zawsze clean up S3
        await _s3Client.DeleteObjectAsync(_bucketName, key);
    }
}
Imports System
Imports System.IO
Imports System.Text
Imports System.Threading.Tasks
Imports Amazon.S3
Imports Amazon.Textract
Imports Amazon.Textract.Model

Public Class PdfProcessor
    Private _s3Client As IAmazonS3
    Private _textractClient As IAmazonTextract
    Private _bucketName As String

    Public Async Function ProcessPdfAsync(pdfPath As String) As Task(Of String)
        ' Step 1: Upload to S3 — credentials for two services required
        Dim key As String = $"uploads/{Guid.NewGuid()}.pdf"
        Using fileStream As FileStream = File.OpenRead(pdfPath)
            Await _s3Client.PutObjectAsync(New PutObjectRequest With {
                .BucketName = _bucketName,
                .Key = key,
                .InputStream = fileStream
            })
        End Using

        Try
            ' Step 2: Start async Textract job
            Dim startResponse = Await _textractClient.StartDocumentTextDetectionAsync(
                New StartDocumentTextDetectionRequest With {
                    .DocumentLocation = New DocumentLocation With {
                        .S3Object = New S3Object With {.Bucket = _bucketName, .Name = key}
                    }
                })

            Dim jobId As String = startResponse.JobId

            ' Step 3: Poll every 5 seconds until complete
            Dim getResponse As GetDocumentTextDetectionResponse
            Do
                Await Task.Delay(5000)
                getResponse = Await _textractClient.GetDocumentTextDetectionAsync(
                    New GetDocumentTextDetectionRequest With {.JobId = jobId})
            Loop While getResponse.JobStatus = JobStatus.IN_PROGRESS

            If getResponse.JobStatus <> JobStatus.SUCCEEDED Then
                Throw New Exception($"Textract job failed: {getResponse.StatusMessage}")
            End If

            ' Step 4: Paginate through result blocks
            Dim allText As New StringBuilder()
            Dim nextToken As String = Nothing
            Do
                Dim pageResponse = Await _textractClient.GetDocumentTextDetectionAsync(
                    New GetDocumentTextDetectionRequest With {
                        .JobId = jobId,
                        .NextToken = nextToken
                    })

                For Each block In pageResponse.Blocks.Where(Function(b) b.BlockType = BlockType.LINE)
                    allText.AppendLine(block.Text)
                Next

                nextToken = pageResponse.NextToken
            Loop While nextToken IsNot Nothing

            Return allText.ToString()
        Finally
            ' Step 5: Zawsze clean up S3
            Await _s3Client.DeleteObjectAsync(_bucketName, key)
        End Try
    End Function
End Class
$vbLabelText   $csharpLabel

To jest minimalna wykonalna implementacja do niezawodnego przetwarzania PDF — pięć odrębnych faz, dwóch klientów usług AWS i logika czyszczenia w bloku finally. Pełna wersja produkcyjna z odpowiednią obsługą błędów, logiką ponownych prób przy ograniczeniu częstotliwości oraz zarządzaniem limitami czasu ma długość 150–300 wierszy.

Zrozumienie IronOCR

IronOCR to komercyjna biblioteka OCR dla platformy .NET, która działa w całości na infrastrukturze użytkownika. Zawiera zoptymalizowany silnik Tesseract 5 z automatycznym przetwarzaniem wstępnym obrazów, natywną obsługą plików PDF oraz synchronicznym interfejsem API, który generuje wyniki bezpośrednio, bez wywoływania usług zewnętrznych lub etapów pośrednich.

Kluczowe cechy architektury IronOCR:

  • Tylko przetwarzanie lokalne: żadne dane dokumentów nie opuszczają komputera, na którym działa aplikacja
  • Pojedynczy pakiet NuGet: dotnet add package IronOcr instaluje wszystko, w tym natywne pliki binarne
  • Automatyczne przetwarzanie wstępne: prostowanie, usuwanie szumów, wzmocnienie kontrastu, binarizacja i skalowanie rozdzielczości odbywają się automatycznie w przypadku danych wejściowych o niskiej jakości
  • Natywna obsługa plików PDF: odczytuje pliki PDF bezpośrednio poprzez ścieżkę pliku lub strumień bez pośrednictwa S3 lub zadań asynchronicznych
  • Bezpieczne dla wątków: Jeden egzemplarz IronTesseract obsługuje równoczesne żądania w wielu wątkach bez kolizji
  • Licencjonowanie wieczyste: $999 Lite / $1,499 Plus / $2,999 Professional / $5,999 Unlimited — jednorazowa płatność, brak opłat za stronę, brak limitów użycia
  • Ponad 125 pakietów językowych: instalowanych jako oddzielne pakiety NuGet, ładowanych lokalnie, bez połączeń sieciowych

Porównanie funkcji

Funkcja AWS Textract IronOCR
Miejsce przetwarzania Amazon Cloud (obowiązkowe) Lokalne / na miejscu
Wielostronicowy plik PDF Wymagane S3 + zadanie asynchroniczne Bezpośrednie wywołanie synchroniczne
Model kosztowy Za stronę (kontaktuj się z AWS w celu uzyskania bieżących cen) Licencja wieczysta, brak opłat za stronę
Wymagane połączenie z Internetem Zawsze Nigdy
Konfiguracja poświadczeń Użytkownik/rola IAM + opcjonalnie S3 Pojedynczy ciąg klucza licencyjnego
Wdrożenie w środowisku izolowanym Niemożliwe W pełni obsługiwane
Obsługa zaszyfrowanych plików PDF Nieobsługiwane Wbudowane (parametr hasła)

Szczegółowe porównanie funkcji

Funkcja AWS Textract IronOCR
Wyodrębnianie tekstu
Podstawowe OCR (obrazy) Tak — DetectDocumentTextAsync Tak — ocr.Read(path)
Wielostronicowy plik PDF Wymaga S3 + asynchronicznego odpytywania Bezpośredni input.LoadPdf(path)
Plik PDF chroniony hasłem Nieobsługiwane input.LoadPdf(path, Password: "x")
Dane wejściowe strumienia Tak (tablica bajtów w żądaniu) Tak — input.LoadImage(stream)
Pobieranie danych ustrukturyzowanych
Wyodrębnianie tabel AnalyzeDocument + przeszukiwanie wykresu blokowego Rekonstrukcja oparta na pozycji słów WORD
Pobieranie danych z pól formularzy AnalyzeDocument + bloki KEY_VALUE_SET Strefy CropRectangle oparte na regionach
Wyniki na poziomie wiersza Filtracja Block według BlockType.LINE Bezpośrednia kolekcja result.Lines
Na poziomie WORD z koordynatami Filtracja Block według BlockType.WORD result.Words z .X, .Y, .Width
Wyniki pewności Pewność dla poszczególnych bloków Po słowie i całkowity result.Confidence
Model przetwarzania
Synchroniczne (obrazy) Tak (tylko jedna strona) Tak (wszystkie typy dokumentów)
Asynchroniczny Wymagane dla plików PDF Opcjonalnie — opakowanie Task.Run()
Przetwarzanie wsadowe Wymaga zarządzania limitami szybkości (domyślnie 5 TPS) Niezwiązane Parallel.ForEach
Przetwarzanie wstępne
Automatyczna korekcja przekrzywienia Nieujawnione input.Deskew()
Usuwanie szumów Wewnętrzne (niekonfigurowalne) input.DeNoise()
Wzmocnienie kontrastu Wewnętrzne (niekonfigurowalne) input.Contrast()
Poprawa rozdzielczości Wewnętrzne (niekonfigurowalne) input.EnhanceResolution(300)
Binaryzacja Wewnętrzne input.Binarize()
Formaty wyjściowe
Zwykły tekst Tak Tak
PDF z funkcją wyszukiwania Nie result.SaveAsSearchablePdf(path)
hOCR Nie result.SaveAsHocrFile(path)
Strukturalny JSON Poprzez serializację blokową result.Words / result.Lines
Wdrożenie
Lokalnie Nie Tak
Odizolowane Nie Tak
Docker Tak (z wstawionymi danymi uwierzytelniającymi AWS) Tak (nie są wymagane dane uwierzytelniające)
AWS Lambda Język ojczysty Obsługiwane
Azure Tak Tak
Linux Tak (zarządzane przez AWS) Tak — get-started/linux/
Zgodność
HIPAA Wymagana umowa BAA z AWS Brak zewnętrznego procesora
RODO Przenoszenie danych do regionów AWS Dane pozostają w granicach
ITAR Zabronione bez specjalnego upoważnienia W całości na miejscu
Odizolowane/CMMC poziom 3 Niemożliwe Obsługiwane

Koszt w skali

Model cenowy oparty na liczbie stron stanowi podstawowe ograniczenie strukturalne usługi AWS Textract. Koszty, które wydają się małe za stronę, znacznie się kumulują przy rzeczywistym przepływie dokumentów.

Podejście AWS Textract

// Every call to this method costs money — per page, permanently
public async Task<string> DetectTextAsync(string imagePath)
{
    var imageBytes = File.ReadAllBytes(imagePath);  // Image leaves your network

    var request = new DetectDocumentTextRequest
    {
        Document = new Document
        {
            Bytes = new MemoryStream(imageBytes)
        }
    };

    var response = await _client.DetectDocumentTextAsync(request);  // per-page charge

    return string.Join("\n", response.Blocks
        .Where(b => b.BlockType == BlockType.LINE)
        .Select(b => b.Text));
}
// Every call to this method costs money — per page, permanently
public async Task<string> DetectTextAsync(string imagePath)
{
    var imageBytes = File.ReadAllBytes(imagePath);  // Image leaves your network

    var request = new DetectDocumentTextRequest
    {
        Document = new Document
        {
            Bytes = new MemoryStream(imageBytes)
        }
    };

    var response = await _client.DetectDocumentTextAsync(request);  // per-page charge

    return string.Join("\n", response.Blocks
        .Where(b => b.BlockType == BlockType.LINE)
        .Select(b => b.Text));
}
Imports System.IO
Imports System.Threading.Tasks

' Every call to this method costs money — per page, permanently
Public Async Function DetectTextAsync(imagePath As String) As Task(Of String)
    Dim imageBytes = File.ReadAllBytes(imagePath)  ' Image leaves your network

    Dim request = New DetectDocumentTextRequest With {
        .Document = New Document With {
            .Bytes = New MemoryStream(imageBytes)
        }
    }

    Dim response = Await _client.DetectDocumentTextAsync(request)  ' per-page charge

    Return String.Join(vbLf, response.Blocks _
        .Where(Function(b) b.BlockType = BlockType.LINE) _
        .Select(Function(b) b.Text))
End Function
$vbLabelText   $csharpLabel

Skonsultuj stronę cennika AWS Textract dla bieżących stawek za stronę. Różne funkcje API (podstawowe wykrywanie tekstu, wyodrębnianie tabel, wyodrębnianie formularzy) mają różne stawki. Dokument zawierajacy tabele i pola formularza generuje wyzsze oplaty niz podstawowe wykrywanie tekstu, a koszty rosna wraz z objetością bez gornych limitow i bez mozliwosci zapłaty z góry.

Przy wysokich objetościach stron, całkowite koszty trzech lat mogą być znaczne, a miernik wciąż biegnie.

Podejście IronOCR

// One license. Nie per-page cost. Same code handles 1 page or 1,000,000.
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";

var text = new IronTesseract().Read("document.jpg").Text;
// One license. Nie per-page cost. Same code handles 1 page or 1,000,000.
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";

var text = new IronTesseract().Read("document.jpg").Text;
Imports IronOcr

' One license. Nie per-page cost. Same code handles 1 page or 1,000,000.
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"

Dim text = New IronTesseract().Read("document.jpg").Text
$vbLabelText   $csharpLabel

Licencja $2,999 Professional obejmuje 10 programistów, nieograniczoną liczbę projektów i nieograniczoną liczbę stron. Po pierwszym roku bieżący koszt przetwarzania stron wynosi zero. Dla zespołów przetwarzających duże ilości stron, licencja IronOCR szybko się zwraca w porównaniu z trwającymi opłatami za przetwarzanie w chmurze na stronę.

Strona licencyjna IronOCR zawiera szczegółowe informacje na temat poziomów licencji, opcji subskrypcji SaaS w scenariuszach rozliczeń opartych na wykorzystaniu oraz warunków redystrybucji OEM.

Suwerenność danych i zgodność z przepisami

ArchitekturaAWS Textractuniemożliwia spełnienie jednej gwarancji: że dokumenty pozostaną w ramach infrastruktury użytkownika. Każda operacja OCR przesyła zawartość dokumentu na serwery Amazon.

Podejście AWS Textract

// This code sends PHI, legal documents, financial records — whatever is in
// the file — to Amazon Web Services infrastructure
public async Task<string> ProcessSensitiveDocumentAsync(string documentPath)
{
    var imageBytes = File.ReadAllBytes(documentPath);

    // Data crosses your security perimeter here
    var request = new DetectDocumentTextRequest
    {
        Document = new Document
        {
            Bytes = new MemoryStream(imageBytes)
        }
    };

    // Amazon processes it; you receive text back
    var response = await _client.DetectDocumentTextAsync(request);

    return string.Join("\n", response.Blocks
        .Where(b => b.BlockType == BlockType.LINE)
        .Select(b => b.Text));
}
// This code sends PHI, legal documents, financial records — whatever is in
// the file — to Amazon Web Services infrastructure
public async Task<string> ProcessSensitiveDocumentAsync(string documentPath)
{
    var imageBytes = File.ReadAllBytes(documentPath);

    // Data crosses your security perimeter here
    var request = new DetectDocumentTextRequest
    {
        Document = new Document
        {
            Bytes = new MemoryStream(imageBytes)
        }
    };

    // Amazon processes it; you receive text back
    var response = await _client.DetectDocumentTextAsync(request);

    return string.Join("\n", response.Blocks
        .Where(b => b.BlockType == BlockType.LINE)
        .Select(b => b.Text));
}
Imports System.IO
Imports System.Threading.Tasks
Imports Amazon.Textract
Imports Amazon.Textract.Model

Public Class DocumentProcessor
    Private _client As AmazonTextractClient

    Public Sub New(client As AmazonTextractClient)
        _client = client
    End Sub

    ' This code sends PHI, legal documents, financial records — whatever is in
    ' the file — to Amazon Web Services infrastructure
    Public Async Function ProcessSensitiveDocumentAsync(documentPath As String) As Task(Of String)
        Dim imageBytes = File.ReadAllBytes(documentPath)

        ' Data crosses your security perimeter here
        Dim request As New DetectDocumentTextRequest With {
            .Document = New Document With {
                .Bytes = New MemoryStream(imageBytes)
            }
        }

        ' Amazon processes it; you receive text back
        Dim response = Await _client.DetectDocumentTextAsync(request)

        Return String.Join(vbLf, response.Blocks _
            .Where(Function(b) b.BlockType = BlockType.LINE) _
            .Select(Function(b) b.Text))
    End Function
End Class
$vbLabelText   $csharpLabel

AWS oferuje umowęHIPAABusiness Associate Agreement dla podmiotów objętych przepisami, a regiony GovCloud zapewniają autoryzację FedRAMP High. Frameworki te nie zmieniają podstawowej architektury: dokumenty opuszczają infrastrukturę użytkownika przy każdej operacji. W przypadku danych technicznych podlegających przepisomITARnie jest to kwestia niuansów zgodności — jest to zakaz. W przypadku obciążeń CMMC poziomu 3 z CUI transmisja w chmurze wymaga specjalnych uprawnień, których większość wykonawców z sektóra obronnego nie posiada. W przypadku systemów odizolowanych — sieci badawczych, przemysłowych środowisk kontrolnych, obiektów o ograniczonym dostępie — Textract jest po prostu niedostępny.

AWS Textract jest dostępny w sześciu regionach: us-east-1, us-west-2, eu-west-1, eu-west-2, ap-southeast-1 i ap-southeast-2. Organizacje, które muszą spełniać wymogi dotyczące lokalizacji danych poza tymi regionami, nie mają żadnej opcji zgodnej z przepisami.

Podejście IronOCR

// IronOCR: document bytes never leave this process
public string ProcessSensitiveDocument(string documentPath)
{
    // Processes entirely on local hardware — no network call
    var ocr = new IronTesseract();
    return ocr.Read(documentPath).Text;
}
// IronOCR: document bytes never leave this process
public string ProcessSensitiveDocument(string documentPath)
{
    // Processes entirely on local hardware — no network call
    var ocr = new IronTesseract();
    return ocr.Read(documentPath).Text;
}
' IronOCR: document bytes never leave this process
Public Function ProcessSensitiveDocument(documentPath As String) As String
    ' Processes entirely on local hardware — no network call
    Dim ocr As New IronTesseract()
    Return ocr.Read(documentPath).Text
End Function
$vbLabelText   $csharpLabel

PonieważIronOCR działa lokalnie, naturalnie wpisuje się w procesy opieki zdrowotnej przetwarzające dane medyczne (PHI), systemy dokumentów prawnych obsługujące poufną korespondencję, aplikacje finansowe przetwarzające obrazy kart płatniczych oraz procesy wykonawców z sektóra obronnego przetwarzające informacje o znaczeniu krytycznym (CUI). Nie ma żadnego zewnętrznego procesora do audytu, żadnej umowy BAA do negocjacji, żadnych ograniczeń dotyczących lokalizacji danych, które należałoby spełnić. Zakres zgodności obejmuje infrastrukturę Twojej organizacji.

Dla zespołów wdrażających rozwiązania w infrastrukturze AWS, ale wymagających lokalnego przetwarzania,IronOCRdziała na AWS (EC2, Lambda) bez żadnej zależności od Textract — przetwarzanie odbywa się w ramach własnego konta AWS, a nie w ramach usługi zarządzanej przez Amazon.

Pobieranie asynchroniczne a przetwarzanie synchroniczne

Podział architektury między synchronicznymi (pojedynczy obraz) i asynchronicznymi (wielostronicowy plik PDF) interfejsami API Textract nie jest drobnym szczegółem API. To one kształtują sposób tworzenia usług, sposób obsługi błędów oraz to, ile kodu muszą przeczytać i przeanalizować osoby odpowiedzialne za utrzymanie oprogramowania.

Podejście AWS Textract

// Full production-grade async processor for Textract PDF handling
public class TextractAsyncProcessor
{
    private readonly AmazonTextractClient _textractClient;
    private readonly AmazonS3Client _s3Client;
    private readonly string _bucketName;
    private readonly TimeSpan _pollInterval = TimeSpan.FromSeconds(5);
    private readonly TimeSpan _maxWaitTime = TimeSpan.FromMinutes(10);

    public async Task<DocumentResult> ProcessDocumentAsync(
        string localFilePath,
        CancellationToken cancellationToken = default)
    {
        var s3Key = $"textract-uploads/{Guid.NewGuid()}{Path.GetExtension(localFilePath)}";

        try
        {
            // Phase 1: Upload to S3
            await UploadToS3Async(localFilePath, s3Key, cancellationToken);

            // Phase 2: Start Textract job
            var jobId = await StartTextractJobAsync(s3Key, cancellationToken);

            // Phase 3: Poll until complete (up to 10 minutes)
            var pollResult = await PollForCompletionAsync(jobId, cancellationToken);

            if (!pollResult.Success)
                throw new Exception($"Textract job failed: {pollResult.ErrorMessage}");

            // Phase 4: Retrieve paginated results
            return await GetAllResultsAsync(jobId, cancellationToken);
        }
        finally
        {
            // Phase 5: S3 cleanup — must succeed or storage costs accumulate
            await DeleteFromS3Async(s3Key, cancellationToken);
        }
    }

    private async Task<(bool Success, string ErrorMessage)> PollForCompletionAsync(
        string jobId, CancellationToken cancellationToken)
    {
        var startTime = DateTime.UtcNow;
        int pollCount = 0;

        while (DateTime.UtcNow - startTime < _maxWaitTime)
        {
            cancellationToken.ThrowIfCancellationRequested();

            var response = await _textractClient.GetDocumentTextDetectionAsync(
                new GetDocumentTextDetectionRequest { JobId = jobId }, cancellationToken);

            pollCount++;

            switch (response.JobStatus)
            {
                case JobStatus.SUCCEEDED: return (true, null);
                case JobStatus.FAILED: return (false, response.StatusMessage ?? "Unknown error");
                case JobStatus.IN_PROGRESS:
                    await Task.Delay(_pollInterval, cancellationToken);
                    break;
                default:
                    throw new Exception($"Unknown job status: {response.JobStatus}");
            }
        }

        return (false, "Job timed out");
    }
}
// Full production-grade async processor for Textract PDF handling
public class TextractAsyncProcessor
{
    private readonly AmazonTextractClient _textractClient;
    private readonly AmazonS3Client _s3Client;
    private readonly string _bucketName;
    private readonly TimeSpan _pollInterval = TimeSpan.FromSeconds(5);
    private readonly TimeSpan _maxWaitTime = TimeSpan.FromMinutes(10);

    public async Task<DocumentResult> ProcessDocumentAsync(
        string localFilePath,
        CancellationToken cancellationToken = default)
    {
        var s3Key = $"textract-uploads/{Guid.NewGuid()}{Path.GetExtension(localFilePath)}";

        try
        {
            // Phase 1: Upload to S3
            await UploadToS3Async(localFilePath, s3Key, cancellationToken);

            // Phase 2: Start Textract job
            var jobId = await StartTextractJobAsync(s3Key, cancellationToken);

            // Phase 3: Poll until complete (up to 10 minutes)
            var pollResult = await PollForCompletionAsync(jobId, cancellationToken);

            if (!pollResult.Success)
                throw new Exception($"Textract job failed: {pollResult.ErrorMessage}");

            // Phase 4: Retrieve paginated results
            return await GetAllResultsAsync(jobId, cancellationToken);
        }
        finally
        {
            // Phase 5: S3 cleanup — must succeed or storage costs accumulate
            await DeleteFromS3Async(s3Key, cancellationToken);
        }
    }

    private async Task<(bool Success, string ErrorMessage)> PollForCompletionAsync(
        string jobId, CancellationToken cancellationToken)
    {
        var startTime = DateTime.UtcNow;
        int pollCount = 0;

        while (DateTime.UtcNow - startTime < _maxWaitTime)
        {
            cancellationToken.ThrowIfCancellationRequested();

            var response = await _textractClient.GetDocumentTextDetectionAsync(
                new GetDocumentTextDetectionRequest { JobId = jobId }, cancellationToken);

            pollCount++;

            switch (response.JobStatus)
            {
                case JobStatus.SUCCEEDED: return (true, null);
                case JobStatus.FAILED: return (false, response.StatusMessage ?? "Unknown error");
                case JobStatus.IN_PROGRESS:
                    await Task.Delay(_pollInterval, cancellationToken);
                    break;
                default:
                    throw new Exception($"Unknown job status: {response.JobStatus}");
            }
        }

        return (false, "Job timed out");
    }
}
Imports System
Imports System.IO
Imports System.Threading
Imports System.Threading.Tasks
Imports Amazon.Textract
Imports Amazon.S3
Imports Amazon.Textract.Model

' Full production-grade async processor for Textract PDF handling
Public Class TextractAsyncProcessor
    Private ReadOnly _textractClient As AmazonTextractClient
    Private ReadOnly _s3Client As AmazonS3Client
    Private ReadOnly _bucketName As String
    Private ReadOnly _pollInterval As TimeSpan = TimeSpan.FromSeconds(5)
    Private ReadOnly _maxWaitTime As TimeSpan = TimeSpan.FromMinutes(10)

    Public Async Function ProcessDocumentAsync(localFilePath As String, Optional cancellationToken As CancellationToken = Nothing) As Task(Of DocumentResult)
        Dim s3Key = $"textract-uploads/{Guid.NewGuid()}{Path.GetExtension(localFilePath)}"

        Try
            ' Phase 1: Upload to S3
            Await UploadToS3Async(localFilePath, s3Key, cancellationToken)

            ' Phase 2: Start Textract job
            Dim jobId = Await StartTextractJobAsync(s3Key, cancellationToken)

            ' Phase 3: Poll until complete (up to 10 minutes)
            Dim pollResult = Await PollForCompletionAsync(jobId, cancellationToken)

            If Not pollResult.Success Then
                Throw New Exception($"Textract job failed: {pollResult.ErrorMessage}")
            End If

            ' Phase 4: Retrieve paginated results
            Return Await GetAllResultsAsync(jobId, cancellationToken)
        Finally
            ' Phase 5: S3 cleanup — must succeed or storage costs accumulate
            Await DeleteFromS3Async(s3Key, cancellationToken)
        End Try
    End Function

    Private Async Function PollForCompletionAsync(jobId As String, cancellationToken As CancellationToken) As Task(Of (Success As Boolean, ErrorMessage As String))
        Dim startTime = DateTime.UtcNow
        Dim pollCount As Integer = 0

        While DateTime.UtcNow - startTime < _maxWaitTime
            cancellationToken.ThrowIfCancellationRequested()

            Dim response = Await _textractClient.GetDocumentTextDetectionAsync(New GetDocumentTextDetectionRequest With {.JobId = jobId}, cancellationToken)

            pollCount += 1

            Select Case response.JobStatus
                Case JobStatus.SUCCEEDED
                    Return (True, Nothing)
                Case JobStatus.FAILED
                    Return (False, If(response.StatusMessage, "Unknown error"))
                Case JobStatus.IN_PROGRESS
                    Await Task.Delay(_pollInterval, cancellationToken)
                Case Else
                    Throw New Exception($"Unknown job status: {response.JobStatus}")
            End Select
        End While

        Return (False, "Job timed out")
    End Function
End Class
$vbLabelText   $csharpLabel

Nie jest to szablon, który można wygenerować i o nim zapomnieć. Gdy zadanie Textract zakończy się niepowodzeniem w trakcie wykonywania, czyszczenie S3 musi nadal przebiegać. Gdy zadanie wygaśnie po 10 minutach, wywołujący potrzebuje jasnego komunikatu o błędzie. W przypadku utraty połączenia sieciowego podczas odpytywania strategia ponownych prób nie może powodować tworzenia zduplikowanych zadań. Każdy z tych trybów awarii wymaga wyraźnego obsługi — struktura pokazana powyżej stanowi minimalną odpowiedzialną implementację.

Przetwarzanie wsadowe dodaje kolejną warstwę: domyślny limit StartDocumentTextDetection TPS dla Textract to 5 żądań na sekundę. Przetworzenie 100 dokumentów wymaga ograniczenia SemaphoreSlim, zegara odnawiania szybkości i logiki ponownego próbowania dla ProvisionedThroughputExceededException.

Podejście IronOCR

// IronOCR: same synchronous API regardless of document type or size
public string ProcessDocument(string filePath)
{
    using var input = new OcrInput();

    if (Path.GetExtension(filePath).Equals(".pdf", StringComparison.OrdinalIgnoreCase))
        input.LoadPdf(filePath);
    else
        input.LoadImage(filePath);

    return new IronTesseract().Read(input).Text;
}
// IronOCR: same synchronous API regardless of document type or size
public string ProcessDocument(string filePath)
{
    using var input = new OcrInput();

    if (Path.GetExtension(filePath).Equals(".pdf", StringComparison.OrdinalIgnoreCase))
        input.LoadPdf(filePath);
    else
        input.LoadImage(filePath);

    return new IronTesseract().Read(input).Text;
}
Imports System.IO

' IronOCR: same synchronous API regardless of document type or size
Public Function ProcessDocument(filePath As String) As String
    Using input As New OcrInput()
        If Path.GetExtension(filePath).Equals(".pdf", StringComparison.OrdinalIgnoreCase) Then
            input.LoadPdf(filePath)
        Else
            input.LoadImage(filePath)
        End If

        Return New IronTesseract().Read(input).Text
    End Using
End Function
$vbLabelText   $csharpLabel

Nie ma pętli odpytywania, śledzenia identyfikatorów zadań, zasobnika S3 ani paginacji wyników. Ten sam kod obsługuje zarówno pojedynczy plik JPEG, jak i 200-stronicowy plik PDF. Przetwarzanie kończy się powodzeniem lub generuje wyjątek — nie ma pośredniego stanu "w toku", którym trzeba by zarządzać. Do przetwarzania wsadowego, IronOCR działa w trybie bezpiecznym dla wątków, a jeden egzemplarz IronTesseract obsługuje Parallel.ForEach bez blokad ani semaforów.

Podręcznik konfiguracji IronTesseract obejmuje ustawienia, a podręcznik dotyczący plików PDF opisuje wybór zakresu stron, pliki PDF chronione hasłem oraz wprowadzanie strumieniowe plików PDF pobranych z baz danych lub odpowiedzi HTTP.

Nakład związany z zarządzaniem poświadczeniami

Rozpoczęcie operacji OCR za pomocąAWS Textractwymaga konfiguracji IAM przed przetworzeniem pierwszej strony.

Podejście AWS Textract

Zanim wywołasz DetectDocumentTextAsync, programista musi:

  1. Utwórz konto AWS lub uzyskaj dostęp do istniejącego konta
  2. Utwórz użytkownika IAM lub rolę z pozwoleniami textract:DetectDocumentText i textract:AnalyzeDocument
  3. Generowanie i bezpieczne przechowywanie identyfikatora klucza dostępu oraz tajnego klucza dostępu
  4. Skonfiguruj rozpoznawanie poświadczeń — zmienne środowiskowe, plik poświadczeń AWS lub profil instancji EC2
  5. Jeśli przetwarzane są PDF-y: utwórz kubeł S3, skonfiguruj politykę kubełka, dodaj uprawnienia s3:PutObject i s3:DeleteObject
  6. Wdrożenie zasad rotacji poświadczeń w celu spełnienia standardów bezpieczeństwa
  7. Bezpieczne przechowywanie danych uwierzytelniających w każdym środowisku wdrożeniowym — sekrety Docker, sekrety Kubernetes, AWS Secrets Manager lub zmienne potoku CI/CD
// Every environment needs these configured before this constructor succeeds
public TextractOcrService()
{
    // Reads credentials from environment, ~/.aws/credentials, or IAM role
    _client = new AmazonTextractClient(Amazon.RegionEndpoint.USEast1);
}
// Every environment needs these configured before this constructor succeeds
public TextractOcrService()
{
    // Reads credentials from environment, ~/.aws/credentials, or IAM role
    _client = new AmazonTextractClient(Amazon.RegionEndpoint.USEast1);
}
' Every environment needs these configured before this constructor succeeds
Public Sub New()
    ' Reads credentials from environment, ~/.aws/credentials, or IAM role
    _client = New AmazonTextractClient(Amazon.RegionEndpoint.USEast1)
End Sub
$vbLabelText   $csharpLabel

Gdy dane uwierzytelniające wygasają, są obracane lub nie są poprawnie skonfigurowane, każde wywołanie OCR kończy się niepowodzeniem z AmazonTextractException zawierającymi ErrorCode == "AccessDeniedException". W systemie produkcyjnym oznacza to wdrożenie konkretnych bloków catch na wypadek niepowodzeń związanych z poświadczeniami oraz monitorowanie odchyleń od zasad IAM.

Podejście IronOCR

// One-time setup at application startup
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";

// Or from environment — recommended for deployments
IronOcr.License.LicenseKey = Environment.GetEnvironmentVariable("IRONOCR_LICENSE");
// One-time setup at application startup
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";

// Or from environment — recommended for deployments
IronOcr.License.LicenseKey = Environment.GetEnvironmentVariable("IRONOCR_LICENSE");
' One-time setup at application startup
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"

' Or from environment — recommended for deployments
IronOcr.License.LicenseKey = Environment.GetEnvironmentVariable("IRONOCR_LICENSE")
$vbLabelText   $csharpLabel

Klucz licencyjny jest ciągiem statycznym. Nie wygasa w trakcie działania, nie wymaga rotacji i nie wymaga zarządzania uprawnieniami. KontenerDockerprzetwarzający dokumenty nie wymaga wstrzykiwania poświadczeń AWS, roli IAM powiązanej z kontekstem wykonania ani dostępu sieciowego do AWS STS w celu odświeżenia tokenu.

Całkowite zmniejszenie obciążenia związanego z poświadczeniami przy przejściu z Textract na IronOCR: usunięto trzy pakiety NuGet (AWSSDK.Textract, AWSSDK.S3, AWSSDK.Core), usunięto wszystkie zmienne środowiskowe AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY / AWS_DEFAULT_REGION, a role IAM i konfiguracje kubełków S3 zostały zlikwidowane. Przewodnik po wprowadzaniu obrazów i przewodnik po wprowadzaniu strumieniowym obejmują pełen zakres metod wprowadzania danych, które zastępują modele dokumentów Textract oparte na tablicach bajtów i obiektach S3.

Przewodnik po mapowaniu API

AWS Textract API Odpowiednik IronOCR
AmazonTextractClient IronTesseract
AmazonS3Client Nie jest wymagane
DetectDocumentTextRequest OcrInput
DetectDocumentTextResponse OcrResult
AnalyzeDocumentRequest OcrInput z CropRectangle dla stref
StartDocumentTextDetectionRequest OcrInput — synchroniczne, nie wymaga uruchamiania
GetDocumentTextDetectionRequest Nie jest wymagane — wyniki natychmiastowe
Document.Bytes input.LoadImage(bytes) lub input.LoadImage(stream)
S3Object (przechowywanie dokumentów) Ciąg znaków ścieżki pliku lub strumień
Block (BlockType.LINE) result.Lines
Block (BlockType.WORD) result.Words
Block (BlockType.TABLE) Grupowanie pozycji słów przez result.Words
Block (BlockType.KEY_VALUE_SET) Ekstrakcja regionu CropRectangle
Block.Confidence word.Confidence / result.Confidence
JobStatus.SUCCEEDED Nie dotyczy — zwrot synchroniczny
JobStatus.IN_PROGRESS Nie dotyczy — brak stanu asynchronicznego
response.NextToken (paginacja) Nie dotyczy — wyniki nie są podzielone na strony
ProvisionedThroughputExceededException Nie dotyczy — brak limitów TPS
client.DetectDocumentTextAsync(request) ocr.Read(path)
client.AnalyzeDocumentAsync(request) ocr.Read(input)
client.StartDocumentTextDetectionAsync(request) ocr.Read(input)
client.GetDocumentTextDetectionAsync(request) Nie dotyczy

Kiedy zespoły rozważają przejście zAWS Textractna IronOCR

Kiedy miesięczny rachunek staje się pozycją w budżecie

Zespoły, które zaczynały korzystać z Textract przy niewielkich wolumenach, często stają przed pewnym dylematem: podczas kwartalnego przeglądu budżetu pojawia się rachunek AWS za przetwarzanie OCR i ktoś pyta, czy ten koszt jest stały. Nie jest. Przy dużych ilościach stron, roczne koszty Textract mogą być znaczące — skonsultuj stronę z wyceną AWS Textract dla aktualnych stawek. Licencja IronOCR Professional w $2,999 jednorazowego zakupu szybko przynosi zwrot przy średnich i wysokich objętościach stron.

Kiedy wymogi zgodności blokują przetwarzanie w chmurze

Organizacje opieki zdrowotnej wdrażające procesy digitalizacji dokumentów często w trakcie projektu odkrywają, że daneHIPAAPHI nie mogą przepływać przez usługi w chmurze bez umowy BAA i dodatkowej weryfikacji prawnej, lub że ich zespół ds. bezpieczeństwa całkowicie zabrania transmisji w chmurze. Wykonawcy z branży obronnej zajmujący się rysunkami technicznymi, specyfikacjami lub dowolnymi informacjami o ograniczonym dostępie (CUI) podlegają ograniczeniomITARi CMMC, które wykluczająAWS Textractz rozważań. Kancelarie prawne przetwarzające poufną korespondencję mają podobne obawy. Nie są to teoretyczne skrajne przypadki zgodności — pojawiają się one regularnie podczas przeglądów zamówień, audytów bezpieczeństwa i negocjacji umów.IronOCR przetwarza dane lokalnie, więc kwestia zgodności w odniesieniu do danych dokumentów sprowadza się do tego, czy w zakresie znajduje się Twoja własna infrastruktura, a nie infrastruktura Amazon.

Kiedy złożoność asynchronicznego PDF przewyższa jego wartość

Pięciofazowy potok S3-async — przesyłanie, uruchamianie zadania, odpytywanie, paginacja wyników, czyszczenie — nie jest trudny do wdrożenia pod względem technicznym. Trudno jest go utrzymywać, testować i obsługiwać. Każda faza jest punktem awarii. Błędy przesyłania do S3 wymagają logiki ponownej próby. W przypadku niepowodzeń zadań Textract należy odróżnić błędy przejściowe od trwałych. Limity czasu na pobieranie danych wymagają obsługi limitów czasu niezależnej od anulowania. Paginacja wyników wymaga gromadzenia stanu w wielu wywołaniach API. Błędy czyszczenia S3 wymagają powiadomienia, ponieważ osierocone obiekty generują koszty. Zespoły, które wdrożyły ten proces do produkcji, zazwyczaj poświęcają więcej czasu na jego utrzymanie niż na jego stworzenie. Odpowiednik IronOCR— input.LoadPdf(path), a następnie ocr.Read(input) — eliminuje wszystkie pięć faz i związane z nimi tryby awarii.

Gdy środowiska wdrożeniowe nie mają dostępu do Internetu

KonteneryDockerdziałające w izolowanych segmentach sieci, serwery lokalne bez dostępu do Internetu, środowiska badawcze odizolowane oraz systemy przemysłowe z rygorystycznymi kontrolami sieciowymi mają jedną wspólną cechę:AWS Textractnie jest dostępny.IronOCR instaluje się jako standardowy pakiet NuGet i po instalacji działa bez żadnych połączeń sieciowych. Zespoły korzystające z aplikacji .NET w tych środowiskach nie mają dostępu do opcji Textract i potrzebują biblioteki, która działa lokalnie. Przewodnik wdrażania Docker oraz przewodnik wdrażania Linux obejmują konkretną konfigurację dla środowisk kontenerowych.

Kiedy ograniczanie przepustowości zakłóca przepływ pracy w trybie wsadowym

Domyślny limit TPS dla StartDocumentTextDetection wynosi 5 żądań na sekundę. Synchroniczne wywołania DetectDocumentText są również ograniczone szybkością. Zadania wsadowe przetwarzające setki lub tysiące dokumentów muszą implementować ograniczenie SemaphoreSlim, wykładnicze wycofanie przy ProvisionedThroughputExceededException i zegary odnawiania szybkości. AWS obsługuje wnioski o zwiększenie limitu TPS, ale wymagają one uzasadnienia, weryfikacji i nie są gwarantowane.IronOCR przetwarza dane tak szybko, jak pozwala na to lokalny procesor — 32-rdzeniowy serwer przetwarza jednocześnie 32 dokumenty bez konfiguracji ograniczania przepustowości ani negocjacji poziomu usługi.

Typowe kwestie związane z migracją

Zastąpienie wykresu blokowego bezpośrednimi kolekcjami

Textract przedstawia wszystkie wyniki jako płaską strukturę List<Block>, gdzie linie, słowa, komórki, tabele i pary klucz-wartość są rozróżniane przez BlockType i powiązane przez tablice identyfikatorów relacji.IronOCR udostępnia bezpośrednie kolekcje danych wpisanych.

// Textract: filter flat block list by type
var lines = response.Blocks.Where(b => b.BlockType == BlockType.LINE);
var words = response.Blocks.Where(b => b.BlockType == BlockType.WORD);

// IronOCR: direct access to typed collections
var result = ocr.Read(imagePath);
var lines = result.Lines;   // IEnumerable<OcrResult.OcrResultLine>
var words = result.Words;   // IEnumerable<OcrResult.OcrResultWord>
foreach (var word in result.Words)
    Console.WriteLine($"'{word.Text}' at ({word.X},{word.Y}) confidence {word.Confidence}%");
// Textract: filter flat block list by type
var lines = response.Blocks.Where(b => b.BlockType == BlockType.LINE);
var words = response.Blocks.Where(b => b.BlockType == BlockType.WORD);

// IronOCR: direct access to typed collections
var result = ocr.Read(imagePath);
var lines = result.Lines;   // IEnumerable<OcrResult.OcrResultLine>
var words = result.Words;   // IEnumerable<OcrResult.OcrResultWord>
foreach (var word in result.Words)
    Console.WriteLine($"'{word.Text}' at ({word.X},{word.Y}) confidence {word.Confidence}%");
' Textract: filter flat block list by type
Dim lines = response.Blocks.Where(Function(b) b.BlockType = BlockType.LINE)
Dim words = response.Blocks.Where(Function(b) b.BlockType = BlockType.WORD)

' IronOCR: direct access to typed collections
Dim result = ocr.Read(imagePath)
Dim lines = result.Lines   ' IEnumerable(Of OcrResult.OcrResultLine)
Dim words = result.Words   ' IEnumerable(Of OcrResult.OcrResultWord)
For Each word In result.Words
    Console.WriteLine($"'{word.Text}' at ({word.X},{word.Y}) confidence {word.Confidence}%")
Next
$vbLabelText   $csharpLabel

Przewodnik po strukturach wyników obejmuje result.Pages, result.Paragraphs, result.Lines, result.Words oraz dostęp do współrzędnych do budowania przetwarzania dokumentów świadomego układu.

Zastąpienie przetwarzania plików PDF w S3-Staged przez Direct LoadPdf

Każdy kod Textract, który przesyła dane do S3 przed rozpoczęciem zadania wykrywania, można zastąpić bezpośrednim wczytaniem pliku PDF. Bez zasobnika przejściowego, bez synchronizacji przesyłania, bez logiki czyszczenia.

// Textract: upload to S3 → start job → poll → paginate → cleanup (50+ lines)
//IronOCR equivalent:
public string ProcessPdf(string pdfPath)
{
    var ocr = new IronTesseract();
    using var input = new OcrInput();
    input.LoadPdf(pdfPath);
    return ocr.Read(input).Text;
}

// Specific page ranges (no Textract equivalent without async job per range)
public string ProcessPdfPages(string pdfPath, int startPage, int endPage)
{
    var ocr = new IronTesseract();
    using var input = new OcrInput();
    input.LoadPdfPages(pdfPath, startPage, endPage);
    return ocr.Read(input).Text;
}
// Textract: upload to S3 → start job → poll → paginate → cleanup (50+ lines)
//IronOCR equivalent:
public string ProcessPdf(string pdfPath)
{
    var ocr = new IronTesseract();
    using var input = new OcrInput();
    input.LoadPdf(pdfPath);
    return ocr.Read(input).Text;
}

// Specific page ranges (no Textract equivalent without async job per range)
public string ProcessPdfPages(string pdfPath, int startPage, int endPage)
{
    var ocr = new IronTesseract();
    using var input = new OcrInput();
    input.LoadPdfPages(pdfPath, startPage, endPage);
    return ocr.Read(input).Text;
}
Imports IronOcr

Public Class PdfProcessor
    ' Textract: upload to S3 → start job → poll → paginate → cleanup (50+ lines)
    ' IronOCR equivalent:
    Public Function ProcessPdf(pdfPath As String) As String
        Dim ocr As New IronTesseract()
        Using input As New OcrInput()
            input.LoadPdf(pdfPath)
            Return ocr.Read(input).Text
        End Using
    End Function

    ' Specific page ranges (no Textract equivalent without async job per range)
    Public Function ProcessPdfPages(pdfPath As String, startPage As Integer, endPage As Integer) As String
        Dim ocr As New IronTesseract()
        Using input As New OcrInput()
            input.LoadPdfPages(pdfPath, startPage, endPage)
            Return ocr.Read(input).Text
        End Using
    End Function
End Class
$vbLabelText   $csharpLabel

Dodanie przetwarzania wstępnego dla dokumentów, które wygenerowały niski poziom pewności w Textract

Przetwarzanie wstępne w Textract jest wewnętrzne i nie można go konfigurować. Gdy zeskanowany dokument daje słabe wyniki, jedyne opcje to ponowna próba lub zaakceptowanie wyników o niskim poziomie pewności.IronOCR udostępnia bezpośrednio potok przetwarzania wstępnego.

// For documents that returned low-confidence results from Textract
using var input = new OcrInput();
input.LoadImage("low-quality-scan.jpg");

input.Deskew();              // Fix rotation from scanner misalignment
input.DeNoise();             // Remove scanner noise artifacts
input.Contrast();            // Boost faint text
input.EnhanceResolution(300); // Scale to optimal OCR resolution

var result = new IronTesseract().Read(input);
Console.WriteLine($"Confidence: {result.Confidence}%");
// For documents that returned low-confidence results from Textract
using var input = new OcrInput();
input.LoadImage("low-quality-scan.jpg");

input.Deskew();              // Fix rotation from scanner misalignment
input.DeNoise();             // Remove scanner noise artifacts
input.Contrast();            // Boost faint text
input.EnhanceResolution(300); // Scale to optimal OCR resolution

var result = new IronTesseract().Read(input);
Console.WriteLine($"Confidence: {result.Confidence}%");
Imports IronOcr

Dim input As New OcrInput()
input.LoadImage("low-quality-scan.jpg")

input.Deskew()              ' Fix rotation from scanner misalignment
input.DeNoise()             ' Remove scanner noise artifacts
input.Contrast()            ' Boost faint text
input.EnhanceResolution(300) ' Scale to optimal OCR resolution

Dim result = New IronTesseract().Read(input)
Console.WriteLine($"Confidence: {result.Confidence}%")
$vbLabelText   $csharpLabel

Przewodnik po korekcji jakości obrazu i samouczek o filtrach obrazów dokumentują pełny potok wstępnego przetwarzania i kombinacje, które najlepiej sprawdzają się dla określonych typów dokumentów. W celu interpretacji wyników zaufania i dostępu do wartości zaufania dla poszczególnych elementów, przewodnik po wynikach zaufania obejmuje właściwość result.Confidence i wartości zaufania dla poszczególnych słów.

Obsługa zmiany wzorca z asynchronicznego na synchroniczny

Istniejący kod Textract jest koniecznie async Task<t> wszędzie, ponieważ SDK jest tylko asynchroniczny. Operacje IronOCRsą synchroniczne. Dla kodu aplikacji, który już ma asynchroniczny łańcuch wywołań, obwiąż wywołanie IronOCR w Task.Run, aby zachować asynchroniczną granicę.

// Preserves async call site for minimal refactoring
public async Task<string> ExtractTextAsync(string path)
{
    return await Task.Run(() => new IronTesseract().Read(path).Text);
}
// Preserves async call site for minimal refactoring
public async Task<string> ExtractTextAsync(string path)
{
    return await Task.Run(() => new IronTesseract().Read(path).Text);
}
Imports System.Threading.Tasks

' Preserves async call site for minimal refactoring
Public Async Function ExtractTextAsync(path As String) As Task(Of String)
    Return Await Task.Run(Function() New IronTesseract().Read(path).Text)
End Function
$vbLabelText   $csharpLabel

Jest to wygodna nakładka, a nie wymóg. W przypadku przetwarzania po stronie serwera, gdzie kod wywołujący znajduje się już w wątku w tle, preferowane jest bezpośrednie wywołanie synchroniczne.

Dodatkowe możliwości IronOCR

Oprócz powyższych punktów porównawczych,IronOCR oferuje funkcje, które nie mają odpowiednika w AWS Textract:

Zgodność z platformą .NET i gotowość na przyszłość

IronOCR jest przeznaczony dla platform .NET 8 i .NET 9, z aktywną kompatybilnością dla projektów .NET Standard 2.0 oraz .NET Framework 4.6.2 do 4.8. Biblioteka zawiera natywne pliki binarne dla systemów Windows x64, Windows x86,Linuxx64 i macOS w jednym pakiecie NuGet — bez konieczności zmiany identyfikatora środowiska uruchomieniowego ani odwołań do pakietów specyficznych dla danej platformy. Pakiet AWSSDK.TextractAWS Textractobsługuje te same nowoczesne cele .NET, ale model wdrażania zawiera całą strukturę zależności AWS SDK, infrastrukturę poświadczeń IAM i ograniczenia architektoniczne udokumentowane w całym tym artykule.IronOCR jest aktywnie rozwijany, a regularne wydania śledzą aktualizacje silnika Tesseract 5 oraz postępy środowiska uruchomieniowego .NET, w tym kompatybilność z .NET 10 po jego wydaniu.

Wnioski

AWS Textract i IronOCR rozwiązują ten sam problem — wyodrębnianie tekstu z dokumentów w aplikacjach .NET — przy zasadniczo niekompatybilnych założeniach architektonicznych. Textract zakłada, że dokumenty mogą opuszczać Twoją sieć, że koszty usług w chmurze rosną liniowo wraz z wolumenem oraz że wielostronicowe pliki PDF uzasadniają pięciofazowy asynchroniczny proces z wykorzystaniem S3.IronOCR zakłada, że dokumenty pozostają tam, gdzie są przetwarzane, że koszty licencji powinny być niezależne od wielkości, a przetwarzanie plików PDF powinno wymagać tych samych trzech linii kodu, co przetwarzanie obrazów.

Aritmetyka kosztów to najjasniejsza linia podziału. Przy niskich wolumenach, opłaty na stronę w Textract są do opanowania. W miarę wzrostu wolumenu, roczne koszty kumulują się znacząco. Przy dużych objętościach stron z wyodrębnianiem tabel, wieloletnie koszty Textract mogą zdecydowanie przekroczyć nawet nieograniczoną licencjęIronOCR w $5,999. Początkowe rachunki się utrzymują: model na stronę szybko się sumuje i nigdy nie przestaje.

Suwerenność danych stanowi drugie ograniczenie strukturalne. W przypadku zadań związanych z opieką zdrowotną, prawem, finansami i administracją publiczną kwestia miejsca przetwarzania dokumentów nie jest kwestią preferencji — jest to wymóg zgodności z przepisami.IronOCR przetwarza dane lokalnie z założenia, a nie z powodu konfiguracji. Nie ma "trybu lokalnego", który można by włączyć; Jedynym trybem jest przetwarzanie lokalne. To sprawia, że odpowiedź dotycząca zgodności jest prosta: dokumenty pozostają w Twojej infrastrukturze, ponieważ nie ma gdzie indziej ich umieścić.

Dla zespołów oceniających OCR na prawdziwą skalę lub działających w środowiskach, w których dane dokumentów nie mogą opuszczać wewnętrznej infrastruktury, dokumentacja IronOCR zawiera kompletną Dokumentację API, przewodniki wdrożeniowe dla Docker, AWS,AzureiLinuxoraz samouczki obejmujące pełen zakres zastosowań OCR, od podstawowego odczytu obrazów po generowanie przeszukiwalnych plików PDF i ekstrakcję wielojęzyczną.

Zwróć uwagęAWS Textract i Tesseract są zarejestrowanymi znakami towarowymi ich właścicieli. Ta strona nie jest powiązana, zatwierdzona ani sponsorowana przez Amazon Web Services lub Google. Wszystkie nazwy produktów, logo 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.

Często Zadawane Pytania

Czym jest Amazon Textract?

Amazon Textract to rozwiązanie OCR wykorzystywane przez programistów i przedsiębiorstwa do wyodrębniania tekstu z obrazów i dokumentów. Jest to jedna z kilku opcji OCR ocenianych obok IronOCR for .NET pod kątem tworzenia aplikacji .NET.

Jak IronOCR wypada w porównaniu z Amazon Textract dla programistów .NET?

IronOCR to natywna dla NuGet biblioteka OCR dla platformy .NET, wykorzystująca IronTesseract jako główny silnik. W porównaniu z Amazon Textract oferuje prostsze wdrożenie (brak instalatorów SDK), ryczałtowe ceny oraz przejrzysty interfejs API w języku C# bez interoperacyjności COM i zależności od chmury.

Czy IronOCR jest łatwiejszy w konfiguracji niż Amazon Textract?

IronOCR instaluje się za pomocą jednego pakietu NuGet. Nie ma żadnych instalatorów SDK, plików licencyjnych do skopiowania, komponentów COM do zarejestrowania ani oddzielnych plików binarnych środowiska uruchomieniowego, którymi trzeba by zarządzać. Cały silnik OCR jest zawarty w pakiecie.

Jakie różnice w dokładności występują między Amazon Textract a IronOCR?

IronOCR osiąga wysoką dokładność rozpoznawania standardowych dokumentów biznesowych, faktur, paragonów i zeskanowanych formularzy. W przypadku dokumentów o bardzo niskiej jakości lub rzadkich skryptów dokładność zależy od jakości źródła. IronOCR zawiera filtry wstępnego przetwarzania obrazu, które poprawiają rozpoznawanie danych wejściowych o niskiej jakości.

Czy IronOCR obsługuje wyodrębnianie tekstu z plików PDF?

Tak. IronOCR wyodrębnia tekst zarówno z natywnych plików PDF, jak i ze skanowanych obrazów PDF za pomocą jednego wywołania. Obsługuje również wielostronicowe pliki TIFF, obrazy i strumienie. W przypadku skanowanych plików PDF OCR jest stosowany strona po stronie, z obiektami wynikowymi dla każdej strony.

Jak wygląda licencjonowanie Amazon Textract w porównaniu z IronOCR?

IronOCR korzysta z licencji wieczystej o stałej stawce, bez opłat za stronę lub skan. Organizacje przetwarzające duże ilości dokumentów płacą ten sam koszt licencji niezależnie od ilości. Szczegóły i ceny hurtowe znajdują się na stronie licencji IronOCR.

Jakie języki obsługuje IronOCR?

IronOCR obsługuje 127 języków za pośrednictwem oddzielnych pakietów językowych NuGet. Dodanie języka wymaga wykonania pojedynczego polecenia „dotnet add package IronOcr.Languages.{Language}”. Nie jest wymagane ręczne umieszczanie plików ani konfiguracja ścieżek.

Jak zainstalować IronOCR w projekcie .NET?

Instalacja przez NuGet: „Install-Package IronOcr” w konsoli menedżera pakietów lub „dotnet add package IronOcr” w CLI. Dodatkowe pakiety językowe instaluje się w ten sam sposób. Nie jest wymagany natywny instalator SDK.

Czy IronOCR nadaje się do wdrożeń w Dockerze i kontenerach, w przeciwieństwie do Amazon Textract?

Tak. IronOCR działa w kontenerach Docker za pośrednictwem pakietu NuGet. Klucz licencyjny jest ustawiany za pomocą zmiennej środowiskowej. Silnik OCR nie wymaga żadnych plików licencyjnych, ścieżek SDK ani montowania woluminów.

Czy przed zakupem mogę wypróbować IronOCR w porównaniu z Amazon Textract?

Tak. Tryb próbny IronOCR przetwarza dokumenty i zwraca wyniki OCR z nakładką znaku wodnego na wyjściu. Przed zakupem licencji można sprawdzić dokładność na własnych dokumentach.

Czy IronOCR obsługuje odczytywanie kodów kreskowych oprócz wyodrębniania tekstu?

IronOCR koncentruje się na wyodrębnianiu tekstu i OCR. Do odczytu kodów kreskowych firma Iron Software udostępnia bibliotekę IronBarcode jako dodatek. Obie biblioteki są dostępne osobno lub w ramach pakietu Iron Suite.

Czy łatwo jest przejść z Amazon Textract na IronOCR?

Migracja z Amazon Textract do IronOCR zazwyczaj polega na zastąpieniu sekwencji inicjalizacyjnych instancjonowaniem IronTesseract, usunięciu zarządzania cyklem życia COM oraz aktualizacji wywołań API. Większość migracji znacznie zmniejsza złożoność kodu.

Kannaopat Udonpant
Inżynier oprogramowania
Zanim stał się inżynierem oprogramowania, Kannapat ukończył doktorat z zasobów środowiskowych na Uniwersytecie Hokkaido w Japonii. W czasie studiowania, Kannapat również został członkiem Laboratorium Robotyki Pojazdów, które jest częścią Wydziału Inżynierii Bioprodukcji. W 2022 roku wykorzystał swoje umiejętności w ...
Czytaj więcej

Zespół wsparcia Iron

Jesteśmy online 24 godziny, 5 dni w tygodniu.
Czat
E-mail
Zadzwoń do mnie