Saltar al contenido principal
Al trabajar con documentos en papel, es necesario encontrar y corregir errores o cambios realizados intencionadamente. Use la API de comparación de documentos para localizar estos cambios de forma rápida y eficaz. Este escenario se utiliza para comparar documentos de especial importancia, como contratos y documentación bancaria, con sus copias. El resultado de la comparación contiene información sobre las diferencias en el tipo de contenido (solo texto), el tipo de modificación (eliminado, insertado o modificado) y su ubicación en el original y en la copia. Puede obtener la lista de diferencias detectadas o la región de cualquier cambio, y guardar el resultado de la comparación en un archivo externo para su posterior procesamiento o almacenamiento a largo plazo. Para comparar documentos o páginas, los archivos obtenidos mediante escaneo o guardados en formato electrónico suelen pasar por varias etapas de procesamiento, cada una con sus propias particularidades:
  1. Preprocesamiento de archivos escaneados o imágenes
Los archivos y sus copias requieren cierto preprocesamiento antes del reconocimiento si presentan defectos o anotaciones hechas intencionadamente, como firmas o sellos.
  1. Reconocimiento con restauración completa de la estructura y el formato del documento
Al reconocer un documento, se identifican varios elementos de diseño (texto, tablas, imágenes, separadores, etc.) del documento. Durante la síntesis del documento, se restaura su estructura lógica, mientras que la síntesis de la página permite restaurar por completo el formato del documento (fuentes, estilos, etc.)
  1. Comparación de documentos o páginas
Para comparar documentos o páginas con sus copias, use archivos reconocidos con ABBYY FineReader Engine. Puede usar dos versiones de un documento en formatos distintos. Tras la comparación, obtendrá un resultado con la lista de cambios; úselo para recuperar información sobre la ubicación de esos cambios. Si utiliza verificación manual, use esta información para resaltar los cambios en el texto y facilitar así el trabajo del operador.
  1. Exportación a un formato externo
También puede guardar el resultado de la comparación en formato XML y DOCX. El procedimiento descrito a continuación también se ilustra con el ejemplo Document Comparison para Linux y macOS, y con la herramienta de demostración para Windows Document Comparison.

Implementación del escenario

Los ejemplos de código proporcionados en este tema son específicos de Windows.
A continuación, se ofrece una descripción detallada del método recomendado para utilizar ABBYY FineReader Engine en este escenario.
Para empezar a trabajar con ABBYY FineReader Engine, debe crear el objeto Engine. El objeto Engine es el objeto superior en la jerarquía de objetos de ABBYY FineReader Engine y proporciona varias configuraciones globales, algunos métodos de procesamiento y métodos para crear los demás objetos.Para crear el objeto Engine, puede usar la función InitializeEngine. Consulte también otras formas de cargar el objeto Engine (Win).

C#

public class EngineLoader : IDisposable
{
    public EngineLoader()
    {
        // Inicialice estas variables con la ruta completa a FREngine.dll, su Customer Project ID,
        // y, si corresponde, la ruta al archivo de token de Online License y la contraseña de Online License
        string enginePath = "";
        string customerProjectId = "";
        string licensePath = "";
        string licensePassword = "";
        // Cargue la biblioteca FREngine.dll
        dllHandle = LoadLibraryEx(enginePath, IntPtr.Zero, LOAD_WITH_ALTERED_SEARCH_PATH);
           
        try
        {
            if (dllHandle == IntPtr.Zero)
            {
                throw new Exception("Can't load " + enginePath);
            }
            IntPtr initializeEnginePtr = GetProcAddress(dllHandle, "InitializeEngine");
            if (initializeEnginePtr == IntPtr.Zero)
            {
                throw new Exception("Can't find InitializeEngine function");
            }
            IntPtr deinitializeEnginePtr = GetProcAddress(dllHandle, "DeinitializeEngine");
            if (deinitializeEnginePtr == IntPtr.Zero)
            {
                throw new Exception("Can't find DeinitializeEngine function");
            }
            IntPtr dllCanUnloadNowPtr = GetProcAddress(dllHandle, "DllCanUnloadNow");
            if (dllCanUnloadNowPtr == IntPtr.Zero)
            {
                throw new Exception("Can't find DllCanUnloadNow function");
            }
            // Convierta los punteros en delegados
            initializeEngine = (InitializeEngine)Marshal.GetDelegateForFunctionPointer(
                initializeEnginePtr, typeof(InitializeEngine));
            deinitializeEngine = (DeinitializeEngine)Marshal.GetDelegateForFunctionPointer(
                deinitializeEnginePtr, typeof(DeinitializeEngine));
            dllCanUnloadNow = (DllCanUnloadNow)Marshal.GetDelegateForFunctionPointer(
                dllCanUnloadNowPtr, typeof(DllCanUnloadNow));
            // Llame a la función InitializeEngine 
            // y pase la ruta al archivo de Online License y la contraseña de Online License
            int hresult = initializeEngine(customerProjectId, licensePath, licensePassword, 
                "", "", false, ref engine);
            Marshal.ThrowExceptionForHR(hresult);
        }
        catch (Exception)
        {
            // Libere la biblioteca FREngine.dll
            engine = null;
            // Elimine todos los objetos antes de llamar a FreeLibrary
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();
            FreeLibrary(dllHandle);
            dllHandle = IntPtr.Zero;
            initializeEngine = null;
            deinitializeEngine = null;
            dllCanUnloadNow = null;
            throw;
        }
    }
    // Funciones de Kernel32.dll
    [DllImport("kernel32.dll")]
    private static extern IntPtr LoadLibraryEx(string dllToLoad, IntPtr reserved, uint flags);
    private const uint LOAD_WITH_ALTERED_SEARCH_PATH = 0x00000008;
    [DllImport("kernel32.dll")]
    private static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);
    [DllImport("kernel32.dll")]
    private static extern bool FreeLibrary(IntPtr hModule);
    // Funciones de FREngine.dll
    [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode)]
    private delegate int InitializeEngine(string customerProjectId, string licensePath, 
        string licensePassword, string tempFolder, string dataFolder, bool isSharedCPUCoresMode, 
        ref FREngine.IEngine engine);
    [UnmanagedFunctionPointer(CallingConvention.StdCall)]
    private delegate int DeinitializeEngine();
    [UnmanagedFunctionPointer(CallingConvention.StdCall)]
    private delegate int DllCanUnloadNow();
    // Variables privadas
    private FREngine.IEngine engine = null;
    // Identificador de FREngine.dll
    private IntPtr dllHandle = IntPtr.Zero;
    private InitializeEngine initializeEngine = null;
    private DeinitializeEngine deinitializeEngine = null;
    private DllCanUnloadNow dllCanUnloadNow = null;
}
ABBYY FineReader Engine proporciona el objeto FRDocument, que permite procesar documentos de varias páginas. El uso de este objeto le permite conservar la organización lógica del documento y mantener el texto original, así como las columnas, fuentes, estilos, etc. Use el objeto FRPage si desea comparar páginas.Para cargar imágenes de un solo documento y preprocesarlas, debe crear el objeto FRDocument y agregarle las imágenes. Puede hacerlo de una de las siguientes maneras:

C#

// Crear el objeto FRDocument a partir de un archivo de imagen
FREngine.IFRDocument frDocument = engine.CreateFRDocumentFromImage( "C:\\MyImage.tif", null );
Para reconocer un documento, le recomendamos usar los métodos de análisis y reconocimiento del objeto FRDocument. Este objeto proporciona toda una serie de métodos para analizar, reconocer y sintetizar documentos. El método más práctico, que integra en una sola operación el análisis, el reconocimiento y la síntesis del documento, es Process. Además, aprovecha de la forma más eficiente las funciones de procesamiento simultáneo de los sistemas multiprocesador y multinúcleo. No obstante, también puede realizar de forma secuencial el preprocesamiento, el análisis, el reconocimiento y la síntesis mediante los métodos Preprocess, Analyze, Recognize y Synthesize.
Puede establecer los parámetros de reconocimiento para sus documentos cargando un profile predefinido adecuado (consulte Working with Profiles para obtener más información).

C#

// Procesar el documento con los parámetros predeterminados
// Puede cambiarlos si es necesario; por ejemplo, cargando previamente un profile
frDocument.Process( null );
Para comparar los documentos o páginas con sus copias:
  1. Asegúrese de que su licencia de ABBYY FineReader Engine sea compatible con el módulo Compare Documents.
  2. Cree un objeto Comparator mediante el método CreateComparator del objeto Engine.
  3. [opcional] Use el objeto ComparisonParams para configurar las propiedades con los valores que necesite.
  4. Llame al método CompareDocuments del objeto Comparator para comparar el documento original con la copia. Recibirá un objeto ComparisonResult que contiene información sobre los cambios detectados.

C#

// Realizar la comparación de los documentos 
FREngine.IComparator comparator = engine.CreateComparator();
FREngine.IComparisonResult comparatorResult = 
    comparator.CompareDocuments( referenceFRDocument, userFRDocument, null, null );
El objeto ComparisonResult contiene la lista completa de diferencias y proporciona métodos para obtener las diferencias de páginas concretas. Puede acceder a los cambios del documento original y de su copia con los métodos GetChangesForReferencePage y GetChangesForUserPage. Use el objeto ChangeLocation para obtener información sobre la ubicación del cambio y su propiedad RegionForPage para obtener la región del cambio en la página especificada.

C#

// Obtener información sobre la modificación detectada y su ubicación en el documento original
FREngine.IChanges changes = comparatorResult.Changes;
foreach( FREngine.IChange change in changes ) {
      FREngine.ModificationTypeEnum modificationType = change.ModificationType;
      FREngine.IChangeLocation referenceLocation = change.ReferenceLocation;
      // Ahora puede resaltar estos cambios en la página para que un operador los revise
      ... 
}
Para exportar el resultado de la comparación, llame al método Export del objeto ComparisonResult y pase la ruta del archivo como parámetro de entrada. Los datos pueden guardarse en XML o en un archivo DOCX con control de cambios.C#
// Guardar en formato XML
comparisonResult.Export( "C:\\ComparisonResult.xml", FREngine.ComparatorExportFormatEnum.CEF_Xml, null );
Después de terminar de trabajar con ABBYY FineReader Engine, debe descargar el objeto Engine. Para ello, use la función exportada DeinitializeEngine.

C#

public class EngineLoader : IDisposable
{
    // Descargar FineReader Engine
    public void Dispose()
    {
        if (engine == null)
        {
            // El Engine no se cargó
            return;
        }
        engine = null;
        // Eliminar todos los objetos antes de llamar a FreeLibrary
        GC.Collect();
        GC.WaitForPendingFinalizers();
        GC.Collect();
        int hresult = deinitializeEngine();
 
        hresult = dllCanUnloadNow();
        if (hresult == 0)
        {
            FreeLibrary(dllHandle);
        }
        dllHandle = IntPtr.Zero;
        initializeEngine = null;
        deinitializeEngine = null;
        dllCanUnloadNow = null;
        // lanzar la excepción después de la limpieza
        Marshal.ThrowExceptionForHR(hresult);
    }
    // Funciones de Kernel32.dll
    [DllImport("kernel32.dll")]
    private static extern IntPtr LoadLibraryEx(string dllToLoad, IntPtr reserved, uint flags);
    private const uint LOAD_WITH_ALTERED_SEARCH_PATH = 0x00000008;
    [DllImport("kernel32.dll")]
    private static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);
    [DllImport("kernel32.dll")]
    private static extern bool FreeLibrary(IntPtr hModule);
    // Funciones de FREngine.dll
    [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode)]
    private delegate int InitializeEngine( string customerProjectId, string LicensePath, string LicensePassword, , , , ref FREngine.IEngine engine);
    [UnmanagedFunctionPointer(CallingConvention.StdCall)]
    private delegate int DeinitializeEngine();
    [UnmanagedFunctionPointer(CallingConvention.StdCall)]
    private delegate int DllCanUnloadNow();
    // Variables privadas
    private FREngine.IEngine engine = null;
    // Handle de FREngine.dll
    private IntPtr dllHandle = IntPtr.Zero;
    private InitializeEngine initializeEngine = null;
    private DeinitializeEngine deinitializeEngine = null;
    private DllCanUnloadNow dllCanUnloadNow = null;
}

Recursos necesarios

Puede usar el archivo FREngineDistribution.csv para crear automáticamente una lista de los archivos necesarios para que su aplicación funcione. Para procesar con este escenario, seleccione en la columna 5 (RequiredByModule) los siguientes valores: Core Core.Resources Opening Opening, Processing Processing Processing.OCR Processing.OCR, Processing.ICR Processing.OCR.NaturalLanguages Processing.OCR.NaturalLanguages, Processing.ICR.NaturalLanguages Export Export, Processing Si modifica el escenario estándar, cambie los módulos necesarios en consecuencia. También debe especificar los idiomas de la interfaz, los idiomas de reconocimiento y cualquier función adicional que use su aplicación (como, por ejemplo, Opening.PDF si necesita abrir archivos PDF, o Processing.OCR.CJK si necesita reconocer textos en idiomas CJK). Consulte Working with the FREngineDistribution.csv File para obtener más información.

Optimización adicional para tareas específicas

A continuación se ofrece una visión general de los temas de Ayuda que contienen información adicional sobre cómo personalizar la configuración en distintas etapas del procesamiento:
  • Escaneo: solo para Windows
    • Escaneo
      Descripción del escenario de ABBYY FineReader Engine para el escaneo de documentos.
  • Reconocimiento
    • Ajuste de los parámetros de preprocesamiento, análisis, reconocimiento y síntesis
      Personalización del procesamiento de documentos mediante objetos de parámetros de análisis, reconocimiento y síntesis.
    • PageProcessingParams Object
      Este objeto permite personalizar los parámetros de análisis y reconocimiento. Con este objeto, puede indicar qué características de la imagen y del texto deben detectarse (imagen invertida, orientación, códigos de barras, idioma de reconocimiento, margen de error de reconocimiento).
    • SynthesisParamsForPage Object
      Este objeto incluye parámetros responsables de restaurar el formato de una página durante la síntesis.
    • SynthesisParamsForDocument Object
      Este objeto permite personalizar la síntesis del documento: restaurar su estructura y formato.
    • MultiProcessingParams Object - Implementado para Linux y Windows
      El procesamiento simultáneo puede resultar útil al procesar una gran cantidad de imágenes. En este caso, la carga de procesamiento se distribuirá entre los núcleos del procesador durante la apertura y el preprocesamiento de las imágenes, el análisis del diseño, el reconocimiento y la exportación, lo que permite acelerar el procesamiento.
      Los modos de lectura (simultáneo o consecutivo) se configuran mediante la propiedad MultiProcessingMode. La propiedad RecognitionProcessesCount controla la cantidad de procesos que pueden iniciarse.

Consulte también

Implementación de escenarios de uso básicos