> ## Documentation Index
> Fetch the complete documentation index at: https://docs.abbyy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# スキャン

> Windows で ABBYY FineReader Engine を使用して紙の文書をスキャンし、後続の Optical Character Recognition (OCR) 処理のために画像ファイルとして保存します — TWAIN ベースのスキャンシナリオ。

<Warning>
  このシナリオは Windows でのみ利用できます。
</Warning>

このシナリオでは、ABBYY FineReader Engine を「スキャン用コンピューター」で使用して画像をスキャンし、ファイルとして保存します。

このシナリオは、文書処理の前段階として、他のシナリオの一部として使用できます。つまり、後続の処理に備えて文書の電子版を取得するために使用されます。たとえば、保管用に文書をスキャンする場合、文書の編集可能な版を取得する場合、文書から特定のデータを抽出する場合などに利用できます。

紙の文書をスキャンして画像を電子形式で保存することで、印刷文書の高品質な電子版を作成できます。

文書は、次の処理段階を経る場合があります。

1. スキャン

   文書は、スキャナーで利用可能な 2 種類のスキャンインターフェース (TWAIN または WIA) のいずれかを使用してスキャンすることも、ABBYY 独自のスキャンインターフェースを使用してスキャンすることも、スキャンインターフェースを使用せずにスキャンすることもできます。

2. スキャン画像の前処理

   スキャン後、画像には前処理を施すことができます。前処理には、ノイズ除去、ゆがんだテキスト行の補正、色の反転、黒い余白の削除、画像の向きや解像度の補正が含まれます。見開きページは、2 つの別々の画像に分割できます。処理後の画像は、JPEG、TIFF、BMP などのさまざまな画像形式で保存できます。

<div id="scenario-implementation">
  ## シナリオの実装
</div>

以下では、このシナリオにおける ABBYY FineReader Engine 12 の推奨される使用方法について詳しく説明します。このシナリオの実装案では、画像準備のフェーズは省略されています。画像準備の実装に関するヒントについては、以下の[追加の最適化](/ja/fine-reader/engine/guided-tour/basic-usage-scenarios-implementation/scanning#optimization)を参照してください。

<Accordion title="ステップ 1. ABBYY FineReader Engine の読み込み">
  ABBYY FineReader Engine の使用を開始するには、[Engine](/ja/fine-reader/engine/api-reference/engine-object-iengine-interface) オブジェクトを作成する必要があります。Engine オブジェクトは、ABBYY FineReader Engine オブジェクト階層の最上位にあるオブジェクトで、さまざまなグローバル設定、一部の処理メソッド、および他のオブジェクトを作成するためのメソッドを提供します。

  Engine オブジェクトを作成するには、[InitializeEngine](/ja/fine-reader/engine/api-reference/functions/initializeengine-function) 関数を使用できます。あわせて、[Engine オブジェクトを読み込むその他の方法](/ja/fine-reader/engine/guided-tour/advanced-techniques/programming-aspects/different-ways-to-load-engine) (Win) も参照してください。

  ### C\#

  ```csharp theme={null}
  public class EngineLoader : IDisposable
  {
      public EngineLoader()
      {
          // これらの変数は、FREngine.dll へのフルパス、Customer Project ID、
          // および該当する場合は Online License トークンファイルへのパスと Online License パスワードで初期化してください
          string enginePath = "";
          string customerProjectId = "";
          string licensePath = "";
          string licensePassword = "";
          // 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");
              }
              // ポインターをデリゲートに変換する
              initializeEngine = (InitializeEngine)Marshal.GetDelegateForFunctionPointer(
                  initializeEnginePtr, typeof(InitializeEngine));
              deinitializeEngine = (DeinitializeEngine)Marshal.GetDelegateForFunctionPointer(
                  deinitializeEnginePtr, typeof(DeinitializeEngine));
              dllCanUnloadNow = (DllCanUnloadNow)Marshal.GetDelegateForFunctionPointer(
                  dllCanUnloadNowPtr, typeof(DllCanUnloadNow));
              // InitializeEngine 関数を呼び出し、 
              // Online License ファイルへのパスと Online License パスワードを渡す
              int hresult = initializeEngine(customerProjectId, licensePath, licensePassword, 
                  "", "", false, ref engine);
              Marshal.ThrowExceptionForHR(hresult);
          }
          catch (Exception)
          {
              // FREngine.dll ライブラリを解放する
              engine = null;
              // FreeLibrary の呼び出し前にすべてのオブジェクトを削除する
              GC.Collect();
              GC.WaitForPendingFinalizers();
              GC.Collect();
              FreeLibrary(dllHandle);
              dllHandle = IntPtr.Zero;
              initializeEngine = null;
              deinitializeEngine = null;
              dllCanUnloadNow = null;
              throw;
          }
      }
      // 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);
      // 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();
      // 非公開変数
      private FREngine.IEngine engine = null;
      // FREngine.dll へのハンドル
      private IntPtr dllHandle = IntPtr.Zero;
      private InitializeEngine initializeEngine = null;
      private DeinitializeEngine deinitializeEngine = null;
      private DllCanUnloadNow dllCanUnloadNow = null;
  }
  ```
</Accordion>

<Accordion title="ステップ 2. スキャン">
  ABBYY FineReader Engine には、スキャンソースを管理するための [ScanManager](/ja/fine-reader/engine/api-reference/mechanism-objects/scanmanager) オブジェクトが用意されています。このオブジェクトの [ScanSources](/ja/fine-reader/engine/api-reference/mechanism-objects/scansources) プロパティでは、利用可能なすべてのスキャナーの一覧にアクセスできます。また、[FindScanSources](/ja/fine-reader/engine/api-reference/mechanism-objects/scanmanager/findscansources-method) メソッドを使用すると、スキャナーが提供する API タイプおよびスキャンオプションの設定に使用するユーザーインターフェースの種類に基づいて、スキャナーを絞り込むことができます。

  ファイルをスキャンしてディスクに保存するには、[ScanSource](/ja/fine-reader/engine/api-reference/mechanism-objects/scansource) オブジェクトの以下の2つのメソッドのいずれかを使用します。スキャンが完了するまで処理を返さない [Scan](/ja/fine-reader/engine/api-reference/mechanism-objects/scansource/scan-method) メソッドと、非同期スキャン操作を開始して即座に処理を返す [BeginScan](/ja/fine-reader/engine/api-reference/mechanism-objects/scansource/beginscan-method) メソッドです。

  [IScanCallback](/ja/fine-reader/engine/api-reference/mechanism-objects/iscancallback) インターフェースを実装することで、スキャンの進行状況に関する通知を取得できます。

  ABBYY FineReader Engine 12 APIからアクセス可能なパラメーターには、明るさ、カラー、解像度、画像圧縮タイプ、画像の回転角度、スキャン領域のサイズ、両面スキャンモード、自動フィーダーモード、ページ間の一時停止などがあります。スキャンパラメーターは、ScanSourceオブジェクトの[ScanSettings](/ja/fine-reader/engine/api-reference/mechanism-objects/scansource#scansettings)プロパティを使用して設定します。このプロパティを使用して[ScanSourceSettings](/ja/fine-reader/engine/api-reference/mechanism-objects/scansourcesettings)オブジェクトにアクセスでき、そこからスキャンソースのスキャン設定を参照・変更できます。

  画像を同期的にスキャンするには：

  1. [ScanManager](/ja/fine-reader/engine/api-reference/mechanism-objects/scanmanager) オブジェクトを作成します。スキャンログを出力するかどうかは、[CreateScanManager](/ja/fine-reader/engine/api-reference/engine-object-iengine-interface/creation-methods/createscanmanager-method) メソッドの入力パラメーターで指定できます。
  2. スキャナーがサポートするAPIとUIの種類を指定して、ScanManagerオブジェクトの[FindScanSources](/ja/fine-reader/engine/api-reference/mechanism-objects/scanmanager/findscansources-method)メソッドを使用してスキャンソースを選択します。
  3. ユーザー自身がスキャン オプションを設定するためのダイアログを表示しない場合は、選択した[ScanSource](/ja/fine-reader/engine/api-reference/mechanism-objects/scansource)の[ScanSettings](/ja/fine-reader/engine/api-reference/mechanism-objects/scansource#scansettings)プロパティを使用してスキャン オプションを調整します。明るさ、解像度、その他のパラメーターには、ScanSourceSettings オブジェクトの対応するプロパティで適切な値を設定します。このスキャナーで使用可能な設定は、ScanSource の Capabilities プロパティで確認できます。
  4. スキャンしたページの保存先フォルダー名を指定します。フォルダー名には、たとえば ScanFolder のような BSTR 変数を指定する必要があります。
  5. ユーザーに表示するダイアログの種類 (何も表示しない場合は SSUIT\_None 定数を渡します) と、結果の保存先フォルダーの ScanFolder パスをパラメーターとして指定して、ScanSource オブジェクトの [Scan](/ja/fine-reader/engine/api-reference/mechanism-objects/scansource/scan-method) メソッドを実行します。
  6. このメソッドは、画像ファイル名を [StringsCollection](/ja/fine-reader/engine/api-reference/supplementary-objects-and-methods/stringscollection) オブジェクトで返します。この StringsCollection オブジェクトから画像ファイル名を取得し、それらのファイルを通常の画像ファイルと同様に処理できます。

  画像を非同期でスキャンするには：

  1. IScanCallback インターフェイスを実装するオブジェクトを作成します。非同期スキャン処理では、コールバック インターフェイスからの通知が非常に役立ちます。
  2. [ScanManager](/ja/fine-reader/engine/api-reference/mechanism-objects/scanmanager) オブジェクトを作成します。スキャンログを出力するかどうかは、CreateScanManager メソッドの入力パラメーターで指定できます。
  3. スキャナーがサポートするAPIとUIの種類を指定し、ScanManager オブジェクトの [FindScanSources](/ja/fine-reader/engine/api-reference/mechanism-objects/scanmanager/findscansources-method) メソッドを使用してスキャンソースを選択します。
  4. ユーザー自身がスキャン オプションを設定するためのダイアログを表示しない場合は、選択した ScanSource の [ScanSettings](/ja/fine-reader/engine/api-reference/mechanism-objects/scansource#scansettings) プロパティを使用してスキャン オプションを調整します。明るさ、解像度、その他のパラメーターについては、ScanSourceSettings オブジェクトの対応するプロパティで適切な値を選択します。このスキャナーで使用可能な設定は、ScanSource の Capabilities プロパティを使用して確認できます。
  5. スキャンしたページの保存先となるフォルダー名を指定します。フォルダー名は、たとえば ScanFolder のような BSTR 型の変数で指定する必要があります。
  6. ScanSource オブジェクトの [BeginScan](/ja/fine-reader/engine/api-reference/mechanism-objects/scansource/beginscan-method) メソッドを実行し、パラメーターとして、ユーザーに表示するダイアログの種類 (ダイアログを表示しない場合は `SSUIT&#95;None` 定数を渡します) 、および結果を格納するフォルダーの ScanFolder パスを指定します。さらに、作成したコールバック オブジェクトへのポインターも渡す必要があります。
  7. 画像ファイルへのパスは、IScanCallbackインターフェイスのOnImageScanned通知で返され、処理の完了はOnScanComplete通知で通知されます。これらのメソッドの実装は自分で行うため、それぞれの状況でどのように処理するかを選択できます。たとえば、画像ファイルへのパスを受け取ったら、ディスク上の他のファイルと同じように扱い、通常どおりFineReader Engineで処理するために読み込むことができます。

  <Warning>
    スキャンが完了し、OnScanComplete 通知を受信するまでは、別のスキャナーであっても BeginScan や Scan を実行することはできません。非同期スキャンの利点は、複数のスキャン処理を同時に実行できることではなく、新しい画像がスキャンされている間に、すでに受信した画像を処理できる点にあります。
  </Warning>

  非同期スキャンシナリオのサンプルコードを以下に示します。

  ### C\#

  ```csharp theme={null}
  // IScanCallbackインターフェースを実装する
  class ScanningCallback :FREngine.IScanCallback
  {
    // コンストラクター
    public ScanningCallback() {}
    ...
    // IScanCallbackメソッドの実装を提供する
    public void OnError(string sourceName, string message) { // ここでエラーを報告または処理する }
    public void OnImageScanned(string sourceName, string Path, ref bool cancel) { // 画像スキャン時に必要な処理をここに記述する }
    public void OnScanComplete() { // スキャン完了後に実行したい処理をここに記述する }
    // プライベート変数
    ...
  }
  // ログを無効にしてスキャンマネージャーを作成する
  scanManager = engineLoader.Engine.CreateScanManager(false);
  // APIタイプとUIタイプでフィルタリングしたスキャンソースの一覧を作成する
  FREngine.IScanSources sources = scanManager.FindScanSources(UIType, APIType);
  // 例として、コレクションの先頭のスキャンソースを選択する
  FREngine.IScanSource selectedSource = sources[0];
  // スキャンソースの設定と機能を取得する
  FREngine.IScanSourceSettings settings = selectedSource.ScanSettings;
  FREngine.IScanSourceCapabilities capabilities = selectedSource.Capabilities;
  // スキャナーが両面モードをサポートしている場合、スキャンオプションを両面モードに設定する
  settings.DuplexMode = capabilities.HasDuplexMode;
  // 複数ページスキャンとページ間の10秒の遅延を設定する
  settings.MultipleImagesEnabled = true;
  settings.PauseBetweenPagesMode = FREngine.ScanPauseModeEnum.SPM_PresetDelay;
  settings.Delay = 10;
  // 結果を保存するフォルダーのパスを設定する
  string scanFolder = "D:\\SampleImages";
  // コールバックオブジェクトを作成する
  IScanningCallback callback = new ScanningCallback();
  // スキャンを開始する
  selectedSource.BeginScan(SSUIT_None, scanFolder, callback);
  ```
</Accordion>

<Accordion title="ステップ 3. ABBYY FineReader Engine のアンロード">
  ABBYY FineReader Engine の使用を終えたら、[Engine](/ja/fine-reader/engine/api-reference/engine-object-iengine-interface) オブジェクトをアンロードする必要があります。そのためには、エクスポート関数 [DeinitializeEngine](/ja/fine-reader/engine/api-reference/functions/deinitializeengine-function) を使用します。

  ### C\#

  ```csharp theme={null}
  public class EngineLoader : IDisposable
  {
      // FineReader Engine をアンロードする
      public void Dispose()
      {
          if (engine == null)
          {
              // Engine はロードされていない
              return;
          }
          engine = null;
          // 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;
          // クリーンアップ後に例外をスローする
          Marshal.ThrowExceptionForHR(hresult);
      }
      // 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);
      // 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();
      // プライベート変数
      private FREngine.IEngine engine = null;
      // FREngine.dll へのハンドル
      private IntPtr dllHandle = IntPtr.Zero;
      private InitializeEngine initializeEngine = null;
      private DeinitializeEngine deinitializeEngine = null;
      private DllCanUnloadNow dllCanUnloadNow = null;
  }
  ```
</Accordion>

<div id="required-resources">
  ## 必要なリソース
</div>

[FREngineDistribution.csv](/ja/fine-reader/engine/distribution/distribution-windows/distribution-kit/working-with-the-frenginedistributioncsv-file) ファイルを使用すると、アプリケーションの動作に必要なファイルのリストを自動的に作成できます。このシナリオで処理を行うには、5 列目 (RequiredByModule) で次の値を選択します。

Core

Core.Resources

Opening

Opening, Processing

Opening.Scanning

標準シナリオを変更する場合は、それに応じて必要なモジュールも変更してください。また、インターフェース言語、認識言語、およびアプリケーションで使用する追加機能も指定する必要があります (たとえば、[CJK 言語](/ja/fine-reader/engine/guided-tour/advanced-techniques/recognizing-cjk-languages#cjk) のテキストを認識する必要がある場合は、Processing.OCR.CJK など) 。詳細については、[Working with the FREngineDistribution.csv File](/ja/fine-reader/engine/distribution/distribution-windows/distribution-kit/working-with-the-frenginedistributioncsv-file) を参照してください。

<div id="additional-optimization">
  ## 追加の最適化
</div>

各処理段階のパラメーター設定についてさらに詳しくは、ヘルプファイルの以下のセクションを参照してください。

* 文書の分割
  * このシナリオでは、入力される画像の流れを文書単位にグループ化する必要が生じることがあります。たとえば、各文書のページ数があらかじめ分かっている場合や、最初の文書の最終ページと次の文書の先頭ページの間に、バーコード付きの区切りページが入るようにする場合です。詳しくは、[バーコード認識シナリオ](/ja/fine-reader/engine/guided-tour/basic-usage-scenarios-implementation/barcode-recognition)を参照してください。

<div id="see-also">
  ## 関連項目
</div>

[基本的な使用シナリオの実装方法](/ja/fine-reader/engine/guided-tour/basic-usage-scenarios-implementation)
