Pular para o conteúdo principal
O resultado deste cenário é uma versão editável de um documento. Neste cenário, as imagens do documento são reconhecidas, com toda a formatação original preservada, e os dados são salvos em um formato de arquivo editável. Como resultado, você obtém versões editáveis dos seus documentos, que podem ser facilmente verificadas quanto a erros e modificadas. Você também poderá copiar todo o texto ou parte dele para reutilizá-lo. Um documento passa por várias etapas de processamento, que diferem ligeiramente das de outros cenários comuns em alguns aspectos:
  1. Pré-processamento de imagens digitalizadas ou fotos
As imagens obtidas por meio de um scanner ou de uma câmera digital podem exigir alguns ajustes antes de poderem ser reconhecidas opticamente. Por exemplo, imagens com ruído ou com linhas de texto distorcidas precisarão de alguma correção para que o reconhecimento óptico seja bem-sucedido.
  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. Exportação para um formato editável
O documento reconhecido é salvo em um formato editável, como RTF ou DOCX.

Implementação do cenário

Os exemplos de código fornecidos neste tópico são específicos para Windows.
A seguir, você encontrará uma descrição detalhada do método recomendado de uso do ABBYY FineReader Engine 12 para converter documentos. O método proposto usa as configurações de processamento mais adequadas para essa finalidade.
Para começar a trabalhar com o ABBYY FineReader Engine, você precisa criar o objeto Engine. O objeto Engine é o objeto de nível mais alto na hierarquia de objetos do ABBYY FineReader Engine e fornece diversas 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. Consulte 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 = "";
        // Carrega a biblioteca FREngine.dll
        dllHandle = LoadLibraryEx(enginePath, IntPtr.Zero, LOAD_WITH_ALTERED_SEARCH_PATH);
           
        try
        {
            if (dllHandle == IntPtr.Zero)
            {
                throw new Exception("Não foi possível carregar " + enginePath);
            }
            IntPtr initializeEnginePtr = GetProcAddress(dllHandle, "InitializeEngine");
            if (initializeEnginePtr == IntPtr.Zero)
            {
                throw new Exception("Não foi possível encontrar a função InitializeEngine");
            }
            IntPtr deinitializeEnginePtr = GetProcAddress(dllHandle, "DeinitializeEngine");
            if (deinitializeEnginePtr == IntPtr.Zero)
            {
                throw new Exception("Não foi possível encontrar a função DeinitializeEngine");
            }
            IntPtr dllCanUnloadNowPtr = GetProcAddress(dllHandle, "DllCanUnloadNow");
            if (dllCanUnloadNowPtr == IntPtr.Zero)
            {
                throw new Exception("Não foi possível encontrar a função DllCanUnloadNow");
            }
            // Converte ponteiros em delegates
            initializeEngine = (InitializeEngine)Marshal.GetDelegateForFunctionPointer(
                initializeEnginePtr, typeof(InitializeEngine));
            deinitializeEngine = (DeinitializeEngine)Marshal.GetDelegateForFunctionPointer(
                deinitializeEnginePtr, typeof(DeinitializeEngine));
            dllCanUnloadNow = (DllCanUnloadNow)Marshal.GetDelegateForFunctionPointer(
                dllCanUnloadNowPtr, typeof(DllCanUnloadNow));
            // Chama a função InitializeEngine
            // passando o caminho para o arquivo de Licença Online e a senha da Licença Online
            int hresult = initializeEngine(customerProjectId, licensePath, licensePassword, 
                "", "", false, ref engine);
            Marshal.ThrowExceptionForHR(hresult);
        }
        catch (Exception)
        {
            // Libera a biblioteca FREngine.dll
            engine = null;
            // Exclui todos os objetos antes da chamada de FreeLibrary
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();
            FreeLibrary(dllHandle);
            dllHandle = IntPtr.Zero;
            initializeEngine = null;
            deinitializeEngine = null;
            dllCanUnloadNow = null;
            throw;
        }
    }
    // Funções do 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 do 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;
    // Handle para FREngine.dll
    private IntPtr dllHandle = IntPtr.Zero;
    private InitializeEngine initializeEngine = null;
    private DeinitializeEngine deinitializeEngine = null;
    private DllCanUnloadNow dllCanUnloadNow = null;
}

C++ (COM)

// Inicialize estas variáveis com o caminho para FREngine.dll, o ID do projeto do cliente do FineReader Engine,
// e, se aplicável, o caminho para o token da Licença Online e a senha da Licença Online
wchar_t* FreDllPath;
wchar_t* CustomerProjectId;
wchar_t* LicensePath;  // se não usar uma Licença Online, atribua strings vazias a estas variáveis
wchar_t* LicensePassword;
// HANDLE para FREngine.dll
static HMODULE libraryHandle = 0;
// Objeto global do FineReader Engine
FREngine::IEnginePtr Engine;
void LoadFREngine()
{
    if( Engine != 0 ) {
    // Já carregado
    return;
    }
    // Primeiro passo: carregar FREngine.dll
    if( libraryHandle == 0 ) {
        libraryHandle = LoadLibraryEx( FreDllPath, 0, LOAD_WITH_ALTERED_SEARCH_PATH );
        if( libraryHandle == 0 ) {
            throw L"Erro ao carregar o ABBYY FineReader Engine";
        }
    }
    // Segundo passo: obter o objeto Engine
    typedef HRESULT ( STDAPICALLTYPE* InitializeEngineFunc )( BSTR, BSTR, BSTR, BSTR, 
        BSTR, VARIANT_BOOL, FREngine::IEngine** );
    InitializeEngineFunc pInitializeEngine =
    ( InitializeEngineFunc )GetProcAddress( libraryHandle, "InitializeEngine" );
    if( pInitializeEngine == 0 || pInitializeEngine( CustomerProjectId, LicensePath, 
        LicensePassword, L"", L"", VARIANT_FALSE, &Engine ) != S_OK ) {
    UnloadFREngine();
    throw L"Erro ao carregar o ABBYY FineReader Engine";
    }
}
O ABBYY FineReader Engine permite carregar todas as configurações de processamento mais adequadas para esse cenário usando o método LoadPredefinedProfile do objeto Engine. Esse método recebe o nome do perfil como parâmetro de entrada. Consulte Working with Profiles para mais informações.O ABBYY FineReader Engine oferece suporte a 2 variantes de configuração para esse cenário:

Nome do perfil

Descrição

DocumentConversion_Accuracy

As configurações foram otimizadas para precisão:

  • Melhor qualidade. Habilita a detecção do estilo da fonte e a síntese completa da estrutura lógica de um documento.

DocumentConversion_Normal

As configurações foram otimizadas para velocidade de processamento:

  • Melhor qualidade. Habilita a detecção do estilo da fonte e a síntese completa da estrutura lógica de um documento.
  • A orientação da imagem não é corrigida.
  • O processo de análise do documento é acelerado.

C#

// Carrega um perfil predefinido
engine.LoadPredefinedProfile("DocumentConversion_Normal");

C++ (COM)

// Carrega um perfil predefinido
Engine->LoadPredefinedProfile( L"DocumentConversion_Normal" );
Se quiser alterar as configurações de processamento, use os objetos Parameter apropriados. Consulte Otimização adicional para tarefas específicas abaixo para mais informações.
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.Para carregar as 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 opções a seguir:

C#

// Cria o objeto FRDocument a partir de um arquivo de imagem
FREngine.IFRDocument frDocument = engine.CreateFRDocumentFromImage( "C:\\MyImage.tif", null );

C++ (COM)

// Cria o objeto FRDocument a partir de um arquivo de imagem
FREngine::IFRDocumentPtr frDocument = Engine->CreateFRDocumentFromImage( L"C:\\MyImage.tif", 0 );
O pré-processamento de imagens com o perfil DocumentConversion_Normal carregado não inclui detecção de orientação. Se quiser que a orientação da imagem seja detectada automaticamente, será necessário configurar parâmetros adicionais e passar o objeto correspondente para a função de pré-processamento. Consulte Otimização adicional para tarefas específicas abaixo para mais informações.
Para reconhecer um documento, recomendamos usar os métodos de análise e reconhecimento do objeto FRDocument. Esse objeto oferece uma ampla variedade de métodos para análise, reconhecimento e síntese de documentos. O método mais prático, que executa análise, reconhecimento e síntese do documento em uma única operação, é o método Process. Ele também usa da forma mais eficiente os recursos de processamento simultâneo de sistemas multiprocessados e multinúcleo. No entanto, você também pode executar o pré-processamento, a análise, o reconhecimento e a síntese em sequência usando os métodos Preprocess, Analyze, Recognize e Synthesize.

C#

// Analisa, reconhece e sintetiza o documento
// Não há necessidade de parâmetros adicionais, pois eles são definidos pelo perfil de processamento
frDocument.Process( null );

C++ (COM)

// Analisa, reconhece e sintetiza o documento
// Não há necessidade de parâmetros adicionais, pois eles são definidos pelo perfil de processamento
frDocument->Process( 0 );
Para salvar um documento reconhecido, você pode usar o método Export do objeto FRDocument, especificando a constante FileExportFormatEnum como um dos parâmetros. Você pode alterar os parâmetros padrão de exportação usando o objeto de exportação correspondente. Consulte Otimização adicional para tarefas específicas abaixo para mais informações.Depois de concluir o trabalho com o objeto FRDocument, libere todos os recursos usados por ele. Use o método IFRDocument::Close.

C#

// Salva o documento reconhecido em formato editável (por exemplo, RTF)
frDocument.Export( "C:\\MyText.rtf", FREngine.FileExportFormatEnum.FEF_RTF, null );
// Libera o objeto FRDocument
frDocument.Close();

C++ (COM)

// Salva o documento reconhecido em formato editável (por exemplo, RTF)
frDocument->Export( L"C:\\MyText.rtf", FREngine::FEF_RTF, 0 );
// Libera o objeto FRDocument
frDocument->Close();
Após 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
{
    // Descarregar o FineReader Engine
    public void Dispose()
    {
        if (engine == null)
        {
            // O Engine não foi carregado
            return;
        }
        engine = null;
        // Excluir 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;
        // lançar 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 da FREngine.dll
    private IntPtr dllHandle = IntPtr.Zero;
    private InitializeEngine initializeEngine = null;
    private DeinitializeEngine deinitializeEngine = null;
    private DllCanUnloadNow dllCanUnloadNow = null;
}

C++ (COM)

void UnloadFREngine()
{
 if( libraryHandle == 0 ) {
  return;
 }
 // Liberar o objeto Engine
 Engine = 0;
 // Desinicializar o FineReader Engine
 typedef HRESULT ( STDAPICALLTYPE* DeinitializeEngineFunc )();
 DeinitializeEngineFunc pDeinitializeEngine =
  ( DeinitializeEngineFunc )GetProcAddress( libraryHandle, "DeinitializeEngine" );
 if( pDeinitializeEngine == 0 || pDeinitializeEngine() != S_OK ) {
  throw L"Erro ao descarregar o ABBYY FineReader Engine";
 }
 // Agora é seguro liberar a biblioteca FREngine.dll
 FreeLibrary( libraryHandle );
 libraryHandle = 0;
}

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 neste 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, altere os módulos necessários conforme apropriado. Você também precisa especificar os idiomas da interface, os idiomas de reconhecimento e quaisquer recursos adicionais usados pelo seu aplicativo (como, por exemplo, Opening.PDF, se precisar abrir arquivos PDF, ou Processing.OCR.CJK, se precisar reconhecer texto em idiomas CJK). Consulte Working with the FREngineDistribution.csv File 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 de configurações em diferentes etapas da conversão de documentos para um formato editável:
  • Digitalização - somente Windows
    • Digitalização
      Descrição do cenário do ABBYY FineReader Engine para digitalização de documentos.
  • Reconhecimento
    • Ajuste dos parâmetros de pré-processamento, análise, reconhecimento e síntese
      Personalização do processamento de documentos usando objetos de parâmetros de análise, reconhecimento e síntese.
    • Reconhecimento de escrita manuscrita
      Os perfis DocumentConversion_*** não incluem reconhecimento de texto manuscrito nem de texto em letra de forma escrito à mão. Se você precisar reconhecer escrita manuscrita, defina a propriedade DetectHandwritten do objeto PageAnalysisParams como TRUE.
    • Objeto PageProcessingParams
      Este objeto permite personalizar os parâmetros de análise e reconhecimento. Com ele, 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).
    • Objeto SynthesisParamsForPage
      Este objeto inclui parâmetros responsáveis pela restauração da formatação de uma página durante a síntese.
    • Objeto SynthesisParamsForDocument
      Este objeto permite personalizar a síntese do documento: restauração de sua estrutura e formatação.
    • Objeto MultiProcessingParams - Implementado 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 das imagens, 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.
  • Exportação

Veja também

Implementação de cenários básicos de uso