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, 2022 |
Development License | Download LEADTOOLS |
Try it in another language |
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.
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:\LEADTOOLS23\Include\ltocr.h"
#pragma comment (lib, "C:\\LEADTOOLS23\\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.
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.
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
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, ARRAYSIZE(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, ARRAYSIZE(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 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.
Click File -> Open, and select the image you would like to load in the viewer.
Click Zones -> Display Zones, to paint the zones gathered from the L_OcrPage_AutoZone(ocrPage, NULL, NULL);
function, or from loading an OZF file.
Click Zones -> Load Zones, and select the OZF file containing the OCR zones you wish to load.
Click Zones -> Save Zones, to save the current OCR zones to OZF file.
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.