Performs automatic bitmap processing clean up on the image to enhance the quality of the page before beginning recognition.


#include "ltocr.h"

L_LTOCR_API L_INT EXT_FUNCTION L_OcrPage_AutoPreprocess(page, commands, callback, userData)


L_OcrPage page

Handle to the OCR page.

L_OcrAutoPreprocessPageCommands commands

The preprocessing command to perform.

L_OcrProgressCallback callback

Optional callback to show operation progress.

L_VOID* userData

Optional user data to pass to the callback function.


Value Meaning
SUCCESS The function was successful.
< 1 An error occurred. Refer to Return Codes.


Performs automatic bitmap processing clean up on the image to enhance the quality of the page before beginning recognition.

Use this method to deskew, rotate or invert the bitmap according to command. By performing auto pre-processing on a page, you can improve the image quality of draft mode faxes.

Use the L_OcrProgressCallback to show the operation progress or to abort it. For more information and an example, refer to L_OcrProgressCallback.

Call this method prior to calling L_OcrPage_Recognize.

This method will call L_OcrPage_GetDeskewAngle, L_OcrPage_GetRotateAngle and L_OcrPage_IsInverted to determine whether the page needs processing, if the page does, this method will internally deskews, rotates or inverts the image accordingly.

If the image is skewed, L_OcrPage_GetDeskewAngle will return the angle needed to deskew the page bitmap, if you call L_OcrPage_AutoPreprocess on the page, all subsequent calls to L_OcrPage_GetDeskewAngle will return 0 since the bitmap is no longer skewed. Same with L_OcrPage_GetRotateAngle and L_OcrPage_IsInverted.

Use L_OcrPage_GetAutoPreprocessValues to obtain the accumulative pre-processing values applied to this L_OcrPage.

This method works on both the original and processing version of the image. For example, if you add a page that is skewed and call L_OcrPage_AutoPreprocess width L_OcrAutoPreprocessPageCommand_Deskew, then obtain either the original or processing bitmaps with L_OcrPage_GetBitmap, you will get two bitmap handles that are both rotated and deskewed.

Required DLLs and Libraries

See Also




static L_INT CreateSampleImage(pBITMAPHANDLE bitmapHandle) 
   L_INT retVal = -1; 
   //Make it white on black 
   L_UINT reserved = 0; 
   retVal = L_InvertBitmap(bitmapHandle, reserved); 
   if(retVal != SUCCESS) 
      return retVal; 
   //Rotate 185 degrees to simulate upside-down skewed image 
   L_COLORREF fillColor = NULL; 
   retVal = L_RotateBitmap(bitmapHandle, 18500, ROTATE_CROP, fillColor); 
   if(retVal != SUCCESS) 
      return retVal; 
   return SUCCESS; 
static L_VOID EXT_CALLBACK bitmapChangedCB(L_OcrPage /*page*/, L_OcrAutoPreprocessPageCommands commands, L_VOID* /*userData*/) 
   std::cout << "L_OcrPageBitmapChangedCallback fired with the following command flag:\n"; 
   case L_OcrAutoPreprocessPageCommands_None: 
      std::cout << "L_OcrAutoPreprocessPageCommands_None\n"; 
   case L_OcrAutoPreprocessPageCommands_All: 
      std::cout << "L_OcrAutoPreprocessPageCommands_All\n"; 
   case L_OcrAutoPreprocessPageCommands_Deskew: 
      std::cout << "L_OcrAutoPreprocessPageCommands_Deskew\n"; 
   case L_OcrAutoPreprocessPageCommands_Rotate: 
      std::cout << "L_OcrAutoPreprocessPageCommands_Rotate\n"; 
   case L_OcrAutoPreprocessPageCommands_Invert: 
      std::cout << "L_OcrAutoPreprocessPageCommands_Invert\n"; 
L_INT L_OcrPage_AutoPreprocessExample() 
   BITMAPHANDLE bitmap = { 0 }; 
   L_OcrEngine ocrEngine = NULL; 
   L_OcrPage ocrPage = NULL; 
   L_OcrDocumentManager ocrDocumentManager = NULL; 
   L_OcrDocument ocrDocument = NULL; 
   // Create an instance of the engine 
   L_INT retCode = L_OcrEngineManager_CreateEngine(L_OcrEngineType_LEAD, &ocrEngine); 
   if(retCode != SUCCESS) 
      return retCode; 
   // Load a page to process 
   retCode = L_LoadBitmap(MAKE_IMAGE_PATH(L_TEXT("Ocr1.tif")), &bitmap, sizeof(BITMAPHANDLE), 0, ORDER_RGB, NULL, NULL); 
   if(retCode != SUCCESS) 
      return retCode; 
   // Create a sample image to test with 
   retCode = CreateSampleImage(&bitmap); 
   if(retCode != SUCCESS) 
      goto CLEANUP; 
   // Start the engine using default parameters 
   std::cout << "Starting up the engine...\n"; 
   retCode = L_OcrEngine_Startup(ocrEngine, NULL, OCR_LEAD_RUNTIME_DIR); 
   if(retCode == SUCCESS) 
      // Add this image to the document 
      retCode = L_OcrPage_FromBitmap(ocrEngine, &ocrPage, &bitmap, L_OcrBitmapSharingMode_AutoFree, NULL, NULL); 
      if(retCode != SUCCESS) 
         return retCode; 
      // We have a valid page and bitmap ownership has transfered. So, we do not need to free the bitmap anymore. 
      // Bitmap will be freed when ocrPage is destroyed. 
      bitmap.Flags.Allocated = 0; 
      L_OcrPage_SetBitmapChangedCallback(ocrPage, &bitmapChangedCB, NULL); 
      // show that the original page is inverted 
      L_BOOL isInverted = L_FALSE; 
      L_OcrPage_IsInverted(ocrPage, &isInverted); 
         std::cout << "Before AutoPreprocess: OCR page is inverted"; 
         std::cout << "Before AutoPreprocess: OCR page is not inverted"; 
      // Auto-preprocess it 
      std::cout << "Preprocessing the page...\n"; 
      // Note: The following can be condensed into a single call using the flag 
      // L_OcrAutoPreprocessPageCommands_All. They have been listed out here for illustration. 
      L_OcrPage_AutoPreprocess(ocrPage, L_OcrAutoPreprocessPageCommands_Invert, NULL, NULL); 
      L_OcrPage_AutoPreprocess(ocrPage, L_OcrAutoPreprocessPageCommands_Rotate, NULL, NULL); 
      L_OcrPage_AutoPreprocess(ocrPage, L_OcrAutoPreprocessPageCommands_Deskew, NULL, NULL); 
      // check for image inversion again and show result 
      L_OcrPage_IsInverted(ocrPage, &isInverted); 
         std::cout << "After AutoPreprocess: OCR page is inverted"; 
         std::cout << "After AutoPreprocess: OCR page is not inverted"; 
      // Get bitmap and save it out to show preprocessing 
      BITMAPHANDLE exportPage = { 0 }; 
      L_OcrPage_GetBitmap(ocrPage, L_OcrPageBitmapType_Original, &exportPage, sizeof(BITMAPHANDLE)); 
      if(exportPage.Flags.Allocated != 0) 
         retCode = L_SaveBitmap(MAKE_IMAGE_PATH(L_TEXT("Ocr1_Preproccessed.tif")), &exportPage, FILE_CCITT_GROUP4, 1, 0, NULL); 
      // Recognize it and save it as PDF 
      std::cout << "Recognizing...\n"; 
      retCode = L_OcrPage_Recognize(ocrPage, NULL, NULL); 
      if(retCode != SUCCESS) 
         goto CLEANUP; 
      // Get the document manager 
      retCode = L_OcrEngine_GetDocumentManager(ocrEngine, &ocrDocumentManager); 
      if(retCode != SUCCESS) 
         goto CLEANUP; 
      // Create an OCR document 
      retCode = L_OcrDocumentManager_CreateDocument(ocrDocumentManager, &ocrDocument, L_OcrCreateDocumentOptions_AutoDeleteFile, NULL); 
      if(retCode != SUCCESS) 
         goto CLEANUP; 
      // In Document File Mode, add OcrPage to OcrDocument after recognition 
      retCode = L_OcrDocument_AddPage(ocrDocument, ocrPage); 
      if(retCode != SUCCESS) 
         goto CLEANUP; 
      // Adding the page to a file based document will take a snap shot of the recognition data and store it in the document.  
      // At this point, the page is no longer needed. So destroy it to free up memory not used anymore 
      // Set the handle to NULL so we do not free it in our clean-up code 
      ocrPage = NULL; 
      std::wcout << "Saving the output file...\"" << MAKE_IMAGE_PATH(L_TEXT("Clean.pdf")) << "\"\n"; 
      retCode = L_OcrDocument_Save(ocrDocument, MAKE_IMAGE_PATH(L_TEXT("Clean.pdf")), DOCUMENTFORMAT_PDF, NULL, NULL); 
   if(ocrPage != NULL) 
   if(ocrDocument != NULL) 
   if(ocrEngine != NULL) 
   return retCode; 
Help Version 23.0.2024.2.29
Products | Support | Contact Us | Intellectual Property Notices
© 1991-2024 LEAD Technologies, Inc. All Rights Reserved.


Products | Support | Contact Us | Intellectual Property Notices
© 1991-2023 LEAD Technologies, Inc. All Rights Reserved.