This tutorial shows how to extract information from a PDF417 barcode that follows the AAMVA specification using the LEADTOOLS SDK in a Windows C/C++ API Application.
Overview | |
---|---|
Summary | This tutorial covers how to use LEADTOOLS AAMVA PDF417 SDK technology 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 |
|
Before working on the Extract Driver's License AAMVA Barcode - Windows C DLL tutorial, get familiar with the basic steps of creating a project and loading/displaying an image by reviewing the Add References and Set a License and Load, Display and Save Images tutorials.
Start with a copy of the 64-bit Windows API project created in the Load, Display and Save Images tutorial. If the project is not available, create it by following the steps in that tutorial.
To read barcodes and extract AAMVA data using LEADTOOLS, add the required header and DLL files. Open the pre-compiled header file (either pch.h
or stdafx.h
, depending on the version of Visual Studio used) and add the following lines:
#include "C:\LEADTOOLS21\Include\Ltbar.h"
#pragma comment (lib, "C:\\LEADTOOLS21\\Lib\\CDLL\\x64\\Ltbar_x.lib") // barcode and AAMVA support
Note
For a full list of which DLLs are required for specific toolkit features or file formats, refer to Files to be Included With Your Application.
For details on needed Barcode DLLs, see the help topic Barcode Files to be Included With Your Application.
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 and display image code added, coding can begin.
The steps below are for Visual Studio 2019; they could be different for other versions of Visual Studio.
Go to the Solution Explorer and double-click the resources file (.rc).
Add a new &Barcode drop down menu next to the File menu. In the newly added &Barcode menu, add a &Extract PDF417 Data menu item. The new item's ID should be ID_BARCODE_EXTRACTPDF417DATA
.
Go to the WndProc
function and under the switch (wmId)
statement that is below the WM_COMMAND
case, add a new case:
switch (wmId)
{
case ID_BARCODE_EXTRACTPDF417DATA:
if (LEADBmp.Flags.Allocated)
ExtractPDF417Data(hWnd);
else
MessageBox(hWnd, TEXT("Cannot search for AAMVA data. No image loaded"), TEXT("Barcode Demo"), MB_ICONERROR);
break;
// keep rest of the code as is
Add a new ExtractPDF417Data
function. You can place this function above the WndProc
function, and add the following code:
void ExtractPDF417Data(HWND hwnd)
{
if (L_BarCodeInit(BARCODES_PDF_READ) != SUCCESS)
return;
pBARCODEDATA pBarCodes = NULL;
BARCODEREADPDF BarPdf = { 0 };
BarPdf.uStructSize = sizeof BARCODEREADPDF;
BarPdf.nDirection = BARCODE_DIR_HORIZONTAL;
BARCODECOLOR BarColor = { 0 };
BarColor.uStructSize = sizeof BARCODECOLOR;
BarColor.dwColorBar = RGB(0, 0, 0);
BarColor.dwColorSpace = RGB(255, 255, 255);
// Search for PDF417 barcodes in the entire bitmap
L_INT nRet = L_BarCodeRead(&LEADBmp, NULL, BARCODE_PDF417, BARCODE_SCANLINES_PER_PIXELS, BARCODE_BLOCK_SEARCH, 0, NULL, &BarPdf, &BarColor, &pBarCodes, sizeof BARCODEDATA);
if (SUCCESS == nRet)
{
if(ParseAAMVAData(hwnd, pBarCodes) != SUCCESS)
MessageBox(hwnd, TEXT("ParseAAMVAData returned an error"), TEXT("Barcode Demo"), MB_ICONERROR);
}
else
MessageBox(hwnd, TEXT("Could not read PDF 417 Barcodes"), TEXT("Barcode Demo"), MB_ICONERROR);
if (pBarCodes)
L_BarCodeFree(&pBarCodes);
L_BarCodeExit();
}
Add a new ParseAAMVAData
function that is called from within ExtractPDF417Data()
. Add the below code to parse the AAMVA data from the PDF417 barcode:
L_INT ParseAAMVAData(HWND hwnd, pBARCODEDATA pBarCodeData)
{
if (!pBarCodeData)
return FAILURE;
AAMVAID id = { 0 };
// Parse Barcode AAMVA data
L_INT nRet = L_BarCodeParseAAMVAData(pBarCodeData->pszBarCodeData, pBarCodeData->nSizeofBarCodeData, &id, L_FALSE);
if (nRet != SUCCESS)
return nRet;
L_CHAR szResultString[1024] = "Issuer Identification Number: ";
strcat_s(szResultString, id.IssuerIdentificationNumber);
//First Name
L_BOOL bInferredFromFullName;
L_CHAR* pszFirstName = NULL;
nRet = L_BarCodeAAMVAIDFirstName(&id, &pszFirstName, &bInferredFromFullName);
if (nRet != SUCCESS)
return nRet;
strcat_s(szResultString, "\nFirst Name: ");
strcat_s(szResultString, pszFirstName);
//Must free result
L_BarCodeAAMVAMemoryFree(pszFirstName);
//Last Name
L_CHAR* pszLastName = NULL;
nRet = L_BarCodeAAMVAIDLastName(&id, &pszLastName, &bInferredFromFullName);
if (nRet != SUCCESS)
return nRet;
strcat_s(szResultString, "\nLast Name: ");
strcat_s(szResultString, pszLastName);
//Must free result
L_BarCodeAAMVAMemoryFree(pszLastName);
L_BOOL bRes;
//Check if we can determine if ID holder is Over 21
nRet = L_BarCodeAAMVAIDOver21Available(&id, &bRes);
if (nRet != SUCCESS)
return nRet;
strcat_s(szResultString, "\nOver 21?: ");
if (bRes)
{
//Over21 is available. Let's check if ID hold is 21+
L_CHAR* pszCurrentDate = GetCurrentDate();
nRet = L_BarCodeAAMVAIDOver21(&id, pszCurrentDate, &bRes);
if (nRet != SUCCESS)
return nRet;
if (bRes)
strcat_s(szResultString, "True");
else
strcat_s(szResultString, "False");
}
else //Over21 is NOT available.
strcat_s(szResultString, "Not Available");
MessageBoxA(hwnd, szResultString, "AAMVA data", MB_OK);
//Free the AAMVAID structure
nRet = L_BarCodeFreeAAMVAID(&id);
return nRet;
}
Add a new helper function namedGetCurrentDate
. Any function that returns the date in yyyymmdd format can be used instead of it.
#include <time.h>
L_CHAR* GetCurrentDate()
{
static char currentDate[9];
time_t t = time(NULL);
struct tm local_t = { 0 };
localtime_s(&local_t, &t);
wsprintfA(currentDate, "%4.4d%2.2d%2.2d", local_t.tm_year + 1900, local_t.tm_mon + 1, local_t.tm_mday);
return currentDate;
}
Note
There are more
AAMVAID
functions in the toolkit; the snippet above showcases a few commonly used values.
Run the project by pressing F5, or by selecting Debug -> Start Debugging.
If the steps were followed correctly, the application should run and enable the user to select File -> Open to load the image containing the barcode data. Select Barcode -> Extract PDF417 Data, to have the application run barcode recognition and parse the AAMVA data and display it in a message box.
Note
If there's no image with driver license barcode available for testing, it is possible to use the image at this file path:
C:\LEADTOOLS21\Resources\Images\license_sample_rear_aamva.png
This tutorial showed how to use the AAMVAID function.