Load and Save OCR Zones - Windows C DLL

This tutorial shows how to load, display and save OCR zones in a Windows C DLL application using the LEADTOOLS SDK.

Overview  
Summary This tutorial covers how to load and save OCR zones in a Windows C DLL application
Completion Time 30 minutes
Visual Studio Project Download tutorial project (19 KB)
Platform Windows C DLL Application
IDE Visual Studio 2017, 2019
Development License Download LEADTOOLS
Try it in another language

Required Knowledge

Get familiar with the basic steps of creating a project and working with LEADTOOLS OCR technologies by reviewing the Add References and Set a License and Convert Images to Searchable PDF with OCR tutorials, before working on the Load and Save OCR Zones - Windows C DLL tutorial.

Create the Project and Add LEADTOOLS References

Start with a copy of the project created in the Convert Images to Searchable PDF with OCR tutorial. If the project is not available, create it by following the steps in that tutorial.

To utilize LEADTOOLS OCR functionality, add the required header and library files. Open the pre-compiled header file (either pch.h or stdafx.h, depending on the version of Visual Studio used) and ensure the below lines are added.

#include "c:\LEADTOOLS22\Include\ltocr.h" 
 
#pragma comment (lib, "C:\\LEADTOOLS22\\Lib\\CDLL\\x64\\Ltocr_x.lib") // OCR support 

Note

For a complete list of DLLs that are required for specific application features, refer to Files to be Included with your Application - C API.

Set the License File

The License unlocks the features needed for the project. It must be set before any toolkit functionality is called. For details, including tutorials for different platforms, refer to Setting a Runtime License.

There are two types of runtime licenses:

Note

Adding LEADTOOLS references and setting a license are covered in more detail in the Add References and Set a License tutorial.

Add the Display OCR Zones Code

With the project created, the references added, the license set, and the load image code added, coding can begin.

In the Solution Explorer, double-click the resources file (.rc).

Add a new &Zones drop down menu next to the OCR menu. Add the three menu items in the table below to the newly-added Zones menu.

Menu Item Text Item ID
&Display Zones ID_ZONES_DISPLAYZONES
&Load Zones ID_ZONES_LOADZONES
&Save Zones ID_ZONES_SAVEZONES

Navigate to the WndProc function inside the project's CPP file. Inside the ID_FILE_OPEN case, locate the call to the L_OcrPage_FromBitmap function and add a call to L_OcrPage_AutoZone below it, as shown below.

// Below the following line: 
L_OcrPage_FromBitmap(ocrEngine, &ocrPage, &LEADBmp, L_OcrBitmapSharingMode_None, NULL, NULL); 
// Add the following line: 
L_OcrPage_AutoZone(ocrPage, NULL, NULL); 

Under the switch (wmId) statement that is below the WM_COMMAND case, add the following code to create a new case. This new case will paint the OCR zones in the OcrPage to the viewer.

switch (wmId) 
{ 
case ID_ZONES_DISPLAYZONES: 
{ 
   if (!ocrPage) 
   { 
      MessageBox(hWnd, TEXT("Cannot search for OCR zones; no page added"), TEXT("LEADTOOLS Demo"), MB_ICONERROR); 
      break; 
   } 
   L_UINT uZones = 0; 
   L_OcrPage_GetZoneCount(ocrPage, &uZones); 
   if (0 == uZones) 
   { 
      MessageBox(hWnd, TEXT("No OCR zones to draw."), TEXT("LEADTOOLS Demo"), MB_ICONERROR); 
      break; 
   } 
   HDC hdc = GetDC(hWnd); 
   SelectObject(hdc, GetStockObject(NULL_BRUSH)); 
   for (L_UINT uZone = 0; uZone < uZones; uZone++) 
   { 
      L_OcrZone ocrZone = { 0 }; 
      ocrZone.StructSize = sizeof ocrZone; 
      L_OcrPage_GetZoneAt(ocrPage, uZone, &ocrZone); 
      int left = ocrZone.Bounds.left; 
      int top = ocrZone.Bounds.top; 
      int right = ocrZone.Bounds.right; 
      int bottom = ocrZone.Bounds.bottom; 
      TCHAR szZoneNo[32]; 
      wsprintf(szZoneNo, TEXT("Zone number %d"), uZone); 
      TextOut(hdc, left, top, szZoneNo, lstrlen(szZoneNo)); 
 
      Rectangle(hdc, left, top, right, bottom); 
   } 
   ReleaseDC(hWnd, hdc); 
   MessageBox(hWnd, TEXT("Zones drawn on window. Press OK to clear them"), TEXT("LEADTOOLS Demo"), MB_ICONINFORMATION); 
   InvalidateRect(hWnd, NULL, TRUE); 
} 
   break; 
   // Keep rest of the code as is 

Add the Code to Load and Save OCR Zones

In the WndProc function, under the switch (wmId) statement, add the two new cases and their code shown below. This code will allow the user to load and save OCR zones.

switch (wmId) 
{ 
case ID_ZONES_LOADZONES: 
{ 
   if (!ocrPage) 
   { 
      MessageBox(hWnd, TEXT("Cannot load OCR zones; no page added"), TEXT("LEADTOOLS Demo"), MB_ICONERROR); 
      break; 
   } 
   TCHAR szZoneFileName[260] = TEXT(""); // file name 
   if (SUCCESS != GetZoneLoadingName(hWnd, szZoneFileName, sizeof(szZoneFileName))) 
      break; 
   L_OcrPage_LoadZonesFile(ocrPage, szZoneFileName, 1); 
} 
   break; 
case ID_ZONES_SAVEZONES: 
{ 
   if (!ocrPage) 
   { 
      MessageBox(hWnd, TEXT("Cannot save OCR zones; no page added"), TEXT("LEADTOOLS Demo"), MB_ICONERROR); 
      break; 
   } 
   TCHAR szZoneFileName[260] = TEXT(""); // file name 
   if (SUCCESS != GetZoneSavingName(hWnd, szZoneFileName, sizeof(szZoneFileName))) 
      break; 
   L_OcrPage_SaveZonesFile(ocrPage, szZoneFileName, 1, NULL); 
} 
   break; 
   // Keep rest of the code as is 

Create two new functions, named GetZoneSavingName(HWND hwnd, TCHAR* pszFileName, DWORD nLen) and GetZoneLoadingName(HWND hwnd, TCHAR* pszFileName, DWORD nLen), and place them above the WndProc function. Add the code below to get a valid zone file name for loading and saving OCR zones.

L_INT GetZoneSavingName(HWND hwnd, TCHAR* pszFileName, DWORD nLen) 
{ 
   OPENFILENAME OpenFileName = { 0 }; 
   OpenFileName.lStructSize = sizeof(OPENFILENAME); 
   OpenFileName.hwndOwner = hwnd; 
   OpenFileName.lpstrFilter = TEXT("Zone files (*.ozf)\0*.ozf\0All\0*.*\0"); 
   OpenFileName.lpstrFile = pszFileName; 
   OpenFileName.nMaxFile = nLen; 
   OpenFileName.lpstrFileTitle = NULL; 
   OpenFileName.lpstrDefExt = TEXT("ozf"); 
   OpenFileName.nMaxFileTitle = 0; 
   OpenFileName.lpstrInitialDir = NULL; 
   OpenFileName.Flags = OFN_OVERWRITEPROMPT; 
    
   // Show the File Save dialog box 
   if (!GetSaveFileName(&OpenFileName)) 
      return FAILURE; 
   return SUCCESS; 
} 
L_INT GetZoneLoadingName(HWND hwnd, TCHAR* pszFileName, DWORD nLen) 
{ 
   OPENFILENAME OpenFileName = { 0 }; 
   OpenFileName.lStructSize = sizeof(OpenFileName); 
   OpenFileName.hwndOwner = hwnd; 
   OpenFileName.lpstrFile = pszFileName; 
   OpenFileName.nMaxFile = nLen; 
   OpenFileName.lpstrFilter = TEXT("Zone files (*.ozf)\0*.ozf\0All\0*.*\0"); 
   OpenFileName.nFilterIndex = 1; 
   OpenFileName.lpstrFileTitle = NULL; 
   OpenFileName.nMaxFileTitle = 0; 
   OpenFileName.lpstrInitialDir = NULL; 
   OpenFileName.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; 
 
   // Show the File Open dialog box 
   if (!GetOpenFileName(&OpenFileName)) 
      return FAILURE; 
   return SUCCESS; 
} 

Run the Project

Run the project by pressing F5, or by selecting Debug -> Start Debugging.

If the steps were followed correctly, the application should run. To test, follow the instructions below.

  1. Click File -> Open, and select the image you would like to load in the viewer.

  2. Click Zones -> Display Zones, to paint the zones gathered from the L_OcrPage_AutoZone(ocrPage, NULL, NULL); function, or from loading an OZF file.

  3. Click Zones -> Load Zones, and select the OZF file containing the OCR zones you wish to load.

  4. Click Zones -> Save Zones, to save the current OCR zones to OZF file.

    Screenshot of the window display with image and zones displayed.

Wrap-up

This tutorial shows how to load and save OCR zones and how to display their locations on screen. We also covered how to use the L_OcrPage and L_OcrZone structs.

See Also

Help Version 22.0.2021.10.18
Products | Support | Contact Us | Intellectual Property Notices
© 1991-2021 LEAD Technologies, Inc. All Rights Reserved.

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