Extracting Data from pdf417 such as Drivers License
Please see below link and generate the parser to extract the information of driver License.
http://www.dol.wa.gov/external/docs/barcodeCalibration-EDLEID.pdf
I have make this decoder for ios app
here the code :
NSString *message=barcode.barcodeString;
NSMutableArray *arrFixedData=[[NSMutableArray alloc]initWithObjects:@"DCS",@"DCT",@"DCU",@"DAG",@"DAI",@"DAJ",@"DAK",@"DCG",@"DAQ",@"DCA",@"DCB",@"DCD",@"DCF",@"DCH",@"DBA",@"DBB",@"DBC",@"DBD",@"DAU",@"DCE",@"DAY",@"ZWA",@"ZWB",@"ZWC",@"ZWD",@"ZWE",@"ZWF", nil];
NSMutableArray *arrDriverData=[[NSMutableArray alloc]initWithObjects:@"Customer Family Name",@"Customer Given Name",@"Name Suffix",@"Street Address 1",@"City",@"Jurisdction Code",@"Postal Code",@"Country Identification",@"Customer Id Number",@"Class",@"Restrictions",@"Endorsements",@"Document Discriminator",@"Vehicle Code",@"Expiration Date",@"Date Of Birth",@"Sex",@"Issue Date",@"Height",@"Weight",@"Eye Color",@"Control Number",@"Endorsements",@"Transaction Types",@"Under 18 Until",@"Under 21 Until",@"Revision Date", nil];
NSMutableDictionary *dict=[[NSMutableDictionary alloc]init];
for (int i=0; i<[arrFixedData count]; i++)
{
NSRange range = [message rangeOfString: [arrFixedData objectAtIndex:i] options: NSCaseInsensitiveSearch];
NSLog(@"found: %@", (range.location != NSNotFound) ? @"Yes" : @"No");
if (range.location != NSNotFound)
{
NSString *temp=[message substringFromIndex:range.location+range.length];
NSRange end = [temp rangeOfString:@"\n"];
if (end.location != NSNotFound)
{
temp = [temp substringToIndex:end.location];
temp =[temp stringByReplacingOccurrencesOfString:@"\n" withString:@""];
temp=[temp stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
NSLog(@"temp data : %@",temp);
[dict setObject:temp forKey:[arrDriverData objectAtIndex:i]];
}
}
NSLog(@"Dictionary : %@",dict);
The barcodestring contains the data which are scanned from pdf 417.
Thanks
Here's the Decoder for Android
Here, The Parameter "data" contains the string which you have to scanned pdf417.
==========Properties=============
HashMap<String, String> myData = new HashMap<String, String>();
public final String Customer_Family_Name = "DCS", Customer_Given_Name = "DCT", Name_Suffix = "DCU",
Street_Address_1 = "DAG", City = "DAI", Jurisdction_Code = "DAJ", Postal_Code = "DAK",
Country_Identification = "DCG", Customer_Id_Number = "DAQ", Class = "DCA", Restrictions = "DCB",
Endorsements = "DCD", Document_Discriminator = "DCF", Vehicle_Code = "DCH", Expiration_Date = "DBA",
Date_Of_Birth = "DBB", Sex = "DBC", Issue_Date = "DBD", Height = "DAU", Weight = "DCE", Eye_Color = "DAY",
Control_Number = "ZWA", WA_SPECIFIC_ENDORSMENT = "ZWB", Transaction_Types = "ZWC", Under_18_Until = "ZWD",
Under_21_Until = "ZWE", Revision_Date = "ZWF", Customer_Full_Name = "DAA", Customer_First_Name = "DAC",
Customer_Middle_Name = "DAD", Street_Address_2 = "DAH", Street_Address_1_optional = "DAL",
Street_Address_2_optional = "DAM";
ArrayList<String> allKeys = new ArrayList<String>();
============Methods after Scaning================
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (requestCode == SCAN_REQUEST_CODE && resultCode == Activity.RESULT_OK)
{
ArrayList<BarcodeResult> barcodes = data.getParcelableArrayListExtra(BarcodeScanActivity.RESULT_EXTRA);
Log.e("BARCODE RESULT ", "<<<>>" + barcodes.toString());
String barcodeResult = barcodes.get(0).barcodeString;
String lines[] = barcodeResult.split("\\r?\\n");
for (int i = 0; i < lines.length; i++)
{
String str = lines[i];
if (str.contains("ANSI"))
{
str = str.substring(str.indexOf("DL"));
String str1[] = str.split("DL");
if (str1.length > 1)
{
str = str1[str1.length - 1];
}
}
if (str.length() > 3)
{
String key = str.substring(0, 3);
String value = str.substring(3);
if (allKeys.contains(key))
{
if (!value.equalsIgnoreCase("None"))
{
myData.put(allKeys.get(allKeys.indexOf(key)), value);
}
}
}
Log.e("RESULT ", "<<>>" + lines[i]);
}
Log.e("TAG", "SO MAY BE FINAL RESULT");
if (myData.containsKey(Customer_Family_Name))
{
Log.v("TAG", "users family name:" + myData.get(Customer_Family_Name));
lname = myData.get(Customer_Family_Name).trim();
}
if (myData.containsKey(Customer_Given_Name))
{
Log.v("TAG", "users Given name:" + myData.get(Customer_Given_Name));
try
{
String CustomerName[] = myData.get(Customer_Given_Name).split(" ");
fname = CustomerName[0].trim();
mname = CustomerName[1].substring(0, 1).trim();
}
catch (Exception e)
{
e.printStackTrace();
}
}
if (myData.containsKey(Name_Suffix))
{
Log.v("TAG", "Surname name:" + myData.get(Name_Suffix));
}
if (myData.containsKey(Street_Address_1))
{
Log.v("TAG", "Address line 1 :" + myData.get(Street_Address_1));
try
{
address = myData.get(Street_Address_1).trim();
}
catch (Exception e)
{
e.printStackTrace();
}
}
if (TextUtils.isEmpty(address))
{
if (myData.containsKey(Street_Address_2))
{
address = myData.get(Street_Address_2).trim();
}
if (TextUtils.isEmpty(address))
{
if (myData.containsKey(Street_Address_1_optional))
{
address = myData.get(Street_Address_1_optional).trim();
}
}
if (TextUtils.isEmpty(address))
{
if (myData.containsKey(Street_Address_2_optional))
{
address = myData.get(Street_Address_2_optional).trim();
}
}
}
if (myData.containsKey(City))
{
Log.v("TAG", "City:" + myData.get(City));
city = myData.get(City).trim();
}
if (myData.containsKey(Jurisdction_Code))
{
Log.v("TAG", "State:" + myData.get(Jurisdction_Code));
State = myData.get(Jurisdction_Code).trim();
}
if (myData.containsKey(Postal_Code))
{
Log.v("TAG", "Pin Code:" + myData.get(Postal_Code));
zipcode = myData.get(Postal_Code).substring(0, 5).trim();
}
if (myData.containsKey(Date_Of_Birth))
{
Log.v("TAG", "Birth Date :" + myData.get(Date_Of_Birth));
birthday = myData.get(Date_Of_Birth).substring(0, 2) + "/" + myData.get(Date_Of_Birth).substring(2, 4)
+ "/" + myData.get(Date_Of_Birth).substring(4);
if (isThisDateValid(birthday, "MM/dd/yyyy", myData.get(Date_Of_Birth)))
Log.e("TAG", "IS VALID");
else
Log.e("TAG", "IS NOT VALID");
}
if (myData.containsKey(Sex))
{
Log.v("TAG", "Sex:" + (myData.get(Sex).toString().trim().equals("1") ? "Male" : "Female"));
}
if (myData.containsKey(Customer_Full_Name))
{
String cName = myData.get(Customer_Full_Name);
int startIndexOfComma = 0;
int endIndexOfComma = 0;
startIndexOfComma = cName.indexOf(",");
endIndexOfComma = cName.lastIndexOf(",");
if (startIndexOfComma != endIndexOfComma)
{
String CustomerName[] = myData.get(Customer_Full_Name).split(",");
lname = CustomerName[0].replace(",", "").trim();
fname = CustomerName[1].trim();
mname = CustomerName[2].substring(0, 1).trim();
}
else
{
String CustomerName[] = myData.get(Customer_Full_Name).split(" ");
lname = CustomerName[0].replace(",", "").trim();
fname = CustomerName[1].trim();
mname = CustomerName[2].substring(0, 1).trim();
}
}
if (myData.containsKey(Customer_First_Name))
{
fname = myData.get(Customer_First_Name).trim();
}
if (myData.containsKey(Customer_Middle_Name))
{
mname = myData.get(Customer_Middle_Name).substring(0, 1).trim();
}
// TODO edit here at 7/3/2014
if (myData.containsKey(Customer_Id_Number))
{
licence_number = myData.get(Customer_Id_Number).trim();
Log.e("TAG", "Licence Number is :" + licence_number);
}
if (myData.containsKey(Expiration_Date))
{
licence_expire_date = myData.get(Expiration_Date).trim();
licence_expire_date = myData.get(Expiration_Date).substring(0, 2) + "/"
+ myData.get(Expiration_Date).substring(2, 4) + "/" + myData.get(Expiration_Date).substring(4);
licence_expire_date = makeDateValid(licence_expire_date, "MM/dd/yyyy", myData.get(Expiration_Date));
Log.e("TAG", "expire date is :" + licence_expire_date);
}
etFirstName.setText(fname.trim());
etMiddleName.setText(mname.trim());
etLastName.setText(lname.trim());
etAddress.setText(address.trim());
etZipCode.setText(zipcode.trim());
etCity.setText(city.trim());
etState.setText(State.trim());
etDLNumber.setText(licence_number);
etDLExpirationDate.setText(licence_expire_date);
etBirthDay.setText(birthday.trim());
}
}
Here's the code I use to decode the PDF417
data in Swift
.
private let pdf417Map: [String: String] = [
"DAA":"Full Name",
"DAB":"Family Name",
"DAC":"Given Name",
"DAD":"Middle Name",
"DAE":"Name Suffix",
"DAF":"Name Prefix",
"DAG":"Mailing Street Address1",
"DAH":"Mailing Street Address2",
"DAI":"Mailing City",
"DAJ":"Mailing Jurisdiction Code",
"DAK":"Mailing Postal Code",
"DAL":"Residence Street Address1",
"DAM":"Residence Street Address2",
"DAN":"Residence City",
"DAO":"Residence Jurisdiction Code",
"DAP":"Residence Postal Code",
"DAQ":"License or ID Number",
"DAR":"License Classification Code",
"DAS":"License Restriction Code",
"DAT":"License Endorsements Code",
"DAU":"Height in FT_IN",
"DAV":"Height in CM",
"DAW":"Weight in LBS",
"DAX":"Weight in KG",
"DAY":"Eye Color",
"DAZ":"Hair Color",
"DBA":"License Expiration Date",
"DBB":"Date of Birth",
"DBC":"Sex",
"DBD":"License or ID Document Issue Date",
"DBE":"Issue Timestamp",
"DBF":"Number of Duplicates",
"DBG":"Medical Indicator Codes",
"DBH":"Organ Donor",
"DBI":"Non-Resident Indicator",
"DBJ":"Unique Customer Identifier",
"DBK":"Social Security Number",
"DBL":"Date Of Birth",
"DBM":"Social Security Number",
"DBN":"Full Name",
"DBO":"Family Name",
"DBP":"Given Name",
"DBQ":"Middle Name or Initial",
"DBR":"Suffix",
"DBS":"Prefix",
"DCA":"Virginia Specific Class",
"DCB":"Virginia Specific Restrictions",
"DCD":"Virginia Specific Endorsements",
"DCE":"Physical Description Weight Range",
"DCF":"Document Discriminator",
"DCG":"Country territory of issuance",
"DCH":"Federal Commercial Vehicle Codes",
"DCI":"Place of birth",
"DCJ":"Audit information",
"DCK":"Inventory Control Number",
"DCL":"Race Ethnicity",
"DCM":"Standard vehicle classification",
"DCN":"Standard endorsement code",
"DCO":"Standard restriction code",
"DCP":"Jurisdiction specific vehicle classification description",
"DCQ":"Jurisdiction-specific",
"DCR":"Jurisdiction specific restriction code description",
"DCS":"Last Name",
"DCT":"First Name",
"DCU":"Suffix",
"DDA":"Compliance Type",
"DDB":"Card Revision Date",
"DDC":"HazMat Endorsement Expiry Date",
"DDD":"Limited Duration Document Indicator",
"DDE":"Family Name Truncation",
"DDF":"First Names Truncation",
"DDG":"Middle Names Truncation",
"DDH":"Under 18 Until",
"DDI":"Under 19 Until",
"DDJ":"Under 21 Until",
"DDK":"Organ Donor Indicator",
"DDL":"Veteran Indicator",
"PAA":"Permit Classification Code",
"PAB":"Permit Expiration Date",
"PAC":"Permit Identifier",
"PAD":"Permit IssueDate",
"PAE":"Permit Restriction Code",
"PAF":"Permit Endorsement Code",
"ZVA":"Court Restriction Code"
]
// metadataObj = @ ANSI 63601404....
if metadataObj.stringValue != nil {
let licenseData = metadataObj.stringValue!.components(separatedBy: "\n")
var customerProfile: [[String: String]] = []
for item in licenseData {
var metaDataItem = item
if metaDataItem.count > 3 {
if let dlCodeRange = metaDataItem.range(of: "DAQ") {
let dlStart = dlCodeRange.lowerBound
let dlEnd = metaDataItem.index(metaDataItem.endIndex, offsetBy: 0)
let dlNoRange = dlStart..<dlEnd
metaDataItem = String(metaDataItem[dlNoRange])
}
// Get the 3 letter code
let pdf417Code = String(metaDataItem.prefix(3))
// See if the code exists in the map
if pdf417Map[pdf417Code] != nil {
// Code exists in map, save to profile
let start = metaDataItem.index(metaDataItem.startIndex, offsetBy: 3)
let end = metaDataItem.index(metaDataItem.endIndex, offsetBy: 0)
let range = start..<end
let extractedData = metaDataItem[range]
customerProfile.append([pdf417Map[pdf417Code]!: String(extractedData)])
}
}
}
print("customerProfile: \(customerProfile)")
}