> ## 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.

# Barcode Recognition

> Use ABBYY FineReader Engine to read barcodes for document separation, indexing, and classification — tune speed and accuracy with the BarcodeRecognition profile.

In this scenario, ABBYY FineReader Engine is used to read barcodes. Barcodes may need to be read, for example, for purposes of automatic document separation, for processing documents by a Document Management System, or for indexing and classifying documents.

This scenario may be used as part of other scenarios. For example, documents scanned with high-speed production scanners may be separated by means of barcodes, or documents prepared for long-term storage may be placed into archiving Document Management Systems based on the values of their barcodes.

When extracting barcodes from texts, the system may detect all barcodes or only barcodes of a certain type with a certain value. The system may get the value of a barcode and calculate its checksum. To obtain the fastest and highest quality results of the barcode recognition:

1. Use color pictures with an optimal resolution of 300 dpi.

2. Tune the recognition speed using profiles (see [Working with Profiles](/fine-reader/engine/guided-tour/advanced-techniques/working-with-profiles) for details).

Recognized barcode values can be saved into formats most convenient for further processing, for example, into TXT.

## Scenario implementation

<Note>
  The code samples provided in this topic are Windows -specific.
</Note>

Below follows a detailed description of the recommended method of using ABBYY FineReader Engine 12 in this scenario. The suggested method uses processing settings deemed most appropriate for this scenario.

<Accordion title="Step 1. Loading ABBYY FineReader Engine">
  To start your work with ABBYY FineReader Engine, you need to create the [Engine](/fine-reader/engine/api-reference/engine-object-iengine-interface) object. The Engine object is the top object in the hierarchy of the ABBYY FineReader Engine objects and provides various global settings, some processing methods, and methods for creating the other objects.

  To create the Engine object, you can use the [InitializeEngine](/fine-reader/engine/api-reference/functions/initializeengine-function) function. See also [other ways to load Engine object](/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()
      {
          // Initialize these variables with the full path to FREngine.dll, your Customer Project ID,
          // and, if applicable, the path to your Online License token file and the Online License password
          string enginePath = "";
          string customerProjectId = "";
          string licensePath = "";
          string licensePassword = "";
          // Load the FREngine.dll library
          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");
              }
              // Convert pointers to delegates
              initializeEngine = (InitializeEngine)Marshal.GetDelegateForFunctionPointer(
                  initializeEnginePtr, typeof(InitializeEngine));
              deinitializeEngine = (DeinitializeEngine)Marshal.GetDelegateForFunctionPointer(
                  deinitializeEnginePtr, typeof(DeinitializeEngine));
              dllCanUnloadNow = (DllCanUnloadNow)Marshal.GetDelegateForFunctionPointer(
                  dllCanUnloadNowPtr, typeof(DllCanUnloadNow));
              // Call the InitializeEngine function 
              // passing the path to the Online License file and the Online License password
              int hresult = initializeEngine(customerProjectId, licensePath, licensePassword, 
                  "", "", false, ref engine);
              Marshal.ThrowExceptionForHR(hresult);
          }
          catch (Exception)
          {
              // Free the FREngine.dll library
              engine = null;
              // Deleting all objects before FreeLibrary call
              GC.Collect();
              GC.WaitForPendingFinalizers();
              GC.Collect();
              FreeLibrary(dllHandle);
              dllHandle = IntPtr.Zero;
              initializeEngine = null;
              deinitializeEngine = null;
              dllCanUnloadNow = null;
              throw;
          }
      }
      // Kernel32.dll functions
      [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 functions
      [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 variables
      private FREngine.IEngine engine = null;
      // Handle to FREngine.dll
      private IntPtr dllHandle = IntPtr.Zero;
      private InitializeEngine initializeEngine = null;
      private DeinitializeEngine deinitializeEngine = null;
      private DllCanUnloadNow dllCanUnloadNow = null;
  }
  ```

  ### C++ (COM)

  ```cpp theme={null}
  // Initialize these variables with the path to FREngine.dll, your FineReader Engine customer project ID,
  // and, if applicable, the path to the Online License token and Online License password
  wchar_t* FreDllPath;
  wchar_t* CustomerProjectId;
  wchar_t* LicensePath;  // if you don't use an Online License, assign empty strings to these variables
  wchar_t* LicensePassword;
  // HANDLE to FREngine.dll
  static HMODULE libraryHandle = 0;
  // Global FineReader Engine object
  FREngine::IEnginePtr Engine;
  void LoadFREngine()
  {
      if( Engine != 0 ) {
      // Already loaded
      return;
      }
      // First step: load FREngine.dll
      if( libraryHandle == 0 ) {
          libraryHandle = LoadLibraryEx( FreDllPath, 0, LOAD_WITH_ALTERED_SEARCH_PATH );
          if( libraryHandle == 0 ) {
              throw L"Error while loading ABBYY FineReader Engine";
          }
      }
      // Second step: obtain the Engine object
      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"Error while loading ABBYY FineReader Engine";
      }
  }
  ```
</Accordion>

<Accordion title="Step 2. Loading settings for the scenario">
  The most suitable settings can be selected by using the [LoadPredefinedProfile](/fine-reader/engine/api-reference/engine-object-iengine-interface/supplementary-methods/loadpredefinedprofile-method) method of the [Engine](/fine-reader/engine/api-reference/engine-object-iengine-interface) object. This method accepts the name of the settings profile being used as an input parameter. For more about profiles, see [Working with Profiles](/fine-reader/engine/guided-tour/advanced-techniques/working-with-profiles).

  ABBYY FineReader Engine supports 2 variants of settings for this scenario:

  | Profile name                   | Description                                                                                                                                                                                                                                                                                     |
  | ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  | BarcodeRecognition\\\_Accuracy | Extracts only barcodes (texts, pictures, or tables are not detected). The settings have been optimized for accuracy. <Warning> This profile requires the [Barcode Autolocation](/fine-reader/engine/licensing/modules#barcode_autolocation) module available in the license. </Warning>         |
  | BarcodeRecognition\\\_Speed    | Extracts only barcodes (texts, pictures, or tables are not detected). The settings have been optimized for processing speed. <Warning> This profile requires the [Barcode Autolocation](/fine-reader/engine/licensing/modules#barcode_autolocation) module available in the license. </Warning> |

  ### C\#

  ```csharp theme={null}
  // Load a predefined profile
  engine.LoadPredefinedProfile("BarcodeRecognition_Speed");
  ```

  ### C++ (COM)

  ```cpp theme={null}
  // Load a predefined profile
  Engine->LoadPredefinedProfile( L"BarcodeRecognition_Speed" );
  ```

  If you wish to change the settings used for processing, use the corresponding parameter objects. See the [Additional optimization](/fine-reader/engine/guided-tour/basic-usage-scenarios-implementation/barcode-recognition#optimization) section below for more information.
</Accordion>

<Accordion title="Step 3. Loading and preprocessing the images">
  ABBYY FineReader Engine provides a [FRDocument](/fine-reader/engine/api-reference/document-related-objects/frdocument) object for processing multi-page documents. To load the images of a document and preprocess them, you should create the FRDocument object and add images to it. You can do one of the following:

  * Create an FRDocument object using the [CreateFRDocumentFromImage](/fine-reader/engine/api-reference/engine-object-iengine-interface/creation-methods/createfrdocumentfromimage-method) method of the Engine object. This method creates an FRDocument object and loads images from a specified file.
  * Create an FRDocument object with the help of the [CreateFRDocument](/fine-reader/engine/api-reference/engine-object-iengine-interface/creation-methods/createlessobjectgreater-methods) method of the Engine object, then add the images into the created FRDocument object from a file (use the [AddImageFile](/fine-reader/engine/api-reference/document-related-objects/frdocument/addimagefile-method), [AddImageFileWithPassword](/fine-reader/engine/api-reference/document-related-objects/frdocument/addimagefilewithpassword-method), or [AddImageFileWithPasswordCallback](/fine-reader/engine/api-reference/document-related-objects/frdocument/addimagefilewithpasswordcallback-method) method of the FRDocument object).

  ### C\#

  ```csharp theme={null}
  // Create the FRDocument object from an image file
  FREngine.IFRDocument frDocument = engine.CreateFRDocumentFromImage( "C:\\MyImage.tif", null );
  ```

  ### C++ (COM)

  ```cpp theme={null}
  // Open an image file and create the FRDocument object
  FREngine::IFRDocumentPtr frDocument = Engine->CreateFRDocumentFromImage( L"C:\\MyImage.tif", 0 );
  ```
</Accordion>

<Accordion title="Step 4. Extracting barcodes">
  If the BarcodeRecognition profile is loaded, you can use the [Process](/fine-reader/engine/api-reference/document-related-objects/frdocument/process-method) method of the FRDocument object to extract only barcodes. In this case, ABBYY FineReader Engine detects only blocks with barcodes. No other blocks are detected. The recognized barcode blocks can be accessed via the [Layout](/fine-reader/engine/api-reference/layout-related-objects/layout) object, which is a subobject of the [FRPage](/fine-reader/engine/api-reference/document-related-objects/frpage) object representing a page of the document.

  To read barcodes of specific type, specify the appropriate parameters of the [BarcodeParams](/fine-reader/engine/api-reference/parameter-objects/preprocessing-analysis-recognition-and-synthesis-parameters/barcodeparams) object and pass the BarcodeParams object as a parameter of one of the above functions.

  ### C\#

  ```csharp theme={null}
  // While the BarcodeRecognition profile is loaded,
  // you do not need to pass any additional parameters to the processing method,
  // if barcodes conform to specification
  frDocument.Process( null );
  // If you need to read barcodes of specific type
  // Create a DocumentProcessingParams object
  FREngine.IDocumentProcessingParams dpp = engine.CreateDocumentProcessingParams();
  // Specify the necessary parameters
  dpp.PageProcessingParams.PageAnalysisParams.BarcodeParams.Type = ( int )FREngine.BarcodeTypeEnum.BT_Code39;
  // Now recognize barcodes with these parameters
  frDocument.Process( dpp );
  ```

  ### C++ (COM)

  ```cpp theme={null}
  // While the BarcodeRecognition profile is loaded,
  // you do not need to pass any additional parameters to the processing method,
  // if barcodes conform to specification
  frDocument->Process( 0 );
  // If you need to read barcodes of specific type
  // Create a DocumentProcessingParams object
  FREngine::IDocumentProcessingParamsPtr params = Engine->CreateDocumentProcessingParams();
  // Specify the necessary parameters
  params->PageProcessingParams->PageAnalysisParams->BarcodeParams->Type = FREngine::BT_Code39;
  // Now recognize barcodes with these parameters
  frDocument->Process( params );
  ```
</Accordion>

<Accordion title="Step 5. Exporting the recognized data">
  To save the values of the recognized barcodes to a file, you may use the [Export](/fine-reader/engine/api-reference/document-related-objects/frdocument/export-method) method of the [FRDocument](/fine-reader/engine/api-reference/document-related-objects/frdocument) object by assigning the [FileExportFormatEnum](/fine-reader/engine/api-reference/enumerations/fileexportformatenum) constant as one of the parameters. This scenario can export, for example, to TXT. You may change the default parameters of export using the corresponding export object. Please see [Additional optimization for specific tasks](/fine-reader/engine/guided-tour/basic-usage-scenarios-implementation/barcode-recognition#optimization) below for further information.

  After you have finished your work with the FRDocument object, release all the resources that were used by this object. Use the [IFRDocument::Close](/fine-reader/engine/api-reference/document-related-objects/frdocument/close-method) method.

  ### C\#

  ```csharp theme={null}
  // Save recognized barcodes to some format (e.g., TXT)
  frDocument.Export( "C:\\barcodes.txt", FREngine.FileExportFormatEnum.FEF_TextUnicodeDefaults, null );
  // Release the FRDocument object
  frDocument.Close();
  ```

  ### C++ (COM)

  ```cpp theme={null}
  // Save recognized barcodes to some format (e.g., TXT)
  frDocument->Export( L"C:\\barcodes.txt", FREngine::FEF_TextUnicodeDefaults, 0 );
  // Release the FRDocument object
  frDocument->Close();
  ```
</Accordion>

<Accordion title="Step 6. Unloading ABBYY FineReader Engine">
  After finishing your work with ABBYY FineReader Engine, you need to unload the [Engine](/fine-reader/engine/api-reference/engine-object-iengine-interface) object. To do this, use the [DeinitializeEngine](/fine-reader/engine/api-reference/functions/deinitializeengine-function) exported function.

  ### C\#

  ```csharp theme={null}
  public class EngineLoader : IDisposable
  {
      // Unload FineReader Engine
      public void Dispose()
      {
          if (engine == null)
          {
              // Engine was not loaded
              return;
          }
          engine = null;
          // Deleting all objects before FreeLibrary call
          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;
          // throwing exception after cleaning up
          Marshal.ThrowExceptionForHR(hresult);
      }
      // Kernel32.dll functions
      [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 functions
      [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 variables
      private FREngine.IEngine engine = null;
      // Handle to FREngine.dll
      private IntPtr dllHandle = IntPtr.Zero;
      private InitializeEngine initializeEngine = null;
      private DeinitializeEngine deinitializeEngine = null;
      private DllCanUnloadNow dllCanUnloadNow = null;
  }
  ```

  ### C++ (COM)

  ```cpp theme={null}
  void UnloadFREngine()
  {
   if( libraryHandle == 0 ) {
    return;
   }
   // Release Engine object
   Engine = 0;
   // Deinitialize FineReader Engine
   typedef HRESULT ( STDAPICALLTYPE* DeinitializeEngineFunc )();
   DeinitializeEngineFunc pDeinitializeEngine =
    ( DeinitializeEngineFunc )GetProcAddress( libraryHandle, "DeinitializeEngine" );
   if( pDeinitializeEngine == 0 || pDeinitializeEngine() != S_OK ) {
    throw L"Error while unloading ABBYY FineReader Engine";
   }
   // Now it's safe to free the FREngine.dll library
   FreeLibrary( libraryHandle );
   libraryHandle = 0;
  }
  ```
</Accordion>

## Required resources

You can use the [FREngineDistribution.csv](/fine-reader/engine/distribution/distribution-windows/distribution-kit/working-with-the-frenginedistributioncsv-file) file to automatically create a list of files required for your application to function. For processing with this scenario, select in the column 5 (RequiredByModule) the following values:

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

If you modify the standard scenario, change the required modules accordingly. You also need to specify the interface languages, recognition languages and any additional features which your application uses (such as, e.g., Opening.PDF if you need to open PDF files, or Processing.OCR.CJK if you need to recognize texts in [CJK languages](/fine-reader/engine/guided-tour/advanced-techniques/recognizing-cjk-languages#cjk)). See [Working with the FREngineDistribution.csv File](/fine-reader/engine/distribution/distribution-windows/distribution-kit/working-with-the-frenginedistributioncsv-file) for further details.

## Additional optimization

These are the sections of the help file where you can find additional information about setting up the parameters for the various processing stages:

* Extracting and reading barcodes
  * [BarcodeParams Object](/fine-reader/engine/api-reference/parameter-objects/preprocessing-analysis-recognition-and-synthesis-parameters/barcodeparams)<br />This object allows you to set up the barcode analysis and reading parameters.
  * [Recognizing Barcodes](/fine-reader/engine/guided-tour/advanced-techniques/recognizing-barcodes)<br />Discusses special cases in barcode recognition and provides hints on working with barcodes.
  * [Barcode Types](/fine-reader/engine/specifications/barcode-types)<br />The list of barcodes supported in ABBYY FineReader Engine 12 and their brief descriptions.
  * [FRDocument Object](/fine-reader/engine/api-reference/document-related-objects/frdocument)<br />Apart from barcode values, you may need to extract other information contained in document. In this case, you may wish to use the methods of the FRDocument object.
  * [PageProcessingParams Object](/fine-reader/engine/api-reference/parameter-objects/preprocessing-analysis-recognition-and-synthesis-parameters/pageprocessingparams)<br />This object allows you to set up analysis and recognition parameters for the entire document. Using this object, you may specify whether barcode values should be recognized. The barcode reading parameters are accessible via the BarcodeParams and DetectBarcodes properties of the PageAnalysisParams subobject.
  * [Working with Layout and Blocks](/fine-reader/engine/guided-tour/advanced-techniques/working-with-layout-and-blocks)<br />You can also mark barcode blocks manually and specify their analysis and reading parameters. This section provides detailed information on working with blocks.
* Working with the recognized barcode values
  * [BarcodeBlock Object](/fine-reader/engine/api-reference/layout-related-objects/barcodeblock)<br />The Text and BarcodeText properties of this object contain the value of the barcode obtained through recognition. The other properties of this object can be used to get the type of the barcode, its orientation, and other parameters.
* Export
  * [Tuning Export Parameters](/fine-reader/engine/guided-tour/advanced-techniques/tuning-export-parameters)<br />Setting up export with the objects of export parameters.
  * [TextExportParams Object](/fine-reader/engine/api-reference/parameter-objects/export-parameters/textexportparams)<br />This object allows you to set up the saving of recognition results to TXT.

## See also

[Basic Usage Scenarios Implementation](/fine-reader/engine/guided-tour/basic-usage-scenarios-implementation)
