Asprise OCR SDK vs IronOCR: .NET OCR Library
Asprise OCR ships a Java library first and treats .NET as a secondary target — and that design decision surfaces in every layer of the product, from documentation written in Java examples to a native binary deployment model that requires platform-specific DLLs (aocr.dll, aocr_x64.dll, libaocr.so, libaocr.dylib) on every machine that runs the software. The threading model compounds this: LITE and STANDARD licenses are contractually restricted to single-threaded, single-process execution, which means every ASP.NET Core endpoint, Windows Service, or Azure Function that calls Asprise on those tiers violates the license agreement. For .NET teams building production systems, these are not theoretical concerns — they are deployment blockers that force either expensive ENTERPRISE licensing or a library swap before reaching production.
Understanding Asprise OCR
Asprise OCR is a commercial OCR product from Asprise Inc. The product originated as a Java OCR engine. .NET support arrived later via native library wrappers that bridge managed C# code to the underlying unmanaged OCR binaries. This bridge architecture is the defining characteristic of the library for .NET developers.
Key architectural characteristics:
- Java-first design: All primary documentation, sample code, and SDK examples are written for Java. .NET developers translate from Java mentally or rely on sparse secondary documentation.
- Native binary dependency: Platform-specific unmanaged DLLs must be present in the deployment directory or system path. The correct binary must match the process architecture — 32-bit processes require
aocr.dll, 64-bit processes requireaocr_x64.dll. - Manual engine lifecycle: The library exposes a C-style initialization pattern (
Ocr.SetUp(),ocr.StartEngine(),ocr.StopEngine()) inherited from its Java origins. There is noIDisposableimplementation. ForgettingStopEngine()leaks native memory. - License-tier thread restrictions: LITE (~$299) and STANDARD (~$699) tiers permit only single-threaded, single-process execution. Multi-threading requires ENTERPRISE, which requires contacting sales.
- Error codes, not exceptions: Recognition failures surface as null returns or strings prefixed with
"ERROR:", consistent with C/Java error-code conventions rather than .NET exception patterns. - 20+ OCR languages: Substantially fewer than alternatives built for the .NET ecosystem.
The Engine Lifecycle Problem
Every Asprise OCR call requires explicit engine management. The pattern is four mandatory steps: static global setup, instance creation, engine start with a language string, and engine stop after completion. Skipping engine stop leaks native resources because the garbage collector cannot release unmanaged memory:
// Asprise: four required steps before reading a single image
Ocr.SetUp(); // Static global init
Ocr ocr = new Ocr();
try
{
ocr.StartEngine("eng", Ocr.SPEED_FAST); // Allocates native engine
string text = ocr.Recognize(
imagePath,
Ocr.RECOGNIZE_TYPE_TEXT,
Ocr.OUTPUT_FORMAT_PLAINTEXT);
return text;
}
finally
{
ocr.StopEngine(); // Must call — no IDisposable fallback
}
// Asprise: four required steps before reading a single image
Ocr.SetUp(); // Static global init
Ocr ocr = new Ocr();
try
{
ocr.StartEngine("eng", Ocr.SPEED_FAST); // Allocates native engine
string text = ocr.Recognize(
imagePath,
Ocr.RECOGNIZE_TYPE_TEXT,
Ocr.OUTPUT_FORMAT_PLAINTEXT);
return text;
}
finally
{
ocr.StopEngine(); // Must call — no IDisposable fallback
}
' Asprise: four required steps before reading a single image
Ocr.SetUp() ' Static global init
Dim ocr As New Ocr()
Try
ocr.StartEngine("eng", Ocr.SPEED_FAST) ' Allocates native engine
Dim text As String = ocr.Recognize( _
imagePath, _
Ocr.RECOGNIZE_TYPE_TEXT, _
Ocr.OUTPUT_FORMAT_PLAINTEXT)
Return text
Finally
ocr.StopEngine() ' Must call — no IDisposable fallback
End Try
This pattern fails silently in three common situations: an unhandled exception before StopEngine() is called, a refactored code path that skips cleanup, and concurrent use on LITE/STANDARD where the license prohibits the threading that would even allow parallelism. The finally block mitigates the first issue, but the license restriction makes the pattern moot for server workloads anyway.
Understanding IronOCR
IronOCR is a commercial OCR library built from the ground up for .NET. It wraps an optimized Tesseract 5 engine with automatic preprocessing, native PDF support, and a managed API that follows standard .NET conventions throughout.
Key characteristics:
- Single NuGet package:
dotnet add package IronOcrinstalls everything — no native binary management, no tessdata folders, no platform-specific configuration. IDisposableresource management:OcrInputimplementsIDisposable. Theusingstatement handles cleanup automatically.- Thread-safe on all license tiers: No artificial threading restrictions.
IronTesseractinstances are safe to use in parallel on the $999 Lite license. - Automatic preprocessing: Built-in
Deskew(),DeNoise(),Contrast(),Binarize(), andEnhanceResolution()methods remove the need for external image processing libraries. - Native PDF input: Pass a PDF path directly — no external rendering library required to convert pages to images first.
- 125+ languages: Available as separate NuGet packages (
IronOcr.Languages.French, etc.), installed only when needed. - Searchable PDF output:
result.SaveAsSearchablePdf()generates PDF/A compliant output from any OCR result. - Structured data access: Results expose word-level, line-level, and paragraph-level text with pixel coordinates and per-word confidence scores.
Feature Comparison
| Feature | Asprise OCR | IronOCR |
|---|---|---|
| Primary platform | Java | .NET |
| NuGet deployment | Wrapper + native DLLs | Single package, no extras |
| Threading (all tiers) | ENTERPRISE only | All tiers |
| Server/web application use | ENTERPRISE only | All tiers |
| Native PDF input | No | Yes |
| Built-in preprocessing | No | Yes |
| OCR languages | 20+ | 125+ |
| Searchable PDF output | No | Yes |
Detailed Feature Comparison
| Feature | Asprise OCR | IronOCR |
|---|---|---|
| Architecture | ||
| Design origin | Java, .NET secondary | .NET native |
| API style | C-style with integer constants | Fluent C# |
IDisposable / using pattern |
Not implemented | Yes (OcrInput) |
| Error handling | Null / error-string returns | .NET exceptions |
| Exception propagation from native | Interop gaps | Managed exceptions |
| Threading and Server Use | ||
| Multi-threading — LITE tier | Prohibited | Permitted |
| Multi-threading — STANDARD tier | Prohibited | Permitted |
| Multi-threading — ENTERPRISE/upper tier | Permitted | Permitted |
| ASP.NET Core Web API | Requires ENTERPRISE | Any tier |
| Azure Functions / AWS Lambda | Requires ENTERPRISE | Any tier |
| Parallel.ForEach batch | Requires ENTERPRISE | Any tier |
| Input Support | ||
| Image files (JPG, PNG, TIFF) | Yes | Yes |
| Native PDF input | No (external lib required) | Yes |
| Password-protected PDF | No | Yes |
| Byte array / Stream input | Limited | Yes |
| Multi-page TIFF | Limited | Yes |
| Preprocessing | ||
| Deskew | Manual / external | Built-in |
| Denoise | Manual / external | Built-in |
| Contrast enhancement | Manual / external | Built-in |
| Binarization | Manual / external | Built-in |
| Resolution scaling (DPI) | Manual / external | Built-in |
| Output | ||
| Plain text | Yes | Yes |
| Searchable PDF output | No | Yes |
| Word coordinates | Limited | Yes |
| Per-word confidence scores | No | Yes |
| hOCR export | No | Yes |
| Languages | ||
| Language count | 20+ | 125+ |
| Language installation | Bundled | NuGet packages |
| Strongly-typed language enum | No (string codes) | Yes (OcrLanguage) |
| Deployment | ||
| Native binary required | Yes (platform-specific DLL) | No |
| Tessdata folder management | No | No |
| Docker | Manual binary config | Works out of box |
| Linux | Requires libaocr.so |
NuGet handles |
| Pricing | ||
| Entry price | contact Asprise for pricing (LITE, single-thread only) | $999 (Lite, all features) |
| Server use entry price | ENTERPRISE (contact sales) | $999 (Lite) |
Native .NET vs Java Bridge Architecture
The fundamental question for .NET teams is not which library has more features on paper — it is which one behaves as a first-class .NET citizen in the deployment and operational environments they actually use.
Asprise Approach
Asprise communicates between managed .NET code and its unmanaged OCR engine via P/Invoke marshaling. The asprise-vs-ironocr-examples.cs source shows the underlying mechanism:
// Asprise interop layer — bridging managed C# to native OCR engine
[DllImport("aocr.dll")]
private static extern IntPtr OCR(string imagePath, int type);
public string ExtractText(string imagePath)
{
// P/Invoke call into unmanaged DLL
IntPtr result = OCR(imagePath, 0);
return Marshal.PtrToStringAnsi(result); // Manual string marshal
}
// Asprise interop layer — bridging managed C# to native OCR engine
[DllImport("aocr.dll")]
private static extern IntPtr OCR(string imagePath, int type);
public string ExtractText(string imagePath)
{
// P/Invoke call into unmanaged DLL
IntPtr result = OCR(imagePath, 0);
return Marshal.PtrToStringAnsi(result); // Manual string marshal
}
Imports System.Runtime.InteropServices
' Asprise interop layer — bridging managed VB.NET to native OCR engine
Private Class OCRInterop
<DllImport("aocr.dll")>
Private Shared Function OCR(imagePath As String, type As Integer) As IntPtr
End Function
Public Function ExtractText(imagePath As String) As String
' P/Invoke call into unmanaged DLL
Dim result As IntPtr = OCR(imagePath, 0)
Return Marshal.PtrToStringAnsi(result) ' Manual string marshal
End Function
End Class
At the higher-level API, developers call into the same bridge through a class wrapper, but the deployment requirement does not change: every target machine needs the correct native binary, in the correct path, matching the correct process architecture. A 64-bit deployment that ships with aocr.dll instead of aocr_x64.dll throws a BadImageFormatException at runtime. A Linux Docker container without libaocr.so in LD_LIBRARY_PATH throws DllNotFoundException. Neither error is caught at build time.
IronOCR Approach
IronOCR installs as a single NuGet reference. The package handles all native dependencies internally through NuGet's platform-specific package selection mechanism:
// Installation — one command, all platforms
// dotnet add package IronOcr
// License setup
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
// Basic OCR — no native binary setup, no tessdata, no config files
var text = new IronTesseract().Read("document.jpg").Text;
// Installation — one command, all platforms
// dotnet add package IronOcr
// License setup
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
// Basic OCR — no native binary setup, no tessdata, no config files
var text = new IronTesseract().Read("document.jpg").Text;
Imports IronOcr
' Installation — one command, all platforms
' dotnet add package IronOcr
' License setup
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"
' Basic OCR — no native binary setup, no tessdata, no config files
Dim text As String = New IronTesseract().Read("document.jpg").Text
The using statement on OcrInput replaces manual engine lifecycle calls. There is no StartEngine() to call and no StopEngine() to forget. The garbage collector and IDisposable pattern handle cleanup correctly in exception scenarios without requiring try/finally scaffolding around every OCR call.
For detailed setup guidance, see the IronTesseract setup guide.
Threading Model
The threading restriction is the single most consequential difference between Asprise and alternatives for .NET server developers. It is not a performance concern — it is a license compliance issue.
Asprise Approach
LITE and STANDARD licenses explicitly prohibit multi-threaded and multi-process execution. Any code that calls Asprise from more than one thread simultaneously violates the license agreement on those tiers. ASP.NET Core processes requests on a thread pool by default. That makes every standard Web API controller that calls Asprise a license violation on LITE/STANDARD:
// ASPRISE LITE/STANDARD — violates license in ASP.NET Core context
// Web server thread pool = multiple concurrent threads = prohibited
[ApiController]
public class OcrController : ControllerBase
{
[HttpPost("extract")]
public IActionResult ExtractText(IFormFile file)
{
// Two concurrent requests = two threads = license violation
var ocr = new Ocr();
ocr.StartEngine("eng", Ocr.SPEED_FAST);
var text = ocr.Recognize(tempPath, Ocr.RECOGNIZE_TYPE_TEXT, Ocr.OUTPUT_FORMAT_PLAINTEXT);
ocr.StopEngine();
return Ok(text);
}
}
// ASPRISE LITE/STANDARD — violates license in ASP.NET Core context
// Web server thread pool = multiple concurrent threads = prohibited
[ApiController]
public class OcrController : ControllerBase
{
[HttpPost("extract")]
public IActionResult ExtractText(IFormFile file)
{
// Two concurrent requests = two threads = license violation
var ocr = new Ocr();
ocr.StartEngine("eng", Ocr.SPEED_FAST);
var text = ocr.Recognize(tempPath, Ocr.RECOGNIZE_TYPE_TEXT, Ocr.OUTPUT_FORMAT_PLAINTEXT);
ocr.StopEngine();
return Ok(text);
}
}
Imports Microsoft.AspNetCore.Mvc
' ASPRISE LITE/STANDARD — violates license in ASP.NET Core context
' Web server thread pool = multiple concurrent threads = prohibited
<ApiController>
Public Class OcrController
Inherits ControllerBase
<HttpPost("extract")>
Public Function ExtractText(file As IFormFile) As IActionResult
' Two concurrent requests = two threads = license violation
Dim ocr As New Ocr()
ocr.StartEngine("eng", Ocr.SPEED_FAST)
Dim text As String = ocr.Recognize(tempPath, Ocr.RECOGNIZE_TYPE_TEXT, Ocr.OUTPUT_FORMAT_PLAINTEXT)
ocr.StopEngine()
Return Ok(text)
End Function
End Class
Batch processing on LITE/STANDARD is forced sequential regardless of available CPU cores:
// ASPRISE LITE/STANDARD — sequential only (100 docs at 2 sec each = 3+ minutes)
Ocr.SetUp();
Ocr ocr = new Ocr();
try
{
ocr.StartEngine("eng", Ocr.SPEED_FAST);
foreach (var path in imagePaths) // Cannot use Parallel.ForEach — license violation
{
string text = ocr.Recognize(path, Ocr.RECOGNIZE_TYPE_TEXT, Ocr.OUTPUT_FORMAT_PLAINTEXT);
results.Add(text);
}
}
finally
{
ocr.StopEngine();
}
// ASPRISE LITE/STANDARD — sequential only (100 docs at 2 sec each = 3+ minutes)
Ocr.SetUp();
Ocr ocr = new Ocr();
try
{
ocr.StartEngine("eng", Ocr.SPEED_FAST);
foreach (var path in imagePaths) // Cannot use Parallel.ForEach — license violation
{
string text = ocr.Recognize(path, Ocr.RECOGNIZE_TYPE_TEXT, Ocr.OUTPUT_FORMAT_PLAINTEXT);
results.Add(text);
}
}
finally
{
ocr.StopEngine();
}
' ASPRISE LITE/STANDARD — sequential only (100 docs at 2 sec each = 3+ minutes)
Ocr.SetUp()
Dim ocr As New Ocr()
Try
ocr.StartEngine("eng", Ocr.SPEED_FAST)
For Each path In imagePaths ' Cannot use Parallel.ForEach — license violation
Dim text As String = ocr.Recognize(path, Ocr.RECOGNIZE_TYPE_TEXT, Ocr.OUTPUT_FORMAT_PLAINTEXT)
results.Add(text)
Next
Finally
ocr.StopEngine()
End Try
ENTERPRISE removes the thread restriction, but ENTERPRISE requires contacting Asprise sales with no published price.
IronOCR Approach
IronTesseract is thread-safe and carries no threading restrictions on any license tier. Parallel batch processing on a $999 Lite license is fully supported:
// IronOCR — parallel batch on any license tier
// 100 docs at 2 sec each, 8 cores = ~25 seconds vs 200 seconds sequential
var results = imagePaths
.AsParallel()
.Select(path => new IronTesseract().Read(path).Text)
.ToList();
// IronOCR — parallel batch on any license tier
// 100 docs at 2 sec each, 8 cores = ~25 seconds vs 200 seconds sequential
var results = imagePaths
.AsParallel()
.Select(path => new IronTesseract().Read(path).Text)
.ToList();
Imports System.Linq
' IronOCR — parallel batch on any license tier
' 100 docs at 2 sec each, 8 cores = ~25 seconds vs 200 seconds sequential
Dim results = imagePaths _
.AsParallel() _
.Select(Function(path) (New IronTesseract()).Read(path).Text) _
.ToList()
ASP.NET Core controllers work without any special configuration:
// IronOCR — concurrent requests on any license tier
[ApiController]
public class OcrController : ControllerBase
{
[HttpPost("extract")]
public IActionResult ExtractText(IFormFile file)
{
// Thread-safe on Lite, Plus, Professional, Unlimited — all tiers
var text = new IronTesseract().Read(tempPath).Text;
return Ok(text);
}
}
// IronOCR — concurrent requests on any license tier
[ApiController]
public class OcrController : ControllerBase
{
[HttpPost("extract")]
public IActionResult ExtractText(IFormFile file)
{
// Thread-safe on Lite, Plus, Professional, Unlimited — all tiers
var text = new IronTesseract().Read(tempPath).Text;
return Ok(text);
}
}
Imports Microsoft.AspNetCore.Mvc
<ApiController>
Public Class OcrController
Inherits ControllerBase
<HttpPost("extract")>
Public Function ExtractText(file As IFormFile) As IActionResult
' Thread-safe on Lite, Plus, Professional, Unlimited — all tiers
Dim text = New IronTesseract().Read(tempPath).Text
Return Ok(text)
End Function
End Class
See the multithreading example for parallel throughput patterns in batch workloads.
Image Preprocessing
Asprise passes images to its native engine without preprocessing. Low-quality scans — skewed pages, noise artifacts, low contrast — degrade OCR accuracy directly because there is no preprocessing layer to correct image defects before recognition runs.
Asprise Approach
Preprocessing requires an external image library. A developer working with Asprise adds a dependency like ImageMagick, SkiaSharp, or System.Drawing, runs the preprocessing operations manually, saves the processed image to a temporary file, and then passes that file to Asprise:
// Asprise preprocessing: external dependency required
// 1. Load with external library
// 2. Apply corrections (deskew, denoise, contrast) with external library
// 3. Save to temp file
// 4. Pass temp file to Asprise
var ocr = new Ocr();
ocr.StartEngine("eng", Ocr.SPEED_FAST);
// preprocessedImagePath comes from your external preprocessing pipeline
string text = ocr.Recognize(preprocessedImagePath, Ocr.RECOGNIZE_TYPE_TEXT, Ocr.OUTPUT_FORMAT_PLAINTEXT);
ocr.StopEngine();
// Asprise preprocessing: external dependency required
// 1. Load with external library
// 2. Apply corrections (deskew, denoise, contrast) with external library
// 3. Save to temp file
// 4. Pass temp file to Asprise
var ocr = new Ocr();
ocr.StartEngine("eng", Ocr.SPEED_FAST);
// preprocessedImagePath comes from your external preprocessing pipeline
string text = ocr.Recognize(preprocessedImagePath, Ocr.RECOGNIZE_TYPE_TEXT, Ocr.OUTPUT_FORMAT_PLAINTEXT);
ocr.StopEngine();
' Asprise preprocessing: external dependency required
' 1. Load with external library
' 2. Apply corrections (deskew, denoise, contrast) with external library
' 3. Save to temp file
' 4. Pass temp file to Asprise
Dim ocr As New Ocr()
ocr.StartEngine("eng", Ocr.SPEED_FAST)
' preprocessedImagePath comes from your external preprocessing pipeline
Dim text As String = ocr.Recognize(preprocessedImagePath, Ocr.RECOGNIZE_TYPE_TEXT, Ocr.OUTPUT_FORMAT_PLAINTEXT)
ocr.StopEngine()
This adds a build dependency, adds runtime overhead from the extra library, and requires the developer to understand image processing well enough to implement effective corrections.
IronOCR Approach
Preprocessing is built into OcrInput. The same pipeline that took 50-100 lines with an external library and careful parameter tuning becomes five method calls:
// IronOCR — preprocessing built in, no external dependencies
using var input = new OcrInput();
input.LoadImage("low-quality-scan.jpg");
input.Deskew(); // Correct page rotation
input.DeNoise(); // Remove scanner artifacts
input.Contrast(); // Improve text/background separation
input.Binarize(); // Convert to black/white for cleaner engine input
input.EnhanceResolution(300); // Scale to optimal DPI
var result = new IronTesseract().Read(input);
Console.WriteLine($"Confidence: {result.Confidence}%");
// IronOCR — preprocessing built in, no external dependencies
using var input = new OcrInput();
input.LoadImage("low-quality-scan.jpg");
input.Deskew(); // Correct page rotation
input.DeNoise(); // Remove scanner artifacts
input.Contrast(); // Improve text/background separation
input.Binarize(); // Convert to black/white for cleaner engine input
input.EnhanceResolution(300); // Scale to optimal DPI
var result = new IronTesseract().Read(input);
Console.WriteLine($"Confidence: {result.Confidence}%");
Imports IronOcr
' IronOCR — preprocessing built in, no external dependencies
Using input As New OcrInput()
input.LoadImage("low-quality-scan.jpg")
input.Deskew() ' Correct page rotation
input.DeNoise() ' Remove scanner artifacts
input.Contrast() ' Improve text/background separation
input.Binarize() ' Convert to black/white for cleaner engine input
input.EnhanceResolution(300) ' Scale to optimal DPI
Dim result = New IronTesseract().Read(input)
Console.WriteLine($"Confidence: {result.Confidence}%")
End Using
For scans where rotation is unpredictable, automatic deskew handles arbitrary angles without requiring the developer to detect or specify rotation values. The image quality correction guide covers the full filter set and when to apply each.
PDF Processing
PDF input is a frequent requirement in document processing pipelines. Asprise does not provide native PDF support — the library operates on image files. Processing a PDF with Asprise requires converting each page to an image first using an external library, then processing each image file individually.
Asprise Approach
// Asprise PDF workaround — external library required to render PDF pages
var images = ExternalPdfLibrary.RenderPages("invoice.pdf");
Ocr.SetUp();
Ocr ocr = new Ocr();
try
{
ocr.StartEngine("eng", Ocr.SPEED_FAST);
var allText = new System.Text.StringBuilder();
foreach (var imagePath in images)
{
string pageText = ocr.Recognize(imagePath, Ocr.RECOGNIZE_TYPE_TEXT, Ocr.OUTPUT_FORMAT_PLAINTEXT);
allText.Append(pageText);
}
return allText.ToString();
}
finally
{
ocr.StopEngine();
}
// Also: clean up temp image files
// Asprise PDF workaround — external library required to render PDF pages
var images = ExternalPdfLibrary.RenderPages("invoice.pdf");
Ocr.SetUp();
Ocr ocr = new Ocr();
try
{
ocr.StartEngine("eng", Ocr.SPEED_FAST);
var allText = new System.Text.StringBuilder();
foreach (var imagePath in images)
{
string pageText = ocr.Recognize(imagePath, Ocr.RECOGNIZE_TYPE_TEXT, Ocr.OUTPUT_FORMAT_PLAINTEXT);
allText.Append(pageText);
}
return allText.ToString();
}
finally
{
ocr.StopEngine();
}
// Also: clean up temp image files
Imports System.Text
' Asprise PDF workaround — external library required to render PDF pages
Dim images = ExternalPdfLibrary.RenderPages("invoice.pdf")
Ocr.SetUp()
Dim ocr As New Ocr()
Try
ocr.StartEngine("eng", Ocr.SPEED_FAST)
Dim allText As New StringBuilder()
For Each imagePath In images
Dim pageText As String = ocr.Recognize(imagePath, Ocr.RECOGNIZE_TYPE_TEXT, Ocr.OUTPUT_FORMAT_PLAINTEXT)
allText.Append(pageText)
Next
Return allText.ToString()
Finally
ocr.StopEngine()
End Try
' Also: clean up temp image files
This approach adds a PDF rendering dependency (typically iText, PDFSharp, or a commercial renderer), requires managing temporary files, and loses PDF metadata and structure that a native PDF reader would preserve. Password-protected PDFs require a third component.
IronOCR Approach
IronOCR reads PDFs directly. The OcrInput.LoadPdf() method handles rendering internally, including multi-page documents and password-protected files:
// IronOCR — native PDF input, no external rendering library
using var input = new OcrInput();
input.LoadPdf("invoice.pdf");
var result = new IronTesseract().Read(input);
Console.WriteLine(result.Text);
// Password-protected PDFs — same API, one parameter
using var secureInput = new OcrInput();
secureInput.LoadPdf("confidential.pdf", Password: "secret");
var secureResult = new IronTesseract().Read(secureInput);
// Generate searchable PDF from a scanned document
var scanResult = new IronTesseract().Read("scanned-contract.pdf");
scanResult.SaveAsSearchablePdf("searchable-contract.pdf");
// IronOCR — native PDF input, no external rendering library
using var input = new OcrInput();
input.LoadPdf("invoice.pdf");
var result = new IronTesseract().Read(input);
Console.WriteLine(result.Text);
// Password-protected PDFs — same API, one parameter
using var secureInput = new OcrInput();
secureInput.LoadPdf("confidential.pdf", Password: "secret");
var secureResult = new IronTesseract().Read(secureInput);
// Generate searchable PDF from a scanned document
var scanResult = new IronTesseract().Read("scanned-contract.pdf");
scanResult.SaveAsSearchablePdf("searchable-contract.pdf");
Imports IronOcr
' IronOCR — native PDF input, no external rendering library
Using input As New OcrInput()
input.LoadPdf("invoice.pdf")
Dim result = New IronTesseract().Read(input)
Console.WriteLine(result.Text)
End Using
' Password-protected PDFs — same API, one parameter
Using secureInput As New OcrInput()
secureInput.LoadPdf("confidential.pdf", Password:="secret")
Dim secureResult = New IronTesseract().Read(secureInput)
End Using
' Generate searchable PDF from a scanned document
Dim scanResult = New IronTesseract().Read("scanned-contract.pdf")
scanResult.SaveAsSearchablePdf("searchable-contract.pdf")
The PDF OCR guide covers page range selection, handling mixed PDF types, and searchable PDF output for archival workflows.
API Mapping Reference
| Asprise OCR | IronOCR Equivalent |
|---|---|
Ocr.SetUp() |
Not required |
new Ocr() |
new IronTesseract() |
ocr.StartEngine("eng", Ocr.SPEED_FAST) |
Not required (engine initializes on first use) |
ocr.Recognize(path, type, format) |
ocr.Read(path) |
Ocr.RECOGNIZE_TYPE_TEXT |
Default behavior |
Ocr.RECOGNIZE_TYPE_BARCODE |
ocr.Configuration.ReadBarCodes = true |
Ocr.RECOGNIZE_TYPE_ALL |
ocr.Configuration.ReadBarCodes = true |
Ocr.OUTPUT_FORMAT_PLAINTEXT |
result.Text |
Ocr.OUTPUT_FORMAT_XML |
result.Words / structured result |
Ocr.OUTPUT_FORMAT_PDF |
result.SaveAsSearchablePdf() |
Ocr.SPEED_FASTEST |
ocr.Configuration speed settings |
Ocr.SPEED_FAST |
Default configuration |
Ocr.SPEED_SLOW |
Higher accuracy configuration |
ocr.StopEngine() |
Not required (using handles cleanup) |
Language string "eng+fra" |
ocr.Language = OcrLanguage.English; ocr.AddSecondaryLanguage(OcrLanguage.French) |
| Manual try/finally cleanup | using var input = new OcrInput() |
| Error-string return value | Standard .NET exceptions |
When Teams Consider Moving from Asprise to IronOCR
The Production Readiness Blocker
The thread restriction surfaces as a hard blocker for most production .NET workloads. A team builds an OCR feature using Asprise LITE during development — single-threaded testing passes, everything works. Then the feature ships to a staging environment behind an ASP.NET Core API, concurrent test requests arrive, and the application either throws errors or operates in a technically non-compliant state. The resolution is either upgrading to ENTERPRISE (with its associated cost and sales engagement) or replacing the library. Teams that reach this point during staging rather than in production are fortunate; those who discover it post-launch face a more urgent migration. IronOCR removes this entire class of problem — the $999 Lite license supports concurrent request processing, batch parallelism, Windows Services, and cloud functions without restriction.
The Deployment Complexity Tax
Teams operating in modern deployment environments — Docker containers, Linux VMs, Kubernetes pods — pay an ongoing maintenance cost with Asprise that does not exist with pure NuGet packages. Every container image build must include the correct native binary for the target architecture. Every CI/CD pipeline that targets multiple platforms must handle platform-specific file inclusion. A missing native library on a production Linux container is a runtime discovery, not a build-time error. Teams that have spent hours debugging a 32-bit DLL loaded into a 64-bit process understand the cost concretely. IronOCR's NuGet-only deployment eliminates this entire category of deployment failure.
The Java Documentation Problem
Teams building .NET applications need C# examples, not Java examples. Asprise's primary documentation, API references, and community resources are oriented toward Java developers. A .NET developer reading Asprise documentation translates Java syntax, Java package conventions, and Java-specific patterns into C# equivalents — and sometimes the translation is not direct because the .NET wrapper does not expose every Java-side feature. IronOCR's documentation, tutorials, and code samples are written for C# developers. The reading text from images tutorial and the full tutorials hub provide working C# examples for every feature without translation overhead.
The PDF Pipeline Gap
Teams processing scanned documents, invoices, contracts, or forms in PDF format cannot use Asprise without adding a PDF rendering library to their dependency graph. That rendering library introduces its own licensing considerations, maintenance burden, and potential incompatibilities. For teams that need OCR + PDF in a single stack, IronOCR handles both natively. The ability to create searchable PDFs from scanned input — a common requirement for archival and compliance workflows — has no equivalent in Asprise at any license tier.
The Language Coverage Gap
Asprise supports 20+ OCR languages. IronOCR supports 125+, each installable as an independent NuGet package. Teams processing documents in Arabic, Hindi, Thai, or any of dozens of other languages supported by IronOCR but not by Asprise have no path to multilingual support through Asprise. The multiple languages guide covers installing and combining language packs, including simultaneous recognition across multiple scripts.
Common Migration Considerations
Replacing Engine Lifecycle Code
The largest mechanical change in migration is removing the Asprise engine lifecycle pattern and replacing it with direct IronTesseract instantiation. Every occurrence of the SetUp() / StartEngine() / Recognize() / StopEngine() sequence becomes a single Read() call:
// Before: Asprise lifecycle (15 lines, manual cleanup)
Ocr.SetUp();
Ocr ocr = new Ocr();
try
{
ocr.StartEngine("eng", Ocr.SPEED_FAST);
string text = ocr.Recognize(
imagePath,
Ocr.RECOGNIZE_TYPE_TEXT,
Ocr.OUTPUT_FORMAT_PLAINTEXT);
return text;
}
finally
{
ocr.StopEngine();
}
// After: IronOCR (1 line)
return new IronTesseract().Read(imagePath).Text;
// Before: Asprise lifecycle (15 lines, manual cleanup)
Ocr.SetUp();
Ocr ocr = new Ocr();
try
{
ocr.StartEngine("eng", Ocr.SPEED_FAST);
string text = ocr.Recognize(
imagePath,
Ocr.RECOGNIZE_TYPE_TEXT,
Ocr.OUTPUT_FORMAT_PLAINTEXT);
return text;
}
finally
{
ocr.StopEngine();
}
// After: IronOCR (1 line)
return new IronTesseract().Read(imagePath).Text;
' Before: Asprise lifecycle (15 lines, manual cleanup)
Ocr.SetUp()
Dim ocr As New Ocr()
Try
ocr.StartEngine("eng", Ocr.SPEED_FAST)
Dim text As String = ocr.Recognize( _
imagePath, _
Ocr.RECOGNIZE_TYPE_TEXT, _
Ocr.OUTPUT_FORMAT_PLAINTEXT)
Return text
Finally
ocr.StopEngine()
End Try
' After: IronOCR (1 line)
Return New IronTesseract().Read(imagePath).Text
For performance-sensitive code that processes many documents sequentially, reuse the IronTesseract instance rather than creating a new one per call — engine initialization carries overhead, and a single instance used sequentially is more efficient than creating and disposing one per document.
Replacing String-Based Language Codes
Asprise uses string parameters for language selection ("eng", "fra", "eng+fra"). IronOCR uses a strongly-typed OcrLanguage enum with a secondary language API. The multiple languages guide covers available language identifiers and the NuGet packages required for each:
// Before: Asprise string-based language
ocr.StartEngine("eng+fra", Ocr.SPEED_FAST);
// After: IronOCR strongly-typed language enum
var ocr = new IronTesseract();
ocr.Language = OcrLanguage.English;
ocr.AddSecondaryLanguage(OcrLanguage.French);
var result = ocr.Read(imagePath);
// Before: Asprise string-based language
ocr.StartEngine("eng+fra", Ocr.SPEED_FAST);
// After: IronOCR strongly-typed language enum
var ocr = new IronTesseract();
ocr.Language = OcrLanguage.English;
ocr.AddSecondaryLanguage(OcrLanguage.French);
var result = ocr.Read(imagePath);
Imports IronOcr
' Before: Asprise string-based language
ocr.StartEngine("eng+fra", Ocr.SPEED_FAST)
' After: IronOCR strongly-typed language enum
Dim ocr As New IronTesseract()
ocr.Language = OcrLanguage.English
ocr.AddSecondaryLanguage(OcrLanguage.French)
Dim result = ocr.Read(imagePath)
Replacing Error-String Checks
Asprise returns null or an error-prefixed string when recognition fails. IronOCR throws .NET exceptions. Replace null and string-prefix checks with standard try/catch blocks. This aligns OCR error handling with the rest of the .NET exception handling model and gives access to full stack traces and exception type hierarchies rather than parsed error strings.
Enabling Parallel Processing
After migration, existing foreach batch loops can be converted to Parallel.ForEach or PLINQ without any licensing concern. For document batches that previously processed sequentially on LITE/STANDARD, parallelism is a direct throughput multiplier. The async OCR guide covers async patterns for web application contexts where non-blocking OCR is preferable to thread pool saturation.
Additional IronOCR Capabilities
Beyond the areas covered in this comparison, IronOCR provides features that have no equivalent in Asprise:
- Barcode reading during OCR: Enable
ocr.Configuration.ReadBarCodes = trueto extract barcodes and QR codes from documents in the same pass as text recognition — no second library required. - Region-based OCR: Use
CropRectangleto extract text from specific areas of a document, useful for invoice headers, form fields, and structured data zones. - Confidence scores: Access per-word and overall recognition confidence values to flag low-confidence extractions for human review.
- Structured data extraction: Navigate result objects by page, paragraph, line, and word, each carrying pixel coordinates — enabling layout-aware document parsing beyond flat text output.
- hOCR export: Export recognition results in hOCR format for integration with downstream document processing tools.
- Specialized document recognition: Purpose-built workflows for passports, MICR cheques, license plates, and handwriting that go beyond general Tesseract recognition.
- Progress tracking: Subscribe to progress events during long-running batch operations for UI feedback and monitoring.
.NET Compatibility and Future Readiness
IronOCR targets .NET Standard 2.0, which covers .NET Framework 4.6.1+, .NET Core 2.0+, and all versions of .NET 5 through .NET 9 and beyond. The library receives regular updates aligned with .NET release cycles and is tested on Windows x64, Windows x86, Linux x64, macOS, Docker, Azure App Service, and AWS Lambda. Asprise's .NET compatibility is constrained by its native binary model — new platform targets (ARM64, WASM) require new native builds from Asprise Inc., and the Java-first release cadence means .NET platform updates may lag behind. For teams targeting .NET 8 and .NET 9 today with plans to move to .NET 10 in 2026, IronOCR's managed NuGet architecture provides a straightforward compatibility path without native binary concerns.
Conclusion
Asprise OCR is a Java OCR library with a .NET wrapper. The Java heritage is not incidental — it defines the deployment model (platform-specific native DLLs), the API style (C-style lifecycle methods with integer constants), the documentation language (Java examples requiring translation), and the threading restrictions (LITE/STANDARD single-threaded by license contract). For Java teams that happen to have a .NET project, Asprise's cross-language positioning makes some sense. For .NET teams building production systems, those same characteristics introduce friction at every stage.
The threading restriction deserves particular weight. The two most affordable Asprise tiers — which cover the majority of teams evaluating the product — prohibit multi-threaded and multi-process execution. Every ASP.NET Core Web API, every Windows Service with a work queue, every Azure Function handling concurrent triggers: these are standard .NET production patterns, and all of them require ENTERPRISE licensing from Asprise. IronOCR's $999 Lite license covers all of them without restriction.
Deployment complexity is the second practical concern. Teams running Docker containers, Linux builds, or cross-platform CI/CD pipelines must manage platform-specific native binaries with Asprise. Those failures — DllNotFoundException, BadImageFormatException — appear at runtime on target infrastructure, not at build time. IronOCR deploys through standard NuGet package management, and the package selection mechanism handles platform-specific binaries internally. The deployment surface is a single NuGet reference.
For .NET teams starting a new OCR integration, the starting point is clear: a single dotnet add package IronOcr, a one-line license key assignment, and new IronTesseract().Read("document.jpg").Text for the first result. No engine initialization, no native binary sourcing, no threading license audit.
Frequently Asked Questions
What is Asprise OCR SDK?
Asprise OCR SDK is an OCR solution used by developers and enterprises to extract text from images and documents. It is one of several OCR options evaluated alongside IronOCR for .NET application development.
How does IronOCR compare to Asprise OCR SDK for .NET developers?
IronOCR is a NuGet-native .NET OCR library using IronTesseract as its core engine. Compared to Asprise OCR SDK, it offers simpler deployment (no SDK installers), flat-rate pricing, and a clean C# API without COM interop or cloud dependencies.
Is IronOCR easier to set up than Asprise OCR SDK?
IronOCR installs via a single NuGet package. There are no SDK installers, license files to copy, COM components to register, or separate runtime binaries to manage. The entire OCR engine is bundled in the package.
What accuracy differences exist between Asprise OCR SDK and IronOCR?
IronOCR achieves high recognition accuracy for standard business documents, invoices, receipts, and scanned forms. For highly degraded documents or uncommon scripts, accuracy varies by source quality. IronOCR includes image preprocessing filters to improve recognition on low-quality inputs.
Does IronOCR support PDF text extraction?
Yes. IronOCR extracts text from both native PDFs and scanned PDF images in a single call. It also supports multi-page TIFF files, images, and streams. For scanned PDFs, OCR is applied page-by-page with per-page result objects.
How does Asprise OCR SDK licensing compare to IronOCR?
IronOCR uses a flat-rate perpetual license with no per-page or per-scan charges. Organizations processing high document volumes pay the same license cost regardless of volume. Details and volume pricing are on the IronOCR licensing page.
What languages does IronOCR support?
IronOCR supports 127 languages via separate NuGet language packs. Adding a language requires a single 'dotnet add package IronOcr.Languages.{Language}' command. No manual file placement or path configuration is needed.
How do I install IronOCR in a .NET project?
Install via NuGet: 'Install-Package IronOcr' in Package Manager Console or 'dotnet add package IronOcr' in the CLI. Additional language packs are installed the same way. No native SDK installer is required.
Is IronOCR suitable for Docker and containerized deployments, unlike Asprise OCR?
Yes. IronOCR works in Docker containers via its NuGet package. The license key is set via an environment variable. No license files, SDK paths, or volume mounts are required for the OCR engine itself.
Can I try IronOCR before purchasing, compared to Asprise OCR?
Yes. IronOCR trial mode processes documents and returns OCR results with a watermark overlay on output. You can verify accuracy on your own documents before purchasing a license.
Does IronOCR support barcode reading alongside text extraction?
IronOCR focuses on text extraction and OCR. For barcode reading, Iron Software provides IronBarcode as a companion library. Both are available individually or as part of the Iron Suite bundle.
Is it easy to migrate from Asprise OCR SDK to IronOCR?
Migration from Asprise OCR SDK to IronOCR typically involves replacing initialization sequences with IronTesseract instantiation, removing COM lifecycle management, and updating API calls. Most migrations reduce code complexity significantly.

