Pular para o conteúdo principal
Ao trabalhar com documentos em papel, você precisa encontrar e corrigir erros ou alterações feitas intencionalmente. Use a API Document Comparison para localizar essas alterações de forma rápida e eficiente. Esse cenário é usado para comparar documentos especialmente importantes, como contratos e documentação bancária, com suas cópias. O resultado da comparação contém informações sobre diferenças no tipo de conteúdo (somente texto), no tipo de modificação (excluído, inserido ou modificado) e em suas localizações no original e na cópia. Você pode obter a lista das diferenças detectadas ou a região de qualquer alteração e salvar o resultado da comparação em um arquivo externo para processamento posterior ou armazenamento de longo prazo. Para comparar os documentos ou páginas, os arquivos obtidos por digitalização ou salvos em formato eletrônico normalmente passam por várias etapas de processamento, cada uma com suas próprias particularidades:
  1. Pré-processamento de arquivos digitalizados ou imagens
Os arquivos e suas cópias exigem algum pré-processamento antes do reconhecimento, caso apresentem defeitos ou anotações feitas intencionalmente, como assinaturas ou carimbos.
  1. Reconhecimento com restauração completa da estrutura e da formatação do documento
Ao reconhecer um documento, vários elementos de layout (texto, tabelas, imagens, separadores etc.) são identificados. Durante a síntese do documento, a estrutura lógica é restaurada, enquanto a síntese da página permite restaurar completamente a formatação do documento (fontes, estilos etc.)
  1. Comparação de documentos ou páginas
Para comparar os documentos ou páginas com suas cópias, use os arquivos reconhecidos com o ABBYY FineReader Engine. Você pode usar as duas versões de um documento em formatos diferentes. Após a comparação, você obtém o resultado com a lista de alterações; use-o para recuperar as informações sobre a localização dessas alterações. Se você estiver usando verificação manual, use essas informações para destacar as alterações no texto, facilitando o trabalho do operador.
  1. Exportação para um formato externo
Você também pode salvar o resultado da comparação nos formatos XML e DOCX. O procedimento descrito abaixo também é ilustrado pelo exemplo Comparação de documentos para Linux e macOS e pela ferramenta de demonstração Comparação de documentos para Windows.

Implementação do cenário

Os exemplos de código fornecidos neste tópico são específicos para Windows.
A seguir, você encontra uma descrição detalhada do método recomendado para usar o ABBYY FineReader Engine neste cenário.
Para começar a trabalhar com o ABBYY FineReader Engine, você precisa criar o objeto Engine. O objeto Engine é o objeto principal na hierarquia de objetos do ABBYY FineReader Engine e fornece várias configurações globais, alguns métodos de processamento e métodos para criar os demais objetos.Para criar o objeto Engine, você pode usar a função InitializeEngine. Veja também outras formas de carregar o objeto Engine (Win).

C#

public class EngineLoader : IDisposable
{
    public EngineLoader()
    {
        // Inicialize estas variáveis com o caminho completo para FREngine.dll, seu ID do projeto do cliente,
        // e, se aplicável, o caminho para o arquivo de token da Licença Online e a senha da Licença Online
        string enginePath = "";
        string customerProjectId = "";
        string licensePath = "";
        string licensePassword = "";
        // Carregue a 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");
            }
            // Converta os ponteiros em delegates
            initializeEngine = (InitializeEngine)Marshal.GetDelegateForFunctionPointer(
                initializeEnginePtr, typeof(InitializeEngine));
            deinitializeEngine = (DeinitializeEngine)Marshal.GetDelegateForFunctionPointer(
                deinitializeEnginePtr, typeof(DeinitializeEngine));
            dllCanUnloadNow = (DllCanUnloadNow)Marshal.GetDelegateForFunctionPointer(
                dllCanUnloadNowPtr, typeof(DllCanUnloadNow));
            // Chame a função InitializeEngine 
            // passando o caminho para o arquivo da Licença Online e a senha da Licença Online
            int hresult = initializeEngine(customerProjectId, licensePath, licensePassword, 
                "", "", false, ref engine);
            Marshal.ThrowExceptionForHR(hresult);
        }
        catch (Exception)
        {
            // Libere a biblioteca FREngine.dll
            engine = null;
            // Excluindo todos os objetos antes da chamada a FreeLibrary
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();
            FreeLibrary(dllHandle);
            dllHandle = IntPtr.Zero;
            initializeEngine = null;
            deinitializeEngine = null;
            dllCanUnloadNow = null;
            throw;
        }
    }
    // Funções 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);
    // Funções 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();
    // Variáveis 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;
}
O ABBYY FineReader Engine fornece o objeto FRDocument, que permite processar documentos com várias páginas. O uso desse objeto permite preservar a organização lógica do documento, mantendo o texto original, as colunas, as fontes, os estilos etc. Use o objeto FRPage se quiser comparar páginas.Para carregar imagens de um único documento e pré-processá-las, você deve criar o objeto FRDocument e adicionar as imagens a ele. Você pode fazer uma das seguintes opções:

C#

// Criar o objeto FRDocument a partir de um arquivo de imagem
FREngine.IFRDocument frDocument = engine.CreateFRDocumentFromImage( "C:\\MyImage.tif", null );
Para reconhecer um documento, sugerimos usar os métodos de análise e reconhecimento do objeto FRDocument. Esse objeto oferece um conjunto completo de métodos para análise, reconhecimento e síntese de documentos. O método mais conveniente, que reúne análise, reconhecimento e síntese em uma única operação, é o método Process. Ele também utiliza da forma mais eficiente os recursos de processamento simultâneo de sistemas multiprocessados e multicore. No entanto, você também pode executar o pré-processamento, a análise, o reconhecimento e a síntese de forma sequencial usando os métodos Preprocess, Analyze, Recognize e Synthesize.
Você pode definir os parâmetros de reconhecimento dos seus documentos carregando um perfil predefinido adequado (consulte Working with Profiles para mais informações).

C#

// Processar o documento com os parâmetros padrão
// Você pode alterá-los, se necessário, por exemplo, carregando um perfil previamente
frDocument.Process( null );
Para comparar os documentos ou as páginas com suas cópias:
  1. Certifique-se de que sua licença do ABBYY FineReader Engine oferece suporte ao módulo Compare Documents.
  2. Crie um objeto Comparator usando o método CreateComparator do objeto Engine.
  3. [opcional] Use o objeto ComparisonParams para definir as propriedades com os valores desejados.
  4. Chame o método CompareDocuments do objeto Comparator para comparar o documento original com a cópia. Você receberá um objeto ComparisonResult contendo informações sobre as alterações detectadas.

C#

// Executa a comparação dos documentos 
FREngine.IComparator comparator = engine.CreateComparator();
FREngine.IComparisonResult comparatorResult = 
    comparator.CompareDocuments( referenceFRDocument, userFRDocument, null, null );
O objeto ComparisonResult contém a lista completa de diferenças e fornece métodos para obtê-las para páginas individuais. Você pode acessar as alterações no documento original e em sua cópia com os métodos GetChangesForReferencePage e GetChangesForUserPage. Use o objeto ChangeLocation para obter informações sobre a localização da alteração e a propriedade RegionForPage para obter a região da alteração na página especificada.

C#

// Obtém informações sobre a modificação detectada e sua localização no documento original
FREngine.IChanges changes = comparatorResult.Changes;
foreach( FREngine.IChange change in changes ) {
      FREngine.ModificationTypeEnum modificationType = change.ModificationType;
      FREngine.IChangeLocation referenceLocation = change.ReferenceLocation;
      // Agora você pode destacar essas alterações na página para que um operador as verifique
      ... 
}
Para exportar o resultado da comparação, chame o método Export do objeto ComparisonResult e passe o caminho do arquivo como parâmetro de entrada. Os dados podem ser salvos em XML ou em um arquivo DOCX com controle de alterações.C#
// Salva no formato XML
comparisonResult.Export( "C:\\ComparisonResult.xml", FREngine.ComparatorExportFormatEnum.CEF_Xml, null );
Depois de concluir o trabalho com o ABBYY FineReader Engine, você precisa descarregar o objeto Engine. Para isso, use a função exportada DeinitializeEngine.

C#

public class EngineLoader : IDisposable
{
    // Descarrega o FineReader Engine
    public void Dispose()
    {
        if (engine == null)
        {
            // O Engine não foi carregado
            return;
        }
        engine = null;
        // Exclui todos os objetos antes da chamada 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;
        // gera exceção após a limpeza
        Marshal.ThrowExceptionForHR(hresult);
    }
    // Funções 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);
    // Funções 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();
    // variáveis privadas
    private FREngine.IEngine engine = null;
    // Handle para FREngine.dll
    private IntPtr dllHandle = IntPtr.Zero;
    private InitializeEngine initializeEngine = null;
    private DeinitializeEngine deinitializeEngine = null;
    private DllCanUnloadNow dllCanUnloadNow = null;
}

Recursos necessários

Você pode usar o arquivo FREngineDistribution.csv para criar automaticamente uma lista dos arquivos necessários para que seu aplicativo funcione. Para o processamento com este cenário, selecione na coluna 5 (RequiredByModule) os seguintes 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 Se você modificar o cenário padrão, ajuste os módulos necessários de acordo. Você também precisa especificar os idiomas da interface, os idiomas de reconhecimento e todos os recursos adicionais usados pelo seu aplicativo (como, por exemplo, Opening.PDF se precisar abrir arquivos PDF, ou Processing.OCR.CJK se precisar reconhecer textos em idiomas CJK). Consulte Como trabalhar com o arquivo FREngineDistribution.csv para mais detalhes.

Otimização adicional para tarefas específicas

Abaixo está uma visão geral dos tópicos da ajuda que contêm informações adicionais sobre a personalização das configurações em diferentes etapas do processamento:
  • Digitalização - Somente Windows
    • Digitalização
      Descrição do cenário do ABBYY FineReader Engine para digitalização de documentos.
  • Reconhecimento
    • Ajuste de parâmetros de pré-processamento, análise, reconhecimento e síntese
      Personalização do processamento de documentos usando objetos de parâmetro de análise, reconhecimento e síntese.
    • PageProcessingParams Object
      Esse objeto permite personalizar os parâmetros de análise e reconhecimento. Com esse objeto, você pode indicar quais características da imagem e do texto devem ser detectadas (imagem invertida, orientação, códigos de barras, idioma de reconhecimento, margem de erro de reconhecimento).
    • SynthesisParamsForPage Object
      Esse objeto inclui parâmetros responsáveis por restaurar a formatação de uma página durante a síntese.
    • SynthesisParamsForDocument Object
      Esse objeto permite personalizar a síntese do documento: restaurar sua estrutura e formatação.
    • MultiProcessingParams Object - Disponível para Linux e Windows
      O processamento simultâneo pode ser útil ao processar um grande número de imagens. Nesse caso, a carga de processamento será distribuída entre os núcleos do processador durante a abertura e o pré-processamento da imagem, a análise de layout, o reconhecimento e a exportação, o que possibilita acelerar o processamento.
      Os modos de leitura (simultâneo ou consecutivo) são definidos usando a propriedade MultiProcessingMode. A propriedade RecognitionProcessesCount controla o número de processos que podem ser iniciados.

Veja também

Cenários básicos de implementação de uso