Vai al contenuto principale
Questo scenario è disponibile solo per Windows.
In questo scenario, ABBYY FineReader Engine viene utilizzato su un “computer di scansione”, che acquisisce le immagini e le salva come file. Questo scenario può essere utilizzato come parte di altri scenari nella fase preliminare dell’elaborazione dei documenti, cioè per ottenere versioni elettroniche dei documenti da sottoporre a ulteriore elaborazione. Esempi di utilizzo includono la scansione di documenti a scopo di archiviazione, l’ottenimento di versioni modificabili dei documenti e l’estrazione di dati specifici dai documenti. I documenti cartacei vengono sottoposti a scansione e le immagini vengono salvate in formato elettronico, producendo versioni elettroniche di alta qualità dei documenti stampati. I documenti possono passare attraverso le seguenti fasi di elaborazione:
  1. Scansione
I documenti possono essere acquisiti tramite una delle due interfacce di scansione disponibili fornite dagli scanner (TWAIN o WIA), utilizzando l’interfaccia di scansione proprietaria di ABBYY oppure senza alcuna interfaccia di scansione.
  1. Pre-elaborazione delle immagini acquisite
Una volta acquisite, le immagini possono essere pre-elaborate. La pre-elaborazione include la rimozione del disturbo, la correzione delle righe di testo distorte, l’inversione dei colori, la rimozione dei margini neri e la correzione dell’orientamento o della risoluzione dell’immagine. Le pagine affiancate possono essere suddivise in due immagini separate. Le immagini elaborate possono essere salvate in vari formati, ad esempio JPEG, TIFF e BMP.

Implementazione dello scenario

Di seguito è riportata una descrizione dettagliata del metodo consigliato per utilizzare ABBYY FineReader Engine 12 in questo scenario. Nell’implementazione proposta, la fase di preparazione dell’immagine viene omessa. Per suggerimenti su come implementare la preparazione dell’immagine, consulta Ottimizzazione aggiuntiva di seguito.
Per iniziare a lavorare con ABBYY FineReader Engine, devi creare l’oggetto Engine. L’oggetto Engine è l’oggetto di livello superiore nella gerarchia degli oggetti di ABBYY FineReader Engine e fornisce diverse impostazioni globali, alcuni metodi di elaborazione e i metodi per creare gli altri oggetti.Per creare l’oggetto Engine, puoi usare la funzione InitializeEngine. Vedi anche altri modi per caricare l’oggetto Engine (Win).

C#

public class EngineLoader : IDisposable
{
    public EngineLoader()
    {
        // Inizializza queste variabili con il percorso completo di FREngine.dll, il tuo Customer Project ID
        // e, se applicabile, con il percorso del file token della Online License e la password della 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 della Online License e la password della 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;
}
ABBYY FineReader Engine mette a disposizione un oggetto ScanManager per la gestione delle sorgenti di scansione. La proprietà ScanSources di questo oggetto consente di accedere all’elenco di tutti gli scanner disponibili, mentre il metodo FindScanSources permette di selezionare gli scanner in base al tipo di API fornito e al tipo di interfaccia utente da utilizzare per configurare le opzioni di scansione.Per acquisire e salvare i file su disco, è possibile utilizzare uno dei due metodi dell’oggetto ScanSource: il metodo Scan, che non restituisce il controllo fino al completamento della scansione, e il metodo BeginScan, che avvia l’operazione di scansione asincrona e restituisce il controllo immediatamente.È possibile implementare l’interfaccia IScanCallback e utilizzarla per ricevere notifiche sull’avanzamento della scansione.I seguenti parametri sono accessibili tramite l’API di ABBYY FineReader Engine 12: luminosità, colore, risoluzione, tipo di compressione dell’immagine, angolo di rotazione dell’immagine, dimensioni dell’area di scansione, modalità di scansione fronte-retro, modalità alimentatore automatico, una pausa tra le pagine e altri ancora. I parametri di scansione vengono impostati tramite la proprietà ScanSettings dell’oggetto ScanSource. Questa proprietà è necessaria per accedere all’oggetto ScanSourceSettings, che a sua volta fornisce accesso alle impostazioni di scansione di una sorgente.Per eseguire la scansione delle immagini in modo sincrono:
  1. Creare un oggetto ScanManager. È possibile specificare, tramite il parametro di input del metodo CreateScanManager, se i log di scansione devono essere registrati.
  2. Selezionare la sorgente di scansione utilizzando il metodo FindScanSources dell’oggetto ScanManager, specificando il tipo di API e di UI supportato dallo scanner.
  3. Se scegli di non visualizzare alcuna finestra di dialogo per consentire all’utente di impostare autonomamente le opzioni di scansione, configura tali opzioni utilizzando la proprietà ScanSettings del ScanSource selezionato. Seleziona i valori appropriati per luminosità, risoluzione e gli altri parametri nelle proprietà corrispondenti dell’oggetto ScanSourceSettings. Puoi verificare quali impostazioni sono disponibili per questo scanner utilizzando la proprietà Capabilities di ScanSource.
  4. Specificare il nome della cartella in cui verranno archiviate le pagine acquisite tramite scansione. Il nome della cartella deve essere una variabile BSTR, ad esempio ScanFolder.
  5. Esegui il metodo Scan dell’oggetto ScanSource, specificando come parametri il tipo di finestra di dialogo da mostrare all’utente (passa la costante SSUIT_None per non visualizzare alcuna finestra) e il percorso ScanFolder della cartella contenente i risultati.
  6. I nomi dei file immagine verranno restituiti da questo metodo come oggetto StringsCollection. È quindi possibile recuperare i nomi dei file immagine da questo oggetto StringsCollection e poi elaborare i file come normali file immagine.
Per eseguire la scansione delle immagini in modo asincrono:
  1. Creare un oggetto che implementi l’interfaccia IScanCallback. Nel caso di un’operazione di scansione asincrona, le notifiche fornite dall’interfaccia di callback sono molto utili.
  2. Creare un oggetto ScanManager. È possibile specificare se i log di scansione vengano scritti tramite il parametro di input del metodo CreateScanManager.
  3. Seleziona la sorgente di scansione utilizzando il metodo FindScanSources dell’oggetto ScanManager, specificando il tipo di API e di interfaccia utente supportato dallo scanner.
  4. Se si sceglie di non visualizzare alcuna finestra di dialogo che consenta all’utente di impostare autonomamente le opzioni di scansione, configurare le opzioni di scansione utilizzando la proprietà ScanSettings dello ScanSource selezionato. Selezionare i valori appropriati per luminosità, risoluzione e gli altri parametri nelle proprietà corrispondenti dell’oggetto ScanSourceSettings. È possibile verificare quali impostazioni sono disponibili per questo scanner tramite la proprietà Capabilities dello ScanSource.
  5. Specificare il nome della cartella in cui verranno memorizzate le pagine acquisite. Il nome della cartella deve essere una variabile BSTR, ad esempio ScanFolder.
  6. Esegui il metodo BeginScan dell’object ScanSource, specificando come parametro il tipo di finestra di dialogo da mostrare all’utente (passa la costante SSUIT_None per non visualizzare alcuna finestra) e il percorso ScanFolder della cartella contenente i risultati. Devi inoltre passare il puntatore all’oggetto di callback che hai creato.
  7. Il percorso del file immagine viene restituito tramite la notifica OnImageScanned dell’interfaccia IScanCallback, mentre il completamento dell’operazione viene segnalato dalla notifica OnScanComplete. Poiché fornisci l’implementazione di questi metodi, puoi scegliere cosa fare in ciascuna di queste situazioni. Ad esempio, quando ricevi il percorso di un file immagine, puoi gestirlo come qualsiasi altro file su disco, caricandolo per l’elaborazione con FineReader Engine nel modo consueto.
Finché la scansione non è completata e non si riceve la notifica OnScanComplete, non è possibile eseguire nuovamente BeginScan o Scan, nemmeno per un altro scanner. Il vantaggio della scansione asincrona non è la possibilità di eseguire più operazioni di scansione contemporaneamente, ma quella di elaborare le immagini già ricevute mentre ne vengono acquisite di nuove.
Di seguito è riportato il codice di esempio per lo scenario di scansione asincrona:

C#

// Implementare l'interfaccia IScanCallback
class ScanningCallback :FREngine.IScanCallback
{
  // costruttore
  public ScanningCallback() {}
  ...
  // fornire l'implementazione dei metodi IScanCallback
  public void OnError(string sourceName, string message) { // segnalare o gestire l'errore qui }
  public void OnImageScanned(string sourceName, string Path, ref bool cancel) { // inserire qui le azioni da eseguire durante la scansione di un'immagine }
  public void OnScanComplete() { // inserire qui un'azione da eseguire al termine della scansione }
  // variabili private
  ...
}
// Creare il gestore di scansione con i log disattivati
scanManager = engineLoader.Engine.CreateScanManager(false);
// Creare un elenco di origini di scansione filtrate per tipo API e tipo UI
FREngine.IScanSources sources = scanManager.FindScanSources(UIType, APIType);
// A titolo di esempio, scegliere la prima origine di scansione dalla raccolta
FREngine.IScanSource selectedSource = sources[0];
// Accedere alle impostazioni e alle funzionalità dell'origine di scansione
FREngine.IScanSourceSettings settings = selectedSource.ScanSettings;
FREngine.IScanSourceCapabilities capabilities = selectedSource.Capabilities;
// Impostare le opzioni di scansione sulla modalità fronte-retro se lo scanner la supporta
settings.DuplexMode = capabilities.HasDuplexMode;
// Impostare le opzioni per la scansione multipagina e il ritardo di 10 secondi tra le pagine
settings.MultipleImagesEnabled = true;
settings.PauseBetweenPagesMode = FREngine.ScanPauseModeEnum.SPM_PresetDelay;
settings.Delay = 10;
// Impostare il percorso della cartella con i risultati
string scanFolder = "D:\\SampleImages";
// Creare un oggetto callback
IScanningCallback callback = new ScanningCallback();
// Avviare la scansione
selectedSource.BeginScan(SSUIT_None, scanFolder, callback);
Dopo aver terminato di lavorare con ABBYY FineReader Engine, è necessario rilasciare l’oggetto Engine. A tale scopo, utilizzare la funzione esportata DeinitializeEngine.

C#

public class EngineLoader : IDisposable
{
    // Rilascia FineReader Engine
    public void Dispose()
    {
        if (engine == null)
        {
            // Il motore non è stato caricato
            return;
        }
        engine = null;
        // Eliminazione di tutti gli oggetti prima della chiamata 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;
        // Genera un'eccezione dopo la pulizia
        Marshal.ThrowExceptionForHR(hresult);
    }
    // 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, , , , 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;
}

Risorse richieste

Puoi usare il file FREngineDistribution.csv per creare automaticamente un elenco dei file necessari al funzionamento dell’applicazione. Per l’elaborazione in questo scenario, seleziona nella colonna 5 (RequiredByModule) i seguenti valori: Core Core.Resources Opening Opening, Processing Opening.Scanning Se modifichi lo scenario standard, aggiorna di conseguenza i moduli richiesti. Devi inoltre specificare le lingue dell’interfaccia, le lingue di riconoscimento e tutte le funzionalità aggiuntive usate dall’applicazione (ad esempio, Processing.OCR.CJK se devi riconoscere testi in lingue CJK). Per ulteriori dettagli, consulta Working with the FREngineDistribution.csv File.

Ottimizzazione aggiuntiva

Queste sono le sezioni della Guida in cui è possibile trovare ulteriori informazioni sulla configurazione dei parametri per le varie fasi di elaborazione:
  • Separazione dei documenti
    • In questo scenario, potrebbe essere necessario raggruppare il flusso di immagini in ingresso in documenti. Ad esempio, potresti conoscere il numero di pagine di ciascun documento oppure assicurarti che tra l’ultima pagina del primo documento e la prima pagina del documento successivo siano presenti pagine separatrici con barcode. Consulta lo scenario di riconoscimento dei barcode.

Vedi anche

Implementazione degli scenari di utilizzo di base