Saltar al pie de página
VIDEOS

Migración de Asprise OCR a IronOCR

Esta guía acompaña a los desarrolladores .NET paso a paso en el proceso de sustitución de OCR Asprise por IronOCR . Abarca el intercambio mecánico de paquetes, los cambios de espacio de nombres y los cuatro patrones de migración de código que representan la mayor parte del uso de Asprise en aplicaciones .NET de producción. El público objetivo son los desarrolladores que ya han decidido migrar y necesitan un plan de acción concreto.

¿Por qué migrar desde Asprise OCR?

Asprise OCR se diseñó inicialmente como un producto Java. La interfaz .NET es una capa que envuelve un motor nativo de origen Java, y ese origen determina todos los aspectos del comportamiento de la biblioteca en .NET , desde la implementación hasta el diseño de la API y las restricciones de licencia.

Dependencia de binario nativo y JRE. OCR Asprise for .NET requiere binarios nativos específicos de la plataforma (aocr.dll, aocr_x64.dll, libaocr.so, libaocr.dylib) que deben estar presentes en cada máquina donde se ejecute la aplicación. Cada archivo binario debe coincidir exactamente con la plataforma de destino y la arquitectura del proceso. Un contenedor de Docker de 64 bits construido con la DLL de 32 bits lanza BadImageFormatException en tiempo de ejecución. Un despliegue de Linux que falta libaocr.so de LD_LIBRARY_PATH lanza DllNotFoundException. Ninguno de los errores se manifiesta durante la compilación. Cada nuevo destino de despliegue (un nuevo servidor, una nueva imagen de contenedor, un agente de CI) se convierte en un ejercicio manual de obtención de binarios.

API de cadena-constante de herencia de Java. Asprise expone constantes enteras para el tipo de reconocimiento y formato de salida: Ocr.RECOGNIZE_TYPE_TEXT, Ocr.OUTPUT_FORMAT_PLAINTEXT, Ocr.OUTPUT_FORMAT_XML. Estas constantes se corresponden directamente con la API basada en enteros del SDK de Java. Los desarrolladores de .NET no reciben ninguna guía de IntelliSense sobre valores constantes válidos, ni seguridad en tiempo de compilación sobre combinaciones de argumentos, ni objetos de resultado fuertemente tipados. La extracción de resultados estructurados requiere el análisis manual de cadenas XML.

No hay soporte para funciones asíncronas sin soluciones alternativas. Asprise no proporciona una API asíncrona nativa. Encerrar llamadas sincrónicas de Asprise en Task.Run para evitar bloquear hilos de ASP.NET crea presión en el grupo de hilos y no resuelve la restricción de licencia que prohíbe la ejecución concurrente en niveles LITE y STANDARD. Los patrones asíncronos en las aplicaciones .NET modernas (servicios en segundo plano, puntos finales de API mínimos, Azure Functions) no tienen un equivalente claro en Asprise.

El procesamiento de archivos TIFF multifotograma requiere división manual. Asprise funciona con archivos de imagen individuales. El procesamiento de un archivo TIFF de varias páginas requiere código externo para dividir los fotogramas en archivos individuales y, a continuación, procesar cada archivo en un bucle. No se conservan los metadatos de los fotogramas ni la numeración de las páginas en el archivo de salida.

La restricción de subprocesos impide la implementación en producción. Las licencias Lite (~$299) y STANDARD (~$699) restringen contractualmente la ejecución a un solo subproceso y un solo proceso. ASP.NET Core procesa todas las solicitudes HTTP en un grupo de subprocesos. Cada punto final de la API web que llama a Asprise en esos niveles constituye una infracción de licencia desde la primera solicitud simultánea. La actualización a Enterprise elimina la restricción, pero requiere contactar con el departamento de ventas, cuyo precio no está publicado; las estimaciones oscilan entre 2000 y más de 5000 dólares, según el alcance de la implementación.

El manejo del formato de salida requiere análisis de cadenas. Cuando se especifica OUTPUT_FORMAT_XML, Asprise devuelve una cadena XML en bruto. La aplicación se encarga de deserializar esa cadena, validar su estructura y extraer las palabras y sus coordenadas. Las puntuaciones de confianza por palabra están integradas en los atributos XML. No existe un modelo de objetos, solo manipulación de cadenas de texto.

El problema fundamental

Asprise requiere una configuración binaria nativa adyacente a JRE antes de que se pueda ejecutar la primera llamada de OCR.IronOCR no requiere nada más que un paquete NuGet :

// Asprise: native binary must exist in PATH or application directory
// aocr_x64.dll missing → DllNotFoundException at runtime, not at build
Ocr.SetUp();                              // Static init — touches native binary
Ocr ocr = new Ocr();
ocr.StartEngine("eng", Ocr.SPEED_FAST);  // Allocates native engine memory
string text = ocr.Recognize(imagePath, Ocr.RECOGNIZE_TYPE_TEXT, Ocr.OUTPUT_FORMAT_PLAINTEXT);
ocr.StopEngine();                         // Must call or native memory leaks
// Asprise: native binary must exist in PATH or application directory
// aocr_x64.dll missing → DllNotFoundException at runtime, not at build
Ocr.SetUp();                              // Static init — touches native binary
Ocr ocr = new Ocr();
ocr.StartEngine("eng", Ocr.SPEED_FAST);  // Allocates native engine memory
string text = ocr.Recognize(imagePath, Ocr.RECOGNIZE_TYPE_TEXT, Ocr.OUTPUT_FORMAT_PLAINTEXT);
ocr.StopEngine();                         // Must call or native memory leaks
' Asprise: native binary must exist in PATH or application directory
' aocr_x64.dll missing → DllNotFoundException at runtime, not at build
Ocr.SetUp()                              ' Static init — touches native binary
Dim ocr As New Ocr()
ocr.StartEngine("eng", Ocr.SPEED_FAST)   ' Allocates native engine memory
Dim text As String = ocr.Recognize(imagePath, Ocr.RECOGNIZE_TYPE_TEXT, Ocr.OUTPUT_FORMAT_PLAINTEXT)
ocr.StopEngine()                         ' Must call or native memory leaks
$vbLabelText   $csharpLabel
// IronOCR: dotnet add package IronOcr — no binary sourcing, no lifecycle calls
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
string text = new IronTesseract().Read(imagePath).Text;
// IronOCR: dotnet add package IronOcr — no binary sourcing, no lifecycle calls
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
string text = new IronTesseract().Read(imagePath).Text;
' IronOCR: dotnet add package IronOcr — no binary sourcing, no lifecycle calls
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"
Dim text As String = New IronTesseract().Read(imagePath).Text
$vbLabelText   $csharpLabel

IronOCR vs Asprise OCR: Comparación de características

La tabla que aparece a continuación resume las funcionalidades más relevantes para los desarrolladores que evalúan esta migración.

Característica OCR Asprise IronOCR
Plataforma principal Java (heredado) .NET nativo
Instalación de NuGet Envoltorio + DLLs nativas de la plataforma Paquete único (IronOcr)
Se requiere un binario nativo en tiempo de ejecución. Sí (DLL por plataforma) No
Estilo de API de .NET Constantes enteras, devoluciones de cadena Clases y enumeraciones fuertemente tipadas
IDisposable / using patrón No implementado Sí (OcrInput)
OCR asíncrono Sin soporte nativo Sí (ReadAsync)
Multiprocesamiento — Nivel Lite/ESTÁNDAR Prohibido por licencia Permitido
Multiprocesamiento — todos los niveles Solo para Enterprise Todos los niveles
Compatibilidad con ASP.NET Core Web API Se requiere Enterprise Cualquier nivel
Azure Functions / AWS Lambda Se requiere Enterprise Cualquier nivel
Entrada nativa de PDF No
Entrada TIFF multifotograma No (división manual de fotogramas) Sí (LoadImageFrames)
Matriz de bytes y entrada de flujo Limitado
Preprocesamiento de imágenes integrado No Sí (más de 9 filtros)
Salida en PDF con capacidad de búsqueda No Sí (SaveAsSearchablePdf)
Modelo de objeto de resultado estructurado No (solo cadena XML) Sí (páginas, párrafos, palabras, caracteres)
Puntuaciones de confianza por palabra No (análisis de atributos XML) Sí (result.Confidence)
Coordenadas de píxeles de la palabra Análisis de atributos XML Propiedades fuertemente tipadas
Recuento de palabras Más de 20 años 125+
Selección de lenguaje fuertemente tipado No (códigos de cadena) Sí (OcrLanguage enum)
Lectura de códigos de barras Sí (reconocer tipo por separado) Sí (indicador de configuración)
Exportación hOCR No
Implementación multiplataforma Binario manual por plataforma NuGet admite todas las plataformas.
Docker / Linux / macOS Configuración manual LD_LIBRARY_PATH Funcionamiento inmediato
Compatibilidad con .NET Limitado (puente Java) .NET Framework 4.6.2+, .NET 5-9
Precio de entrada para el uso del servidor Enterprise (~$2,000+) $999 (Lite, todas las funciones)
Tipo de licencia Para cada nivel, contacte con el departamento de ventas de Enterprise. Perpetuo (compra única)

Inicio rápido: Migración de OCR Asprise a IronOCR

Paso 1: Sustituir el paquete NuGet

Eliminar Asprise OCR:

dotnet remove package asprise-ocr-api
dotnet remove package asprise-ocr-api
SHELL

Instale IronOCR desde la página del paquete NuGet :

dotnet add package IronOcr

Paso 2: Actualizar los espacios de nombres

Reemplaza espacios de nombres de Asprise con el espacio de nombres IronOCR:

// Before (Asprise)
using asprise.ocr;

// After (IronOCR)
using IronOcr;
// Before (Asprise)
using asprise.ocr;

// After (IronOCR)
using IronOcr;
Imports IronOcr
$vbLabelText   $csharpLabel

Paso 3: Inicializar licencia

Añadir la asignación de clave de licencia al inicio de la aplicación — en Program.cs antes de cualquier llamada OCR, en Startup.Configure, o en un constructor estático:

IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"
$vbLabelText   $csharpLabel

Puede obtener una clave de prueba gratuita en la página de licencias de IronOCR . Durante el desarrollo y la evaluación,IronOCR se ejecuta sin clave y añade una marca de agua de prueba a la salida.

Ejemplos de migración de código

Eliminación de la configuración de la ruta JRE y la inicialización del motor

Las aplicaciones de Asprise que se ejecutan en Linux o macOS suelen incluir código de inicio que establece la ruta de JRE o valida la presencia de binarios nativos antes de que comience cualquier trabajo de OCR. Esta infraestructura no tiene equivalente en IronOCR.

Enfoque OCR de Asprise:

// AppStartup.cs — native binary validation before accepting any requests
public static void InitializeOcr()
{
    // Validate native library is reachable before first use
    string nativePath = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
        ? Path.Combine(AppContext.BaseDirectory, "aocr_x64.dll")
        : RuntimeInformation.IsOSPlatform(OSPlatform.Linux)
            ? "/usr/lib/libaocr.so"
            : "/usr/local/lib/libaocr.dylib";

    if (!File.Exists(nativePath))
        throw new FileNotFoundException(
            $"Asprise native binary not found: {nativePath}. " +
            "Deploy the correct platform binary before starting.");

    // Static global init — must run before any Ocr instance is created
    Ocr.SetUp();
}
// AppStartup.cs — native binary validation before accepting any requests
public static void InitializeOcr()
{
    // Validate native library is reachable before first use
    string nativePath = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
        ? Path.Combine(AppContext.BaseDirectory, "aocr_x64.dll")
        : RuntimeInformation.IsOSPlatform(OSPlatform.Linux)
            ? "/usr/lib/libaocr.so"
            : "/usr/local/lib/libaocr.dylib";

    if (!File.Exists(nativePath))
        throw new FileNotFoundException(
            $"Asprise native binary not found: {nativePath}. " +
            "Deploy the correct platform binary before starting.");

    // Static global init — must run before any Ocr instance is created
    Ocr.SetUp();
}
Imports System
Imports System.IO
Imports System.Runtime.InteropServices

' AppStartup.vb — native binary validation before accepting any requests
Public Module AppStartup
    Public Sub InitializeOcr()
        ' Validate native library is reachable before first use
        Dim nativePath As String = If(RuntimeInformation.IsOSPlatform(OSPlatform.Windows),
                                      Path.Combine(AppContext.BaseDirectory, "aocr_x64.dll"),
                                      If(RuntimeInformation.IsOSPlatform(OSPlatform.Linux),
                                         "/usr/lib/libaocr.so",
                                         "/usr/local/lib/libaocr.dylib"))

        If Not File.Exists(nativePath) Then
            Throw New FileNotFoundException($"Asprise native binary not found: {nativePath}. " &
                                            "Deploy the correct platform binary before starting.")
        End If

        ' Static global init — must run before any Ocr instance is created
        Ocr.SetUp()
    End Sub
End Module
$vbLabelText   $csharpLabel

Enfoque IronOCR:

// Program.cs — license key assignment is the entire initialization
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";

// That is it. No binary validation, no path configuration, no SetUp() call.
// NuGet resolved the correct native runtime during package restore.
// Program.cs — license key assignment is the entire initialization
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";

// That is it. No binary validation, no path configuration, no SetUp() call.
// NuGet resolved the correct native runtime during package restore.
Imports IronOcr

' Program.vb — license key assignment is the entire initialization
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"

' That is it. No binary validation, no path configuration, no SetUp() call.
' NuGet resolved the correct native runtime during package restore.
$vbLabelText   $csharpLabel

El patrón de Asprise es típicamente de 15-30 líneas a través de múltiples archivos — un validador de inicio, un cambio de plataforma, una excepción con un mensaje de despliegue y la llamada SetUp().IronOCR lo reemplaza todo con una sola tarea. La guía de configuración de IronTesseract abarca las opciones de configuración de implementación para entornos que requieren rutas de datos de prueba personalizadas o funcionamiento sin conexión.

Sustitución del formato de salida XML por objetos de resultados estructurados.

Asprise produce una salida estructurada como una cadena XML en bruto cuando se especifica OUTPUT_FORMAT_XML. Para extraer el texto, las coordenadas y el nivel de confianza de esa cadena, se necesita código de análisis XML.IronOCR devuelve un gráfico de objetos tipados.

Enfoque OCR de Asprise:

// Asprise: structured output is an XML string — must parse manually
Ocr.SetUp();
Ocr ocr = new Ocr();
try
{
    ocr.StartEngine("eng", Ocr.SPEED_FAST);
    string xmlOutput = ocr.Recognize(
        imagePath,
        Ocr.RECOGNIZE_TYPE_TEXT,
        Ocr.OUTPUT_FORMAT_XML);   // Returns raw XML, not an object

    // Parse the XML manually to extract words and coordinates
    var doc = System.Xml.Linq.XDocument.Parse(xmlOutput);
    var words = doc.Descendants("word")
        .Select(w => new
        {
            Text       = (string)w.Attribute("text"),
            Confidence = (float)w.Attribute("confidence"),
            X          = (int)w.Attribute("x"),
            Y          = (int)w.Attribute("y"),
        })
        .ToList();

    foreach (var word in words)
        Console.WriteLine($"{word.Text} @ ({word.X},{word.Y}) conf={word.Confidence}");
}
finally
{
    ocr.StopEngine();
}
// Asprise: structured output is an XML string — must parse manually
Ocr.SetUp();
Ocr ocr = new Ocr();
try
{
    ocr.StartEngine("eng", Ocr.SPEED_FAST);
    string xmlOutput = ocr.Recognize(
        imagePath,
        Ocr.RECOGNIZE_TYPE_TEXT,
        Ocr.OUTPUT_FORMAT_XML);   // Returns raw XML, not an object

    // Parse the XML manually to extract words and coordinates
    var doc = System.Xml.Linq.XDocument.Parse(xmlOutput);
    var words = doc.Descendants("word")
        .Select(w => new
        {
            Text       = (string)w.Attribute("text"),
            Confidence = (float)w.Attribute("confidence"),
            X          = (int)w.Attribute("x"),
            Y          = (int)w.Attribute("y"),
        })
        .ToList();

    foreach (var word in words)
        Console.WriteLine($"{word.Text} @ ({word.X},{word.Y}) conf={word.Confidence}");
}
finally
{
    ocr.StopEngine();
}
Imports System.Xml.Linq

' Asprise: structured output is an XML string — must parse manually
Ocr.SetUp()
Dim ocr As New Ocr()
Try
    ocr.StartEngine("eng", Ocr.SPEED_FAST)
    Dim xmlOutput As String = ocr.Recognize(imagePath, Ocr.RECOGNIZE_TYPE_TEXT, Ocr.OUTPUT_FORMAT_XML) ' Returns raw XML, not an object

    ' Parse the XML manually to extract words and coordinates
    Dim doc As XDocument = XDocument.Parse(xmlOutput)
    Dim words = doc.Descendants("word") _
        .Select(Function(w) New With {
            .Text = CStr(w.Attribute("text")),
            .Confidence = CSng(w.Attribute("confidence")),
            .X = CInt(w.Attribute("x")),
            .Y = CInt(w.Attribute("y"))
        }) _
        .ToList()

    For Each word In words
        Console.WriteLine($"{word.Text} @ ({word.X},{word.Y}) conf={word.Confidence}")
Next
Finally
    ocr.StopEngine()
End Try
$vbLabelText   $csharpLabel

Enfoque IronOCR:

// IronOCR: structured result is a typed object — no XML parsing
var result = new IronTesseract().Read(imagePath);

foreach (var page in result.Pages)
{
    foreach (var paragraph in page.Paragraphs)
    {
        foreach (var word in paragraph.Words)
        {
            Console.WriteLine(
                $"{word.Text} @ ({word.X},{word.Y}) conf={word.Confidence:F1}%");
        }
    }
}
// IronOCR: structured result is a typed object — no XML parsing
var result = new IronTesseract().Read(imagePath);

foreach (var page in result.Pages)
{
    foreach (var paragraph in page.Paragraphs)
    {
        foreach (var word in paragraph.Words)
        {
            Console.WriteLine(
                $"{word.Text} @ ({word.X},{word.Y}) conf={word.Confidence:F1}%");
        }
    }
}
Imports IronOcr

' IronOCR: structured result is a typed object — no XML parsing
Dim result = New IronTesseract().Read(imagePath)

For Each page In result.Pages
    For Each paragraph In page.Paragraphs
        For Each word In paragraph.Words
            Console.WriteLine($"{word.Text} @ ({word.X},{word.Y}) conf={word.Confidence:F1}%")
        Next
    Next
Next
$vbLabelText   $csharpLabel

Sin deserialización XML, sin conversión de atributos, sin suposiciones de esquema. El modelo de objeto OcrResult expone páginas, párrafos, líneas, palabras y caracteres con propiedades tipadas. La guía de resultados de lectura abarca la jerarquía completa y el sistema de coordenadas, incluyendo cómo filtrar por umbral de confianza para flujos de trabajo automatizados.

Procesamiento de archivos TIFF multifotograma

Asprise acepta archivos de imagen individuales. Un archivo TIFF multifotograma, habitual en los flujos de trabajo de escaneo de documentos, debe dividirse en archivos de fotogramas individuales antes de que Asprise pueda procesarlo.IronOCR acepta TIFFs de múltiples cuadros directamente a través de LoadImageFrames.

Enfoque OCR de Asprise:

// Asprise: no multi-frame TIFF support — split frames externally first
// Using an external imaging library (e.g., System.Drawing or Magick.NET)
var frameFiles = new List<string>();
using (var tiff = System.Drawing.Image.FromFile("scanned-batch.tiff"))
{
    int frameCount = tiff.GetFrameCount(System.Drawing.Imaging.FrameDimension.Page);
    for (int i = 0; i < frameCount; i++)
    {
        tiff.SelectActiveFrame(System.Drawing.Imaging.FrameDimension.Page, i);
        string framePath = $"frame_{i}.png";
        tiff.Save(framePath);
        frameFiles.Add(framePath);
    }
}

// Now process each frame individually — sequential on LITE/STANDARD
var allText = new System.Text.StringBuilder();
Ocr.SetUp();
Ocr ocr = new Ocr();
try
{
    ocr.StartEngine("eng", Ocr.SPEED_FAST);
    foreach (var framePath in frameFiles)
    {
        string pageText = ocr.Recognize(
            framePath,
            Ocr.RECOGNIZE_TYPE_TEXT,
            Ocr.OUTPUT_FORMAT_PLAINTEXT);
        allText.AppendLine(pageText);
    }
}
finally
{
    ocr.StopEngine();
    // Clean up temporary frame files
    foreach (var f in frameFiles)
        File.Delete(f);
}
Console.WriteLine(allText.ToString());
// Asprise: no multi-frame TIFF support — split frames externally first
// Using an external imaging library (e.g., System.Drawing or Magick.NET)
var frameFiles = new List<string>();
using (var tiff = System.Drawing.Image.FromFile("scanned-batch.tiff"))
{
    int frameCount = tiff.GetFrameCount(System.Drawing.Imaging.FrameDimension.Page);
    for (int i = 0; i < frameCount; i++)
    {
        tiff.SelectActiveFrame(System.Drawing.Imaging.FrameDimension.Page, i);
        string framePath = $"frame_{i}.png";
        tiff.Save(framePath);
        frameFiles.Add(framePath);
    }
}

// Now process each frame individually — sequential on LITE/STANDARD
var allText = new System.Text.StringBuilder();
Ocr.SetUp();
Ocr ocr = new Ocr();
try
{
    ocr.StartEngine("eng", Ocr.SPEED_FAST);
    foreach (var framePath in frameFiles)
    {
        string pageText = ocr.Recognize(
            framePath,
            Ocr.RECOGNIZE_TYPE_TEXT,
            Ocr.OUTPUT_FORMAT_PLAINTEXT);
        allText.AppendLine(pageText);
    }
}
finally
{
    ocr.StopEngine();
    // Clean up temporary frame files
    foreach (var f in frameFiles)
        File.Delete(f);
}
Console.WriteLine(allText.ToString());
Imports System.Drawing
Imports System.Text
Imports System.IO

' Asprise: no multi-frame TIFF support — split frames externally first
' Using an external imaging library (e.g., System.Drawing or Magick.NET)
Dim frameFiles As New List(Of String)()
Using tiff As Image = Image.FromFile("scanned-batch.tiff")
    Dim frameCount As Integer = tiff.GetFrameCount(Imaging.FrameDimension.Page)
    For i As Integer = 0 To frameCount - 1
        tiff.SelectActiveFrame(Imaging.FrameDimension.Page, i)
        Dim framePath As String = $"frame_{i}.png"
        tiff.Save(framePath)
        frameFiles.Add(framePath)
    Next
End Using

' Now process each frame individually — sequential on LITE/STANDARD
Dim allText As New StringBuilder()
Ocr.SetUp()
Dim ocr As New Ocr()
Try
    ocr.StartEngine("eng", Ocr.SPEED_FAST)
    For Each framePath As String In frameFiles
        Dim pageText As String = ocr.Recognize(framePath, Ocr.RECOGNIZE_TYPE_TEXT, Ocr.OUTPUT_FORMAT_PLAINTEXT)
        allText.AppendLine(pageText)
    Next
Finally
    ocr.StopEngine()
    ' Clean up temporary frame files
    For Each f As String In frameFiles
        File.Delete(f)
    Next
End Try
Console.WriteLine(allText.ToString())
$vbLabelText   $csharpLabel

Enfoque IronOCR:

// IronOCR: multi-frame TIFF loads directly — no frame splitting, no temp files
using var input = new OcrInput();
input.LoadImageFrames("scanned-batch.tiff");  // All frames, one call

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

// Access each page independently with its page number
foreach (var page in result.Pages)
    Console.WriteLine($"Page {page.PageNumber}: {page.Text}");
// IronOCR: multi-frame TIFF loads directly — no frame splitting, no temp files
using var input = new OcrInput();
input.LoadImageFrames("scanned-batch.tiff");  // All frames, one call

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

// Access each page independently with its page number
foreach (var page in result.Pages)
    Console.WriteLine($"Page {page.PageNumber}: {page.Text}");
Imports IronOcr

' IronOCR: multi-frame TIFF loads directly — no frame splitting, no temp files
Using input As New OcrInput()
    input.LoadImageFrames("scanned-batch.tiff") ' All frames, one call

    Dim result = New IronTesseract().Read(input)

    ' Access each page independently with its page number
    For Each page In result.Pages
        Console.WriteLine($"Page {page.PageNumber}: {page.Text}")
    Next
End Using
$vbLabelText   $csharpLabel

El método Asprise requiere una dependencia de procesamiento de imágenes externo, gestión de archivos temporales, limpieza manual y procesamiento secuencial por fotograma.IronOCR procesa todos los fotogramas en una sola pasada. La guía de entrada de archivos TIFF y GIF abarca la selección del rango de fotogramas para archivos TIFF grandes en los que solo se necesitan páginas específicas.

Generación de PDF con capacidad de búsqueda

Asprise no ofrece la posibilidad de generar archivos PDF con texto seleccionable en ningún nivel de licencia. Para crear un PDF con texto OCR incrustado a partir de un documento escaneado, se requiere una biblioteca PDF externa, un paso de OCR independiente para obtener las posiciones del texto y la construcción manual de la superposición.IronOCR genera archivos PDF con capacidad de búsqueda directamente a partir del resultado del reconocimiento.

Enfoque OCR de Asprise:

// Asprise: no searchable PDF output — external PDF library required
// Step 1: OCR the document to get text
Ocr.SetUp();
Ocr ocr = new Ocr();
string recognizedText;
try
{
    ocr.StartEngine("eng", Ocr.SPEED_FAST);
    recognizedText = ocr.Recognize(
        "scanned-contract.jpg",
        Ocr.RECOGNIZE_TYPE_TEXT,
        Ocr.OUTPUT_FORMAT_PLAINTEXT);   // Only plain text — no position data
}
finally
{
    ocr.StopEngine();
}

// Step 2: Use an external PDF library to embed text over the image
// (iTextSharp, PdfSharp, or similar — adds another dependency and license)
// Text positioning requires coordinate data Asprise cannot provide in plain text mode
// ... 40-80 lines of PDF construction code
Console.WriteLine("Searchable PDF: not achievable with Asprise alone");
// Asprise: no searchable PDF output — external PDF library required
// Step 1: OCR the document to get text
Ocr.SetUp();
Ocr ocr = new Ocr();
string recognizedText;
try
{
    ocr.StartEngine("eng", Ocr.SPEED_FAST);
    recognizedText = ocr.Recognize(
        "scanned-contract.jpg",
        Ocr.RECOGNIZE_TYPE_TEXT,
        Ocr.OUTPUT_FORMAT_PLAINTEXT);   // Only plain text — no position data
}
finally
{
    ocr.StopEngine();
}

// Step 2: Use an external PDF library to embed text over the image
// (iTextSharp, PdfSharp, or similar — adds another dependency and license)
// Text positioning requires coordinate data Asprise cannot provide in plain text mode
// ... 40-80 lines of PDF construction code
Console.WriteLine("Searchable PDF: not achievable with Asprise alone");
' Asprise: no searchable PDF output — external PDF library required
' Step 1: OCR the document to get text
Ocr.SetUp()
Dim ocr As New Ocr()
Dim recognizedText As String
Try
    ocr.StartEngine("eng", Ocr.SPEED_FAST)
    recognizedText = ocr.Recognize( _
        "scanned-contract.jpg", _
        Ocr.RECOGNIZE_TYPE_TEXT, _
        Ocr.OUTPUT_FORMAT_PLAINTEXT)   ' Only plain text — no position data
Finally
    ocr.StopEngine()
End Try

' Step 2: Use an external PDF library to embed text over the image
' (iTextSharp, PdfSharp, or similar — adds another dependency and license)
' Text positioning requires coordinate data Asprise cannot provide in plain text mode
' ... 40-80 lines of PDF construction code
Console.WriteLine("Searchable PDF: not achievable with Asprise alone")
$vbLabelText   $csharpLabel

Enfoque IronOCR:

// IronOCR: searchable PDF in two lines — no external PDF library
var result = new IronTesseract().Read("scanned-contract.jpg");
result.SaveAsSearchablePdf("searchable-contract.pdf");

// Batch: convert a folder of scanned images to searchable PDFs
foreach (var imagePath in Directory.GetFiles("scans", "*.jpg"))
{
    var batchResult = new IronTesseract().Read(imagePath);
    string outputPath = Path.ChangeExtension(imagePath, ".searchable.pdf");
    batchResult.SaveAsSearchablePdf(outputPath);
    Console.WriteLine($"Converted: {outputPath}");
}
// IronOCR: searchable PDF in two lines — no external PDF library
var result = new IronTesseract().Read("scanned-contract.jpg");
result.SaveAsSearchablePdf("searchable-contract.pdf");

// Batch: convert a folder of scanned images to searchable PDFs
foreach (var imagePath in Directory.GetFiles("scans", "*.jpg"))
{
    var batchResult = new IronTesseract().Read(imagePath);
    string outputPath = Path.ChangeExtension(imagePath, ".searchable.pdf");
    batchResult.SaveAsSearchablePdf(outputPath);
    Console.WriteLine($"Converted: {outputPath}");
}
Imports System.IO
Imports IronOcr

' IronOCR: searchable PDF in two lines — no external PDF library
Dim result = New IronTesseract().Read("scanned-contract.jpg")
result.SaveAsSearchablePdf("searchable-contract.pdf")

' Batch: convert a folder of scanned images to searchable PDFs
For Each imagePath In Directory.GetFiles("scans", "*.jpg")
    Dim batchResult = New IronTesseract().Read(imagePath)
    Dim outputPath As String = Path.ChangeExtension(imagePath, ".searchable.pdf")
    batchResult.SaveAsSearchablePdf(outputPath)
    Console.WriteLine($"Converted: {outputPath}")
Next
$vbLabelText   $csharpLabel

El PDF con capacidad de búsqueda contiene la imagen original como capa visual con texto OCR invisible superpuesto en las coordenadas correctas, el formato estándar para flujos de trabajo de archivo y cumplimiento normativo. Consulte la guía práctica en formato PDF con función de búsqueda y el ejemplo en formato PDF con función de búsqueda para conocer las opciones disponibles, incluida la salida en formato PDF/A para el archivo a largo plazo.

OCR asíncrono en aplicaciones web

Asprise no tiene una API asíncrona. Los desarrolladores lo integran en aplicaciones .NET asíncronas envolviendo llamadas sincrónicas en Task.Run, lo que consume hilos del grupo de hilos y no elimina el bloqueo.IronOCR proporciona una ruta asíncrona nativa.

Enfoque OCR de Asprise:

// Asprise: no async API — must offload to Task.Run
// This blocks a thread pool thread during the entire OCR operation
// On LITE/STANDARD, concurrent Task.Run calls = license violation
public async Task<string> ProcessUploadAsync(Stream fileStream, string fileName)
{
    string tempPath = Path.GetTempFileName();
    await using (var fs = new FileStream(tempPath, FileMode.Create))
        await fileStream.CopyToAsync(fs);

    // Task.Run wraps synchronous Asprise — occupies a thread pool thread
    // Two concurrent requests still violate LITE/STANDARD license
    return await Task.Run(() =>
    {
        Ocr ocr = new Ocr();
        try
        {
            ocr.StartEngine("eng", Ocr.SPEED_FAST);
            return ocr.Recognize(
                tempPath,
                Ocr.RECOGNIZE_TYPE_TEXT,
                Ocr.OUTPUT_FORMAT_PLAINTEXT);
        }
        finally
        {
            ocr.StopEngine();
            File.Delete(tempPath);
        }
    });
}
// Asprise: no async API — must offload to Task.Run
// This blocks a thread pool thread during the entire OCR operation
// On LITE/STANDARD, concurrent Task.Run calls = license violation
public async Task<string> ProcessUploadAsync(Stream fileStream, string fileName)
{
    string tempPath = Path.GetTempFileName();
    await using (var fs = new FileStream(tempPath, FileMode.Create))
        await fileStream.CopyToAsync(fs);

    // Task.Run wraps synchronous Asprise — occupies a thread pool thread
    // Two concurrent requests still violate LITE/STANDARD license
    return await Task.Run(() =>
    {
        Ocr ocr = new Ocr();
        try
        {
            ocr.StartEngine("eng", Ocr.SPEED_FAST);
            return ocr.Recognize(
                tempPath,
                Ocr.RECOGNIZE_TYPE_TEXT,
                Ocr.OUTPUT_FORMAT_PLAINTEXT);
        }
        finally
        {
            ocr.StopEngine();
            File.Delete(tempPath);
        }
    });
}
Imports System.IO
Imports System.Threading.Tasks

' Asprise: no async API — must offload to Task.Run
' This blocks a thread pool thread during the entire OCR operation
' On LITE/STANDARD, concurrent Task.Run calls = license violation
Public Async Function ProcessUploadAsync(fileStream As Stream, fileName As String) As Task(Of String)
    Dim tempPath As String = Path.GetTempFileName()
    Await Using fs As New FileStream(tempPath, FileMode.Create)
        Await fileStream.CopyToAsync(fs)
    End Using

    ' Task.Run wraps synchronous Asprise — occupies a thread pool thread
    ' Two concurrent requests still violate LITE/STANDARD license
    Return Await Task.Run(Function()
                              Dim ocr As New Ocr()
                              Try
                                  ocr.StartEngine("eng", Ocr.SPEED_FAST)
                                  Return ocr.Recognize(tempPath, Ocr.RECOGNIZE_TYPE_TEXT, Ocr.OUTPUT_FORMAT_PLAINTEXT)
                              Finally
                                  ocr.StopEngine()
                                  File.Delete(tempPath)
                              End Try
                          End Function)
End Function
$vbLabelText   $csharpLabel

Enfoque IronOCR:

// IronOCR: native async, concurrent requests permitted on all tiers
public async Task<string> ProcessUploadAsync(Stream fileStream, string fileName)
{
    using var input = new OcrInput();
    input.LoadImage(fileStream);       // Stream input directly — no temp file

    var ocr = new IronTesseract();
    var result = await ocr.ReadAsync(input);
    return result.Text;
}
// IronOCR: native async, concurrent requests permitted on all tiers
public async Task<string> ProcessUploadAsync(Stream fileStream, string fileName)
{
    using var input = new OcrInput();
    input.LoadImage(fileStream);       // Stream input directly — no temp file

    var ocr = new IronTesseract();
    var result = await ocr.ReadAsync(input);
    return result.Text;
}
Imports System.IO
Imports System.Threading.Tasks

' IronOCR: native async, concurrent requests permitted on all tiers
Public Async Function ProcessUploadAsync(fileStream As Stream, fileName As String) As Task(Of String)
    Using input As New OcrInput()
        input.LoadImage(fileStream) ' Stream input directly — no temp file

        Dim ocr As New IronTesseract()
        Dim result = Await ocr.ReadAsync(input)
        Return result.Text
    End Using
End Function
$vbLabelText   $csharpLabel

La versión de IronOCR elimina la escritura de archivos temporales, el envoltorio Task.Run, y el comportamiento de bloqueo de hilos. Múltiples solicitudes concurrentes cada una crea su propia instancia de IronTesseract — la clase es sin estado y cada instancia es independiente. La guía de OCR asíncrona cubre patrones ReadAsync y soporte para tokens de cancelación para operaciones por lotes de larga duración en servicios alojados.

Referencia de mapeo de la API OCR de Asprise a IronOCR

OCR Asprise Equivalente a IronOCR
asprise.ocr espacio de nombres IronOcr espacio de nombres
Ocr.SetUp() No es necesario
new Ocr() new IronTesseract()
ocr.StartEngine("eng", Ocr.SPEED_FAST) No es necesario
ocr.StartEngine("eng+fra", speed) ocr.Language = OcrLanguage.English + OcrLanguage.French
ocr.Recognize(path, type, format) ocr.Read(path) o ocr.Read(input)
Ocr.RECOGNIZE_TYPE_TEXT Comportamiento por defecto
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.Pages / result.Pages[n].Words
Ocr.OUTPUT_FORMAT_PDF result.SaveAsSearchablePdf(path)
Ocr.SPEED_FASTEST ocr.Configuration.TesseractEngineMode sintonización
Ocr.SPEED_FAST Configuración predeterminada
Ocr.SPEED_SLOW Configuración de mayor precisión
ocr.StopEngine() No requerido — OcrInput es IDisposable
result.StartsWith("ERROR:") chequeo Manejo de excepciones estándar de .NET (try/catch)
DLL nativa de la plataforma (aocr_x64.dll) Paquete de tiempo de ejecución NuGet (automático)
Archivo temporal manual para la entrada de flujo input.LoadImage(stream) directamente
Biblioteca externa para TIFF multifotograma input.LoadImageFrames(path)
Biblioteca externa para archivos PDF con capacidad de búsqueda. result.SaveAsSearchablePdf(path)

Problemas comunes de migración y soluciones

Problema 1: Excepción DllNotFoundException después de eliminar los binarios nativos.

Asprise OCR: Eliminar el paquete NuGet de Asprise pero dejar las referencias de binarios nativos (en reglas de copia de archivos del proyecto, instrucciones de Docker COPY o scripts de despliegue) puede causar que DllNotFoundException resurja desde una configuración obsoleta apuntando a un binario inexistente.

Solución: Buscar artefactos de despliegue para cualquier referencia a configuraciones aocr, libaocr, o LD_LIBRARY_PATH y eliminarlos.IronOCR no tiene ningún requisito de configuración correspondiente. En Dockerfile:

# Remove: COPY aocr_x64.dll /app/
# Remove: ENV LD_LIBRARY_PATH=/app
# IronOCR: nothing to add — NuGet handles native runtime packaging
RUN dotnet restore
RUN dotnet publish -c Release -o /app/publish

Para la implementación multiplataforma, la guía de implementación de Docker cubre los requisitos de imagen base para IronOCR en contenedores Linux.

Problema 2: Falta de eliminación de Ocr.SetUp() interrumpe el inicio

Asprise OCR: Ocr.SetUp() realiza una inicialización nativa global. Algunas bases de código lo llaman en un constructor estático o Startup.Configure. Después de la migración, eliminar el espacio de nombres Asprise elimina el error de compilación, pero si SetUp() está envuelto en un try/catch que suprime la excepción, el código puede compilarse y ejecutarse silenciosamente sin inicializar nada.

Solución: Usar grep para todas las llamadas SetUp() y eliminar todo el bloque de inicialización. Reemplace el gancho de inicio equivalente con la asignación de clave de licencia de IronOCR:

grep -rn "Ocr.SetUp\|StartEngine\|StopEngine" --include="*.cs" .
grep -rn "Ocr.SetUp\|StartEngine\|StopEngine" --include="*.cs" .
SHELL
// Remove all occurrences of the engine lifecycle pattern:
// Ocr.SetUp();
// ocr.StartEngine(...);
// ocr.StopEngine();

// Replace application startup initialization with:
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
// Remove all occurrences of the engine lifecycle pattern:
// Ocr.SetUp();
// ocr.StartEngine(...);
// ocr.StopEngine();

// Replace application startup initialization with:
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
$vbLabelText   $csharpLabel

Problema 3: El código de análisis de salida XML no tiene un reemplazo directo.

Asprise OCR: El código que analiza cadenas OUTPUT_FORMAT_XML usando XDocument, XmlReader, o patrones regex no tiene una estructura XML equivalente en IronOCR. El esquema XML que genera Asprise no se corresponde directamente con el modelo de objetos de IronOCR.

Solución: Reemplazar el código de análisis XML con acceso directo a propiedades en OcrResult. El mapeo es:

// Asprise XML parsing (remove)
var words = XDocument.Parse(xmlOutput)
    .Descendants("word")
    .Select(w => new { Text = (string)w.Attribute("text"), X = (int)w.Attribute("x") });

//IronOCR object model (replace with)
var result = new IronTesseract().Read(imagePath);
var words = result.Pages
    .SelectMany(p => p.Paragraphs)
    .SelectMany(para => para.Words)
    .Select(w => new { w.Text, w.X });
// Asprise XML parsing (remove)
var words = XDocument.Parse(xmlOutput)
    .Descendants("word")
    .Select(w => new { Text = (string)w.Attribute("text"), X = (int)w.Attribute("x") });

//IronOCR object model (replace with)
var result = new IronTesseract().Read(imagePath);
var words = result.Pages
    .SelectMany(p => p.Paragraphs)
    .SelectMany(para => para.Words)
    .Select(w => new { w.Text, w.X });
Imports System.Xml.Linq
Imports IronOcr

' Asprise XML parsing (remove)
Dim words = XDocument.Parse(xmlOutput) _
    .Descendants("word") _
    .Select(Function(w) New With {Key .Text = CType(w.Attribute("text"), String), Key .X = CType(w.Attribute("x"), Integer)})

' IronOCR object model (replace with)
Dim result = New IronTesseract().Read(imagePath)
Dim words = result.Pages _
    .SelectMany(Function(p) p.Paragraphs) _
    .SelectMany(Function(para) para.Words) _
    .Select(Function(w) New With {w.Text, w.X})
$vbLabelText   $csharpLabel

La guía de resultados de lectura abarca la jerarquía completa de objetos, incluidos los datos a nivel de caracteres con cuadros delimitadores.

Problema 4: Los envoltorios de Task.Run provocan el agotamiento del grupo de subprocesos.

Asprise OCR: Las aplicaciones web de alta concurrencia que envuelven Asprise en Task.Run pueden agotar el grupo de hilos cuando se incrementa el volumen de OCR. Cada Task.Run en cola mantiene un hilo del grupo de hilos durante toda la duración de la operación OCR.

Solución: Reemplazar Task.Run(() =&gt; { asprise... }) patrones con llamadas asíncronas nativas de IronOCR. Cada instancia IronTesseract es independiente — crea una por solicitud:

// Remove: await Task.Run(() => { ocr.Recognize(...) });

// Replace with:
using var input = new OcrInput();
input.LoadImage(stream);
var result = await new IronTesseract().ReadAsync(input);
return result.Text;
// Remove: await Task.Run(() => { ocr.Recognize(...) });

// Replace with:
using var input = new OcrInput();
input.LoadImage(stream);
var result = await new IronTesseract().ReadAsync(input);
return result.Text;
Imports IronTesseract

Using input As New OcrInput()
    input.LoadImage(stream)
    Dim result = Await (New IronTesseract()).ReadAsync(input)
    Return result.Text
End Using
$vbLabelText   $csharpLabel

Problema 5: Validación de códigos de lenguaje basada en cadenas de texto

Asprise OCR: Los códigos de lenguaje se pasan como cadenas ("eng", "fra", "eng+fra"). Las aplicaciones que validan estas cadenas en tiempo de ejecución — verificando contra una lista codificada, leyendo desde la configuración — necesitan actualizaciones cuando el formato de la cadena cambia al enum OcrLanguage.

Solución: Reemplazar los parámetros de lenguaje de cadena con valores de enum OcrLanguage. La selección de lengua impulsada por configuración se asigna claramente a Enum.Parse:

// Asprise string-based (remove)
string language = config["OcrLanguage"];  // e.g. "eng+fra"
ocr.StartEngine(language, Ocr.SPEED_FAST);

//IronOCR enum-based (replace with)
// For single language from config:
var ocr = new IronTesseract();
ocr.Language = Enum.Parse<OcrLanguage>(config["OcrLanguage"]);  // e.g. "English"
var result = ocr.Read(input);
// Asprise string-based (remove)
string language = config["OcrLanguage"];  // e.g. "eng+fra"
ocr.StartEngine(language, Ocr.SPEED_FAST);

//IronOCR enum-based (replace with)
// For single language from config:
var ocr = new IronTesseract();
ocr.Language = Enum.Parse<OcrLanguage>(config["OcrLanguage"]);  // e.g. "English"
var result = ocr.Read(input);
Imports System
Imports IronOcr

' Asprise string-based (remove)
Dim language As String = config("OcrLanguage")  ' e.g. "eng+fra"
ocr.StartEngine(language, Ocr.SPEED_FAST)

' IronOCR enum-based (replace with)
' For single language from config:
Dim ocr As New IronTesseract()
ocr.Language = [Enum].Parse(Of OcrLanguage)(config("OcrLanguage"))  ' e.g. "English"
Dim result = ocr.Read(input)
$vbLabelText   $csharpLabel

La guía de múltiples lenguas enumera todos los valores válidos de enum OcrLanguage y sus paquetes de paquetes de lenguaje de NuGet correspondientes.

Problema 6: Ya no es necesaria la lógica de verificación del nivel de licencia.

Asprise OCR: Algunos códigos de producción incluyen comprobaciones en tiempo de ejecución que detectan el nivel de licencia de Asprise y serializan el trabajo de OCR cuando se ejecuta por debajo de Enterprise. Estas medidas evitan infracciones de licencia, pero añaden complejidad y reducen el rendimiento.

Solución: Eliminar todas las protecciones de detección de niveles y serialización.IronOCR no tiene restricciones de subprocesos en ningún nivel. Los patrones ConcurrentQueue, SemaphoreSlim, o el despachador de un solo hilo usados para serializar llamadas de Asprise no sirven después de la migración:

// Remove: SemaphoreSlim _ocrLock = new SemaphoreSlim(1, 1);
// Remove: await _ocrLock.WaitAsync(); ... _ocrLock.Release();

// IronOCR: direct concurrent access, no guards needed
Parallel.ForEach(documentPaths, path =>
{
    var text = new IronTesseract().Read(path).Text;
    results[path] = text;
});
// Remove: SemaphoreSlim _ocrLock = new SemaphoreSlim(1, 1);
// Remove: await _ocrLock.WaitAsync(); ... _ocrLock.Release();

// IronOCR: direct concurrent access, no guards needed
Parallel.ForEach(documentPaths, path =>
{
    var text = new IronTesseract().Read(path).Text;
    results[path] = text;
});
Imports System.Threading.Tasks

' IronOCR: direct concurrent access, no guards needed
Parallel.ForEach(documentPaths, Sub(path)
    Dim text = (New IronTesseract()).Read(path).Text
    results(path) = text
End Sub)
$vbLabelText   $csharpLabel

Lista de verificación de migración de OCR de Asprise

Pre-Migración

Antes de escribir cualquier código de reemplazo, revise el código fuente para detectar cualquier uso de Asprise:

# Find all files importing asprise namespace
grep -rn "using asprise" --include="*.cs" .

# Find all engine lifecycle calls
grep -rn "SetUp\|StartEngine\|StopEngine" --include="*.cs" .

# Find all integer constant references
grep -rn "RECOGNIZE_TYPE\|OUTPUT_FORMAT\|SPEED_FAST\|SPEED_SLOW" --include="*.cs" .

# Find native binary references in project files and deployment scripts
grep -rn "aocr\|libaocr" --include="*.csproj" --include="Dockerfile" --include="*.yml" .

# Find XML output parsing code
grep -rn "OUTPUT_FORMAT_XML\|XDocument.Parse\|Descendants.*word" --include="*.cs" .

# Find Task.Run wrappers around OCR calls
grep -rn "Task.Run.*ocr\|Task.Run.*Recognize" --include="*.cs" .
# Find all files importing asprise namespace
grep -rn "using asprise" --include="*.cs" .

# Find all engine lifecycle calls
grep -rn "SetUp\|StartEngine\|StopEngine" --include="*.cs" .

# Find all integer constant references
grep -rn "RECOGNIZE_TYPE\|OUTPUT_FORMAT\|SPEED_FAST\|SPEED_SLOW" --include="*.cs" .

# Find native binary references in project files and deployment scripts
grep -rn "aocr\|libaocr" --include="*.csproj" --include="Dockerfile" --include="*.yml" .

# Find XML output parsing code
grep -rn "OUTPUT_FORMAT_XML\|XDocument.Parse\|Descendants.*word" --include="*.cs" .

# Find Task.Run wrappers around OCR calls
grep -rn "Task.Run.*ocr\|Task.Run.*Recognize" --include="*.cs" .
SHELL

Inventarie los resultados:

  • Cuenta los archivos que importan asprise.ocr — todos necesitan actualizaciones de espacio de nombres.
  • Lista cada sitio de llamada de StartEngine — cada uno se convierte en una llamada Read.
  • Identificar el código de análisis de salida XML: cada bloque necesita ser reemplazado por un modelo de objetos.
  • Tenga en cuenta cualquier protección de nivel de licencia o envoltorio de serialización; estos se pueden eliminar.
  • Localizar los scripts de despliegue binario nativos y la configuración del contenedor.

Migración de código

  1. Eliminar el paquete NuGet de asprise-ocr-api de todos los proyectos.
  2. Instalar el paquete NuGet IronOcr en cada proyecto que realice OCR.
  3. Reemplaza using asprise.ocr con using IronOcr en todos los archivos.
  4. Agregar IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY" al inicio de la aplicación.
  5. Eliminar llamadas Ocr.SetUp() de todo el código de inicio e inicialización.
  6. Reemplazar cada bloque Ocr.StartEngine / Recognize / StopEngine con new IronTesseract().Read(path).Text.
  7. Reemplaza bloques de análisis OUTPUT_FORMAT_XML con recorrido de objetos result.Pages.
  8. Reemplazar soluciones alternativas OUTPUT_FORMAT_PDF con result.SaveAsSearchablePdf(path).
  9. Reemplazar código de división de TIFF de múltiples cuadros con input.LoadImageFrames(tiffPath).
  10. Reemplazar envolturas basadas en flujo Task.Run con await ocr.ReadAsync(input).
  11. Eliminar SemaphoreSlim o guardias de serialización que protegían Asprise del uso concurrente.
  12. Eliminar instrucciones de copia de binarios nativos de archivos .csproj y Dockerfiles.
  13. Eliminar configuraciones LD_LIBRARY_PATH de la configuración del entorno y scripts de CI.
  14. Reemplazar códigos de lenguaje de cadena ("eng", "eng+fra") con valores de enum OcrLanguage.
  15. Reemplazar pruebas result.StartsWith("ERROR:") con bloques try/catch.

Posmigración

  • Verificar que dotnet build completa sin advertencias sobre bibliotecas nativas faltantes.
  • Confirmar que no ocurre DllNotFoundException o BadImageFormatException al inicio en todos los entornos objetivo (Windows, Linux, Docker).
  • Ejecutar el OCR en una imagen representativa y confirmar que el texto resultante coincide con la línea base previa a la migración.
  • Pruebe el procesamiento de TIFF multifotograma y verifique que todas las páginas se devuelvan con los números de página correctos.
  • Generar un PDF con capacidad de búsqueda y verificar que el texto se pueda seleccionar y buscar en un visor de PDF.
  • Enviar solicitudes HTTP simultáneas a cualquier punto final de la API que llame a OCR y confirmar que todas las solicitudes se completen sin errores.
  • Verificar que los puntos finales asíncronos devuelvan resultados sin interbloqueo bajo carga concurrente
  • Confirmar que la extracción de datos estructurados (coordenadas de palabras y nivel de confianza) produce un resultado correcto en un documento conocido.
  • Verificar el uso de memoria de la aplicación a lo largo del tiempo para confirmar que no hay fugas de memoria nativa (anteriormente causadas por llamadas a StopEngine() olvidadas).
  • Ejecute la aplicación en Linux o en un contenedor Docker para confirmar que la implementación multiplataforma funciona sin configuración binaria.

Principales ventajas de migrar a IronOCR

La implementación se reduce a una única referencia NuGet . Tras la migración, todos los destinos de implementación (estaciones de trabajo de desarrollo, servidores de prueba, contenedores Linux, agentes de CI) instalan el mismo paquete con el mismo comando. No existe lógica de detección de plataforma, ni selección de binarios específicos de la arquitectura, ni configuración de ruta de ejecución. Una imagen de Docker que antes requería instrucciones de COPY manual de binario nativo ahora no requiere nada más allá de dotnet restore. La guía de implementación de Linux y la guía de implementación de Azure incluyen notas específicas del entorno cuando corresponda.

Todos los niveles de licencia desbloquean la implementación de servidor. La licencia Lite $999 admite ASP.NET Core Web APIs, Servicios de Windows, Funciones de Azure, AWS Lambda y cualquier otra carga de trabajo .NET multi-hilo. La capacidad de subprocesos de nivel EMPRESARIAL por la que Asprise cobra entre 2000 y 5000 dólares o más está incluida en todos los niveles de IronOCR. Los equipos que migran de Asprise Enterprise a IronOCR Lite reducen sus costos de licencias de OCR al tiempo que obtienen capacidades que Enterprise no proporcionaba: PDF nativo, salida estructurada, generación de PDF con capacidad de búsqueda y 125 idiomas.

Resultados de OCR estructurados reemplazan el análisis de cadenas XML. El modelo de objeto OcrResult expone una jerarquía completa de documentos: páginas, párrafos, líneas, palabras y caracteres, cada uno con coordenadas de caja delimitadora precisas en píxeles y puntajes de confianza. El código que anteriormente analizaba las cadenas XML de Asprise con XDocument o expresiones regulares ahora accede directamente a las propiedades. La página de resultados de OCR incluye información sobre sistemas de coordenadas y cómo filtrar los resultados por nivel de confianza para los controles de calidad automatizados.

El preprocesamiento incorporado elimina las dependencias de imagen externas. El pipeline de preprocesamiento disponible a través de OcrInputDeskew, DeNoise, Contrast, Binarize, Sharpen, Dilate, Erode, Scale, Invert, y DeepCleanBackgroundNoise — elimina la biblioteca de imágenes externa que las integraciones de Asprise requieren. Eliminar esa dependencia elimina una preocupación de licencia, reduce la huella de construcción, y coloca la configuración de preprocesamiento directamente adyacente a la configuración de OCR en el mismo archivo de código. La página de características de preprocesamiento y la guía de corrección de calidad de imagen cubren cuándo aplicar cada filtro y las ganancias de precisión medibles que cada uno proporciona en escaneos de baja calidad.

Async nativo y verdadero paralelismo mejoran el rendimiento. ReadAsync se integra en el patrón estándar async/await sin bloqueo del grupo de hilos. El procesamiento por lotes paralelo con Parallel.ForEach o PLINQ se escala linealmente con los núcleos disponibles. Un lote de documentos que Asprise Lite/STANDARD forzó a ejecutar de forma secuencial (100 documentos a 2 segundos cada uno tardan más de 3 minutos) se ejecuta en aproximadamente 25 segundos en una máquina de 8 núcleos con IronOCR. El ejemplo de multithreading demuestra patrones de rendimiento paralelo y muestra cómo usar ConcurrentBag para la recolección de resultados seguros para hilos.

125+ idiomas sin distribución binaria. Los paquetes de idiomas se instalan como paquetes NuGet — dotnet add package IronOcr.Languages.Arabic, dotnet add package IronOcr.Languages.Japanese — y se despliegan con la aplicación como cualquier otra dependencia. No es necesario rellenar manualmente la carpeta tessdata, localizar el archivo binario del idioma ni configurar la ruta en la máquina de destino. El índice de idiomas incluye los más de 125 paquetes de idiomas disponibles.

Por favor notaAsprise OCR, PDFSharp, Tesseract e iText son marcas registradas de sus respectivos propietarios. Este sitio no está afiliado, respaldado ni patrocinado por Asprise, Google, empira Software GmbH, o iText Group. Todos los nombres de productos, logotipos y marcas son propiedad de sus respectivos propietarios. Las comparaciones son solo para fines informativos y reflejan información públicamente disponible en el momento de la redacción.

Preguntas Frecuentes

¿Por qué debería migrar de Asprise OCR SDK a IronOCR?

Los impulsores comunes incluyen la eliminación de la complejidad de la interoperabilidad COM, la sustitución de la gestión de licencias basada en archivos, la evitación de la facturación por página, la habilitación de la implementación de Docker/contenedores y la adopción de un flujo de trabajo nativo de NuGet que se integre con las herramientas .NET estándar.

¿Cuáles son los principales cambios en el código al migrar de Asprise OCR SDK a IronOCR?

Sustituya las secuencias de inicialización de Asprise OCR por la instanciación de IronTesseract, elimine la gestión del ciclo de vida COM (patrones explícitos Create/Load/Close) y actualice los nombres de las propiedades de los resultados. El resultado es un número significativamente menor de líneas repetitivas.

¿Cómo instalo IronOCR para comenzar la migración?

Ejecute 'Install-Package IronOcr' en la consola del gestor de paquetes o 'dotnet add package IronOcr' en la CLI. Los paquetes de idiomas son paquetes independientes: 'dotnet add package IronOcr.Languages.French' para el francés, por ejemplo.

¿IronOCR ofrece la misma precisión de reconocimiento óptico de caracteres que Asprise OCR SDK para documentos comerciales estándar?

IronOCR consigue una gran precisión para contenido empresarial estándar, como facturas, contratos, recibos y formularios mecanografiados. Los filtros de preprocesamiento de imágenes (eliminación de distorsiones, eliminación de ruido, mejora del contraste) mejoran aún más el reconocimiento en entradas degradadas.

¿Cómo gestiona IronOCR los datos de idioma que Asprise OCR SDK instala por separado?

Los datos de idiomas en IronOCR se distribuyen como paquetes NuGet. dotnet add package IronOcr.Languages.German' instala la compatibilidad con el alemán. No es necesario colocar manualmente los archivos ni las rutas de los directorios.

¿La migración de Asprise OCR SDK a IronOCR requiere cambios en la infraestructura de implementación?

IronOCR requiere menos cambios de infraestructura que Asprise OCR SDK. No hay rutas binarias del SDK, ubicaciones de archivos de licencia ni configuraciones del servidor de licencias. El paquete NuGet contiene el motor OCR completo, y la clave de licencia es una cadena establecida en el código de la aplicación.

¿Cómo configuro las licencias de IronOCR después de la migración?

Asigne IronOcr.License.LicenseKey = "YOUR-KEY" en el código de inicio de la aplicación. En Docker o Kubernetes, almacene la clave como una variable de entorno y léala en el inicio. Utilice License.IsValidLicense para validar antes de aceptar tráfico.

¿Puede IronOCR procesar archivos PDF del mismo modo que Asprise OCR?

Sí, IronOCR lee PDF nativos y escaneados. Instancie IronTesseract, llame a ocr.Read(input) donde input es una ruta PDF u OcrPdfInput, e itere las páginas OcrResult. No es necesario un proceso de renderizado de PDF independiente.

¿Cómo gestiona IronOCR los hilos en el procesamiento de grandes volúmenes?

IronTesseract puede instanciarse de forma segura por subproceso. Gire una instancia por hilo en un Parallel.ForEach o Task pool, ejecute OCR concurrentemente, y disponga de cada instancia cuando termine. No se requiere estado global o bloqueo.

¿Qué formatos de salida admite IronOCR tras la extracción de texto?

IronOCR devuelve resultados estructurados que incluyen texto, coordenadas de palabras, puntuaciones de confianza y estructura de páginas. Las opciones de exportación incluyen texto sin formato, PDF con opción de búsqueda y objetos de resultados estructurados para su procesamiento posterior.

¿Es el precio de IronOCR más predecible que el de Asprise OCR SDK para escalar cargas de trabajo?

IronOCR utiliza licencias perpetuas de tarifa plana sin cargos por página o volumen. Tanto si procesa 10.000 como 10 millones de páginas, el coste de la licencia permanece constante. Las opciones de licencias por volumen y por equipo se encuentran en la página de precios de IronOCR.

¿Qué sucede con mis pruebas existentes después de migrar de Asprise OCR SDK a IronOCR?

Las pruebas que validan el contenido de texto extraído deben seguir superándose tras la migración. Las pruebas que validan patrones de llamada a API o el ciclo de vida de objetos COM deberán actualizarse para reflejar el modelo de inicialización y resultados más sencillo de IronOCR.

Kannaopat Udonpant
Ingeniero de Software
Antes de convertirse en Ingeniero de Software, Kannapat completó un doctorado en Recursos Ambientales de la Universidad de Hokkaido en Japón. Mientras perseguía su grado, Kannapat también se convirtió en miembro del Laboratorio de Robótica de Vehículos, que es parte del Departamento de Ingeniería ...
Leer más

Equipo de soporte de Iron

Estamos disponibles online las 24 horas, 5 días a la semana.
Chat
Email
Llámame