Pular para o conteúdo principal
Este tópico se aplica ao FRE para Windows.

Adicionando a biblioteca do FineReader Engine a um projeto Java

O ABBYY FineReader Engine inclui um arquivo com.abbyy.FREngine-%BUILD_ID%.jar, que contém a biblioteca de classes Java do FineReader Engine. Você pode encontrá-lo na pasta Inc\Java. O caminho para esse arquivo pode ser especificado no parâmetro classpath da linha de comando e nas configurações do projeto em diferentes ambientes de desenvolvimento Java. Exemplo:
%JDK%\bin\Javac -classpath <path>/com.abbyy.FREngine-%BUILD_ID%.jar Hello.java
%JDK% é o caminho para o diretório do Java Development Kit.
Consulte a lista de Java Development Kits compatíveis em Requisitos do sistema.

Carregando e descarregando o FineReader Engine

Você pode usar a classe estática Engine para carregar o objeto Engine. A classe Engine fornece métodos que correspondem às funções do ABBYY FineReader Engine para carregar e descarregar o Engine:
FunctionEngine class methodThe signature of the Engine class method
InitializeEngineInitializeEnginecsharp static public IEngine InitializeEngine( String dllFolder, String customerProjectId, String licensePath, String licensePassword, String dataFolder, String tempFolder, boolean isSharedCPUCoresMode ) throws Exception;
DeinitializeEngineDeinitializeEnginestatic public void DeinitializeEngine() throws Exception;
import com.abbyy.FREngine.*;
public class Hello {
    public static void main( String[] args )
    {
        try {
            // Carrega o Engine com Licença Online
            engine = Engine.InitializeEngine( dllPath, customerProjectId, LicensePath, LicensePassword, "", "", false );
            try {
                // Carrega um perfil predefinido
                engine.LoadPredefinedProfile( "DocumentConversion_Accuracy" );
                // Processa imagens
                IFRDocument document = engine.CreateFRDocument();
                ...
            } finally {
                engine = null;
                System.runFinalization();
                Engine.DeinitializeEngine();
            }
        } catch( Exception ex ) {
            trace( ex.getMessage() );
        }
    }
    private IEngine engine = null;
...
}
Para carregar o Engine por meio de COM, use os métodos GetEngineInprocLoader ou GetEngineOutprocLoader. Consulte a descrição da interface IEngineLoader para mais detalhes. Se você usar o método GetEngineOutprocLoader para carregamento, não será necessário chamar o método IHostProcessControl::SetClientProcessId, pois o processo pai será definido automaticamente.
Se você desenvolver seu aplicativo no Windows, mas pretender executá-lo no Linux, não use esses métodos para carregar o Engine. Use somente o método InitializeEngine descrito acima. Essa limitação se deve ao fato de que os objetos que implementam IEngineLoader não estão disponíveis no Linux.
import com.abbyy.FREngine.*;
// Carregando o Engine com Licença Online
engineLoader = Engine.GetEngineInprocLoader();
engine = engineLoader.InitializeEngine( customerProjectId, LicensePath, LicensePassword, "", "", false );
...
// Descarregando o Engine
engine = null;
System.runFinalization();
engineLoader.ExplicitlyUnload();
engineLoader = null;
System.runFinalization();
import com.abbyy.FREngine.*;
// Carregando o Engine com Licença Online
engineLoader = Engine.GetEngineOutprocLoader();
engine = engineLoader.InitializeEngine( customerProjectId, LicensePath, LicensePassword, "", "", false );
...
// Descarregando o Engine
engine = null;
System.runFinalization();
engineLoader.ExplicitlyUnload();
engineLoader = null;
System.runFinalization();
Para trabalhar com o objeto Engine criado por meio de um carregador de engine, a classe Engine fornece métodos que chamam as funções COM correspondentes para fazer o marshaling do ponteiro de interface entre threads:
MethodSignatureComment
MarshalInterfacelong MarshalInterface();Chama a função COM CoMarshalInterface para fazer o marshaling da interface IEngine. Esse método deve ser chamado na thread em que o engine foi criado, para garantir que os dados necessários para criar um objeto proxy em outra thread estejam disponíveis. Retorna o handle dos dados de marshaling.
UnmarshalInterfacecsharp IEngine UnmarshalInterface( long handle ); Chama a função COM CoUnmarshalInterface para desfazer o marshaling da interface IEngine, ou seja, criar um objeto proxy com o qual o processo cliente poderá interagir da mesma forma que com o próprio engine. Recebe o handle dos dados de marshaling (retornado pelo método MarshalInterface) como parâmetro de entrada e retorna um ponteiro para a interface IEngine.
O arquivo com.abbyy.FREngine-%BUILD_ID%.jar é um arquivo autoextraível, descompactado na sua máquina na primeira vez que você usa a API Java do FineReader Engine. A pasta padrão em que o conteúdo é descompactado é Inc\Java no Windows. Se precisar usar outra pasta, chame o método Engine.SetJNIDllFolder antes de carregar o Engine por qualquer um dos métodos descritos acima. Para saber qual pasta está definida no momento para a descompactação do arquivo, chame Engine.GetJNIDllFolder .

Usando o Engine em aplicações Java multithread

Para aplicações Java multithread, você pode usar a classe EnginesPool, que oferece uma solução completa para criar e gerenciar um pool de objetos FineReader Engine. Essa classe implementa a interface java.lang.Runnable.
public class EnginesPool implements Runnable;
Os métodos da classe EnginesPool estão listados abaixo.
MétodoAssinaturaComentário
constructorpublic EnginesPool( int enginesCount, int waitingEngineTimeout, String customerProjectId, String licensePath, String licensePassword, String dataFolder, String tempFolder, boolean isSharedCPUCoresMode ) throws Exception;Cria um novo pool de enginesCount Engines. O waitingEngineTimeout define o tempo limite para EnginesPool.GetEngine. Os demais parâmetros são os mesmos que em InitializeEngine
GetEnginecsharp public IEngine GetEngine() throws Exception; Obtém uma instância de Engine do pool. Lança uma exceção se o waitingEngineTimeout for excedido.
ReleaseEnginecsharp public void ReleaseEngine( IEngine engine, boolean isRecycleRequired ) throws Exception; Retorna uma instância de Engine ao pool. Se isRecycleRequired for true, exclui essa instância e a substitui por uma nova (mesmo que o limite de uso não tenha sido atingido ou que a reciclagem automática esteja desabilitada).
SetAutoRecycleUsageCountpublic void SetAutoRecycleUsageCount( int value );Define quantas vezes uma única instância de Engine neste pool pode ser reutilizada antes de ser reciclada: excluída e substituída automaticamente por uma nova. O contador pode ser definido como 0 para desabilitar a reciclagem automática (somente a reciclagem manual será possível, via ReleaseEngine). O padrão é 0 (nunca reciclar automaticamente).
GetAutoRecycleUsageCountpublic int GetAutoRecycleUsageCount();Obtém o limite de reutilização de instâncias de Engine para este pool.
UnloadEnginespublic void UnloadEngines() throws Exception;Descarrega todas as Engines e desinicializa o pool.
Consulte o exemplo de código EnginesPool para ver um exemplo de uso da classe EnginesPool.

Tratamento de erros

O ABBYY FineReader Engine pode lançar exceções dos seguintes tipos:
  • java.lang.OutOfMemoryError
  • com.abbyy.FREngine.EngineException
A exceção com.abbyy.FREngine.EngineException herda de java.lang.Exception e contém um método adicional, int getHResult, que retorna o código HRESULT do erro ocorrido. Para uma exceção desse tipo, você pode não apenas recuperar a mensagem de erro usando o método getMessage(), mas também obter o código do erro.
try {
    ...
} catch( Exception ex ) {
    displayMessage( "Message = " + ex.getMessage() );
    if( ex instanceof EngineException ) {
        displayMessage( "HResult = " + Integer.toString( ( ( EngineException )ex ).getHResult() ) );
    }
}

Chamando métodos com parâmetros de saída

Há vários métodos na API do ABBYY FineReader Engine que têm parâmetros de saída, os quais recebem um novo valor após a chamada do método e devem ser passados por referência. Esses parâmetros são marcados na biblioteca de tipos e nas descrições dos métodos nesta Ajuda do Desenvolvedor como [out] ou [in, out]. Ao trabalhar com o ABBYY FineReader Engine em Java, você precisa usar uma classe especial Ref para passar um parâmetro por referência. Veja os exemplos abaixo. Exemplo em que os parâmetros de saída são passados por referência para o método IFRPage::FindPageSplitPosition:
Ref<PageSplitDirectionEnum> _ps = new Ref<PageSplitDirectionEnum>();
Ref<Integer> _start = new Ref<Integer>();
Ref<Integer> _end = new Ref<Integer>();
page.FindPageSplitPosition( null, null, _ps, _start, _end );
PageSplitDirectionEnum ps = _ps.get();
Integer start = _start.get();
Integer end = _end.get();
Exemplo em que os parâmetros de entrada e saída são passados por referência para o método ICoordinatesConverter::ConvertCoordinates:
Ref<Integer> _x = new Ref<Integer>( 100 );
Ref<Integer> _y = new Ref<Integer>( 200 );
cnv.ConvertCoordinates( ImageTypeEnum.IT_Modified, ImageTypeEnum.IT_Base, _x, _y );
Integer x = _x.get();
Integer y = _y.get();
O exemplo a seguir mostra os parâmetros de saída de array passados por referência para o método IPlainText::GetCharacterData:
Ref<int[]> _leftBorders = new Ref<int[]>();
Ref<int[]> _topBorders = new Ref<int[]>();
Ref<int[]> _rightBorders = new Ref<int[]>();
Ref<int[]> _bottomBorders = new Ref<int[]>();
Ref<int[]> _confidences = new Ref<int[]>();
Ref<boolean[]> _isSuspicious = new Ref<boolean[]>();
plainText.GetCharacterData( _pageNumbers, _leftBorders, _topBorders, _rightBorders, _bottomBorders, _confidences, _isSuspicious );
int[] pageNumbers = _pageNumbers.get();
int[] leftBorders = _leftBorders.get();
int[] topBorders = _topBorders.get();
int[] rightBorders = _rightBorders.get();
int[] bottomBorders = _bottomBorders.get();
int[] confidences = _confidences.get();
boolean[]isSuspicious = _isSuspicious.get();
Ref<int[]> _pageNumbers = new Ref<int[]>();

Coleta de lixo

O FineReader Engine oferece suporte à interface AutoCloseable, o que permite usar a instrução try para acessar os recursos alocados para os objetos. Isso significa que, quando o bloco try chega ao fim, todos os recursos alocados são fechados automaticamente, sem a necessidade de chamar explicitamente métodos de fechamento. Recomendamos que você use a instrução try para todos os objetos no seu código (veja o exemplo abaixo):
try( IFRDocument document = engine.CreateDocument() )
 {
  // Adicionar imagem a um documento
  document.AddImageFile( imagePath, null, null );
  ...
  // Salvar resultados em PDF
  document.Export( pdfExportPath, FileExportFormatEnum.FEF_PDF, pdfParams );
 }
Trabalhando com HGLOBAL Alguns dos métodos da API do ABBYY FineReader Engine recebem como parâmetro de entrada um handle HGLOBAL para um bloco de memória (passado como __int64). Como HGLOBAL é uma entidade específica do Windows, no wrapper Java esses métodos recebem, em vez disso, o conteúdo do bloco de memória como byte[]. Veja a lista desses métodos: Por outro lado, os métodos que retornam um objeto Handle também o retornam no wrapper Java.

Trabalhando com enumerações

Métodos e propriedades que aceitam uma combinação de constantes de enumeração exigem que o valor int seja passado ao método/à propriedade. Para obter o valor int de uma constante de enumeração, use o método getValue, disponível em todas as enumerações. Veja abaixo um exemplo de código que mostra como definir a propriedade BwPictureFormats do objeto PDFPictureCompressionParams:
IPDFExportParams pep = engine.CreatePDFExportParams();
IPDFPictureCompressionParams ppcp = pep.getPictureCompressionParams();
ppcp.setBwPictureFormats(BwPictureFormatsEnum.BWPF_Auto.getValue());
Consulte também Diferentes maneiras de carregar o objeto Engine no Windows Desenvolvimento multiplataforma em Java no Windows