Quando si lavora con documenti cartacei, è necessario individuare e correggere errori o modifiche apportate intenzionalmente. Utilizza l’API Document Comparison per cercare queste modifiche in modo rapido ed efficiente.Questo scenario viene utilizzato per confrontare documenti di particolare importanza, come contratti e documentazione bancaria, con le rispettive copie. Il risultato del confronto contiene informazioni sulle differenze relative al tipo di contenuto (solo testo), al tipo di modifica (eliminata, inserita o modificata) e alla loro posizione nell’originale e nella copia. Puoi ottenere l’elenco delle differenze rilevate oppure l’area interessata da una qualsiasi modifica e salvare il risultato del confronto in un file esterno per ulteriori elaborazioni o per l’archiviazione a lungo termine.Per confrontare documenti o pagine, i file acquisiti tramite scansione o salvati in formato elettronico passano in genere attraverso diverse fasi di elaborazione, ciascuna con caratteristiche specifiche:
Preelaborazione di file o immagini acquisiti tramite scansione
I file e le relative copie richiedono una fase di preelaborazione prima del riconoscimento, se presentano difetti o annotazioni apposte intenzionalmente, come firme o timbri.
Riconoscimento con ripristino completo della struttura e della formattazione del documento
Durante il riconoscimento di un documento, vengono identificati vari elementi di layout del documento (testo, tabelle, immagini, separatori e così via). Nel corso della sintesi del documento, ne viene ripristinata la struttura logica, mentre la sintesi della pagina consente di ripristinarne completamente la formattazione (font, stili e così via)
Confronto di documenti o pagine
Per confrontare documenti o pagine con le rispettive copie, utilizza i file riconosciuti con ABBYY FineReader Engine. Puoi utilizzare due versioni dello stesso documento anche in formati diversi. Al termine del confronto, otterrai il risultato con l’elenco delle modifiche: usalo per recuperare le informazioni sulla posizione delle modifiche. Se utilizzi la verifica manuale, usa queste informazioni per evidenziare le modifiche nel testo, semplificando il lavoro dell’operatore.
Esportazione in un formato esterno
Puoi anche salvare il risultato del confronto nei formati XML e DOCX.La procedura descritta di seguito è illustrata anche nell’esempio Document Comparison per Linux e macOS e nello strumento demo Document Comparison per Windows.
Gli esempi di codice forniti in questo argomento sono specifici per Windows.
Di seguito è riportata una descrizione dettagliata del metodo consigliato per l’utilizzo di ABBYY FineReader Engine in questo scenario.
Passaggio 1. Caricamento di ABBYY FineReader Engine
Per iniziare a lavorare con ABBYY FineReader Engine, è necessario creare l’oggetto Engine. L’oggetto Engine è l’oggetto principale nella gerarchia degli oggetti di ABBYY FineReader Engine e fornisce varie impostazioni globali, alcuni metodi di elaborazione e metodi per creare gli altri oggetti.Per creare l’oggetto Engine, è possibile utilizzare la funzione InitializeEngine. Vedere anche altri modi per caricare l’oggetto Engine (Win).
public class EngineLoader : IDisposable{ public EngineLoader() { // Inizializzare queste variabili con il percorso completo di FREngine.dll, il Customer Project ID, // e, se applicabile, il percorso del file del token Online License e la password di Online License string enginePath = ""; string customerProjectId = ""; string licensePath = ""; string licensePassword = ""; // Carica la libreria 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"); } // Converte i puntatori in delegati initializeEngine = (InitializeEngine)Marshal.GetDelegateForFunctionPointer( initializeEnginePtr, typeof(InitializeEngine)); deinitializeEngine = (DeinitializeEngine)Marshal.GetDelegateForFunctionPointer( deinitializeEnginePtr, typeof(DeinitializeEngine)); dllCanUnloadNow = (DllCanUnloadNow)Marshal.GetDelegateForFunctionPointer( dllCanUnloadNowPtr, typeof(DllCanUnloadNow)); // Chiama la funzione InitializeEngine // passando il percorso del file Online License e la password di Online License int hresult = initializeEngine(customerProjectId, licensePath, licensePassword, "", "", false, ref engine); Marshal.ThrowExceptionForHR(hresult); } catch (Exception) { // Libera la libreria FREngine.dll engine = null; // Elimina tutti gli oggetti prima della chiamata a FreeLibrary GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); FreeLibrary(dllHandle); dllHandle = IntPtr.Zero; initializeEngine = null; deinitializeEngine = null; dllCanUnloadNow = null; throw; } } // Funzioni di 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); // Funzioni di 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(); // Variabili private private FREngine.IEngine engine = null; // Handle di FREngine.dll private IntPtr dllHandle = IntPtr.Zero; private InitializeEngine initializeEngine = null; private DeinitializeEngine deinitializeEngine = null; private DllCanUnloadNow dllCanUnloadNow = null;}
Passaggio 2. Caricamento e preelaborazione di file e immagini
ABBYY FineReader Engine mette a disposizione l’oggetto FRDocument, che consente di elaborare documenti multipagina. L’uso di questo oggetto permette di preservare l’organizzazione logica del documento, mantenendo il testo originale, le colonne, i font, gli stili e così via. Usa l’oggetto FRPage se vuoi confrontare le pagine.Per caricare le immagini di un singolo documento e preelaborarle, devi creare l’oggetto FRDocument e aggiungervi le immagini. Puoi procedere in uno dei modi seguenti:
Creare l’oggetto FRDocument usando il metodo CreateFRDocumentFromImage dell’oggetto Engine. Questo metodo crea l’oggetto FRDocument e carica le immagini dal file specificato.
// Crea l'oggetto FRDocument da un file immagineFREngine.IFRDocument frDocument = engine.CreateFRDocumentFromImage( "C:\\MyImage.tif", null );
Passaggio 3. Riconoscimento del documento
Per riconoscere un documento, consigliamo di usare i metodi di analisi e riconoscimento dell’oggetto FRDocument. Questo oggetto offre un’ampia gamma di metodi per l’analisi, il riconoscimento e la sintesi del documento. Il metodo più pratico, che riunisce analisi, riconoscimento e sintesi in un’unica operazione, è Process. Inoltre, sfrutta nel modo più efficiente le funzionalità di elaborazione simultanea dei sistemi multiprocessore e multicore. Tuttavia, puoi anche eseguire in sequenza preelaborazione, analisi, riconoscimento e sintesi usando i metodi Preprocess, Analyze, Recognize e Synthesize. Puoi impostare i parametri di riconoscimento per i tuoi documenti caricando un profilo predefinito appropriato (per maggiori informazioni, vedi Working with Profiles).
[facoltativo] Usa l’oggetto ComparisonParams per impostare le proprietà con i valori desiderati.
Chiama il metodo CompareDocuments dell’oggetto Comparator per confrontare il documento originale con la copia. Riceverai un oggetto ComparisonResult contenente informazioni sulle modifiche rilevate.
// Esegue il confronto dei documenti FREngine.IComparator comparator = engine.CreateComparator();FREngine.IComparisonResult comparatorResult = comparator.CompareDocuments( referenceFRDocument, userFRDocument, null, null );
Passaggio 5. Utilizzo delle modifiche rilevate
L’oggetto ComparisonResult contiene l’elenco completo delle differenze e fornisce metodi per ottenere le differenze per le singole pagine. Puoi accedere alle modifiche del documento originale e della relativa copia con i metodi GetChangesForReferencePage e GetChangesForUserPage. Usa l’oggetto ChangeLocation per ottenere informazioni sulla posizione della modifica e la relativa proprietà RegionForPage per ottenere l’area della modifica nella pagina specificata.
// Ottiene le informazioni sulla modifica rilevata e sulla sua posizione nel documento originaleFREngine.IChanges changes = comparatorResult.Changes;foreach( FREngine.IChange change in changes ) { FREngine.ModificationTypeEnum modificationType = change.ModificationType; FREngine.IChangeLocation referenceLocation = change.ReferenceLocation; // Ora puoi evidenziare queste modifiche sulla pagina affinché un operatore le controlli ... }
Passaggio 6. Esportazione del risultato del confronto
Per esportare il risultato del confronto, chiama il metodo Export dell’oggetto ComparisonResult e passa il percorso del file come parametro di input. I dati possono essere salvati in XML o in un file DOCX con revisioni.C#
// Salva in formato XMLcomparisonResult.Export( "C:\\ComparisonResult.xml", FREngine.ComparatorExportFormatEnum.CEF_Xml, null );
Passaggio 7. Scaricamento di ABBYY FineReader Engine
Al termine dell’utilizzo di ABBYY FineReader Engine, è necessario scaricare l’oggetto Engine. A tale scopo, usare la funzione esportata DeinitializeEngine.
Puoi usare il file FREngineDistribution.csv per creare automaticamente un elenco dei file necessari al funzionamento della tua applicazione. Per l’elaborazione in questo scenario, seleziona nella colonna 5 (RequiredByModule) i seguenti valori:CoreCore.ResourcesOpeningOpening, ProcessingProcessingProcessing.OCRProcessing.OCR, Processing.ICRProcessing.OCR.NaturalLanguagesProcessing.OCR.NaturalLanguages, Processing.ICR.NaturalLanguagesExportExport, ProcessingSe modifichi lo scenario standard, aggiorna di conseguenza i moduli richiesti. Devi inoltre specificare le lingue dell’interfaccia, le lingue di riconoscimento ed eventuali funzionalità aggiuntive utilizzate dalla tua applicazione (come, ad esempio, Opening.PDF se devi aprire file PDF oppure Processing.OCR.CJK se devi riconoscere testi nelle lingue CJK). Per ulteriori dettagli, consulta Working with the FREngineDistribution.csv File.
Di seguito è riportata una panoramica degli argomenti della Guida che contengono informazioni aggiuntive sulla personalizzazione delle impostazioni nelle diverse fasi di elaborazione:
Scansione - Solo Windows
Scansione Descrizione dello scenario di ABBYY FineReader Engine per la scansione di documenti.
PageProcessingParams Object Questo oggetto consente di personalizzare i parametri di analisi e riconoscimento. Con questo oggetto, è possibile indicare quali caratteristiche dell’immagine e del testo devono essere rilevate (immagine invertita, orientamento, barcode, lingua di riconoscimento, margine di errore del riconoscimento).
SynthesisParamsForPage Object Questo oggetto include i parametri responsabili del ripristino della formattazione di una pagina durante la sintesi.
SynthesisParamsForDocument Object Questo oggetto consente di personalizzare la sintesi del documento: il ripristino della relativa struttura e formattazione.
MultiProcessingParams Object - Implementato per Linux e Windows L’elaborazione simultanea può essere utile quando si elabora un numero elevato di immagini. In questo caso, il carico di elaborazione viene distribuito tra i core del processore durante l’apertura e la preelaborazione delle immagini, l’analisi del layout, il riconoscimento e l’esportazione, consentendo di velocizzare l’elaborazione. Le modalità di elaborazione (simultanea o consecutiva) vengono impostate tramite la proprietà MultiProcessingMode. La proprietà RecognitionProcessesCount controlla il numero di processi che possono essere avviati.