tessl install tessl/github-zxing-cpp--zxing-cpp@2.3.0Open-source, multi-format linear/matrix barcode image processing library implemented in C++
This document provides practical examples for common ZXing-C++ use cases.
#include "ZXing/ReadBarcode.h"
class POSScanner {
ZXing::ReaderOptions options;
public:
POSScanner() {
// Configure for retail formats
options.setFormats(
ZXing::BarcodeFormat::EAN13 |
ZXing::BarcodeFormat::EAN8 |
ZXing::BarcodeFormat::UPCA |
ZXing::BarcodeFormat::UPCE
);
options.setTryHarder(true);
options.setTryRotate(false); // Products usually upright
}
std::optional<std::string> scanProduct(const ZXing::ImageView& image) {
auto barcode = ZXing::ReadBarcode(image, options);
if (!barcode.isValid()) {
return std::nullopt;
}
// Validate check digit
if (!ZXing::GTIN::IsCheckDigitValid(barcode.text())) {
logWarning("Invalid check digit");
return std::nullopt;
}
return barcode.text();
}
};auto options = ZXing::ReaderOptions()
.setFormats(ZXing::BarcodeFormat::EAN13)
.setEanAddOnSymbol(ZXing::EanAddOnSymbol::Read);
auto barcode = ZXing::ReadBarcode(image, options);
if (barcode.isValid()) {
std::string mainCode = barcode.text();
std::string addOn = ZXing::GTIN::EanAddOn(barcode);
if (!addOn.empty()) {
if (addOn.length() == 2) {
// Magazine issue number
std::string issue = ZXing::GTIN::IssueNr(addOn);
std::cout << "Issue: " << issue << "\n";
} else if (addOn.length() == 5) {
// Book price
std::string price = ZXing::GTIN::Price(addOn);
std::cout << "Price: " << price << "\n";
}
}
}#include <vector>
#include <string>
class WarehouseScanner {
public:
struct ScanResult {
std::string code;
ZXing::BarcodeFormat format;
ZXing::Position position;
std::chrono::system_clock::time_point timestamp;
};
std::vector<ScanResult> scanPallet(const ZXing::ImageView& image) {
auto options = ZXing::ReaderOptions()
.setFormats(ZXing::BarcodeFormat::Code128 |
ZXing::BarcodeFormat::DataMatrix)
.setMaxNumberOfSymbols(20)
.setTryHarder(true);
auto barcodes = ZXing::ReadBarcodes(image, options);
std::vector<ScanResult> results;
for (const auto& bc : barcodes) {
if (bc.isValid()) {
results.push_back({
bc.text(),
bc.format(),
bc.position(),
std::chrono::system_clock::now()
});
}
}
return results;
}
};class PackageTracker {
std::map<std::string, std::vector<std::string>> packageHistory;
public:
void scanPackage(const ZXing::ImageView& image,
const std::string& location) {
auto options = ZXing::ReaderOptions()
.setFormats(ZXing::BarcodeFormat::Code128);
auto barcode = ZXing::ReadBarcode(image, options);
if (barcode.isValid()) {
std::string trackingNumber = barcode.text();
packageHistory[trackingNumber].push_back(location);
// Log to database
logPackageMovement(trackingNumber, location);
}
}
std::vector<std::string> getPackageHistory(const std::string& trackingNumber) {
return packageHistory[trackingNumber];
}
};struct DriverLicense {
std::string name;
std::string licenseNumber;
std::string dateOfBirth;
std::string expirationDate;
std::string address;
};
std::optional<DriverLicense> scanDriverLicense(const ZXing::ImageView& image) {
auto options = ZXing::ReaderOptions()
.setFormats(ZXing::BarcodeFormat::PDF417)
.setTryHarder(true);
auto barcode = ZXing::ReadBarcode(image, options);
if (!barcode.isValid()) {
return std::nullopt;
}
// Parse AAMVA format
std::string data = barcode.text();
DriverLicense license;
// Parse fields (simplified example)
size_t pos = 0;
while ((pos = data.find("DAA", pos)) != std::string::npos) {
license.name = data.substr(pos + 3, data.find('\n', pos) - pos - 3);
break;
}
// Parse other fields...
return license;
}class DocumentScanner {
std::map<std::string, std::vector<ZXing::Barcode>> documents;
public:
void scanPage(const ZXing::ImageView& image, int pageNumber) {
auto options = ZXing::ReaderOptions()
.setFormats(ZXing::BarcodeFormat::QRCode |
ZXing::BarcodeFormat::DataMatrix)
.setMaxNumberOfSymbols(10);
auto barcodes = ZXing::ReadBarcodes(image, options);
for (const auto& bc : barcodes) {
if (bc.isValid() && bc.isPartOfSequence()) {
std::string docId = bc.sequenceId();
documents[docId].push_back(bc);
// Check if document is complete
if (isDocumentComplete(docId)) {
processCompleteDocument(docId);
}
}
}
}
private:
bool isDocumentComplete(const std::string& docId) {
const auto& pages = documents[docId];
if (pages.empty()) return false;
int expectedPages = pages[0].sequenceSize();
return pages.size() == expectedPages;
}
void processCompleteDocument(const std::string& docId) {
auto merged = ZXing::MergeStructuredAppendSequence(documents[docId]);
if (merged.isValid()) {
std::cout << "Document complete: " << merged.text() << "\n";
documents.erase(docId);
}
}
};struct BusinessCard {
std::string name;
std::string company;
std::string email;
std::string phone;
std::string website;
};
std::optional<BusinessCard> scanBusinessCard(const ZXing::ImageView& image) {
auto options = ZXing::ReaderOptions()
.setFormats(ZXing::BarcodeFormat::QRCode);
auto barcode = ZXing::ReadBarcode(image, options);
if (!barcode.isValid()) {
return std::nullopt;
}
std::string vcard = barcode.text();
// Parse vCard format
BusinessCard card;
auto extractField = [&](const std::string& field) -> std::string {
size_t pos = vcard.find(field);
if (pos == std::string::npos) return "";
size_t start = vcard.find(':', pos) + 1;
size_t end = vcard.find('\n', start);
return vcard.substr(start, end - start);
};
card.name = extractField("FN:");
card.company = extractField("ORG:");
card.email = extractField("EMAIL:");
card.phone = extractField("TEL:");
card.website = extractField("URL:");
return card;
}struct WiFiCredentials {
std::string ssid;
std::string password;
std::string encryption; // WPA, WEP, nopass
};
std::optional<WiFiCredentials> scanWiFiQR(const ZXing::ImageView& image) {
auto barcode = ZXing::ReadBarcode(image);
if (!barcode.isValid()) {
return std::nullopt;
}
std::string text = barcode.text();
// WiFi QR format: WIFI:T:WPA;S:SSID;P:password;;
if (text.substr(0, 5) != "WIFI:") {
return std::nullopt;
}
WiFiCredentials creds;
auto extractParam = [&](const std::string& param) -> std::string {
size_t pos = text.find(param + ":");
if (pos == std::string::npos) return "";
size_t start = pos + param.length() + 1;
size_t end = text.find(';', start);
return text.substr(start, end - start);
};
creds.encryption = extractParam("T");
creds.ssid = extractParam("S");
creds.password = extractParam("P");
return creds;
}class PartTracker {
public:
struct PartInfo {
std::string partNumber;
std::string serialNumber;
std::string lotNumber;
std::string manufactureDate;
};
std::optional<PartInfo> scanPart(const ZXing::ImageView& image) {
auto options = ZXing::ReaderOptions()
.setFormats(ZXing::BarcodeFormat::DataMatrix)
.setTryHarder(true)
.setTryInvert(true); // Parts may have inverted codes
auto barcode = ZXing::ReadBarcode(image, options);
if (!barcode.isValid()) {
return std::nullopt;
}
// Parse GS1 format
if (barcode.contentType() == ZXing::ContentType::GS1) {
return parseGS1Data(barcode.text());
}
return std::nullopt;
}
private:
std::optional<PartInfo> parseGS1Data(const std::string& data) {
PartInfo info;
// Parse GS1 Application Identifiers
// (01) = GTIN, (10) = Batch/Lot, (17) = Expiry, (21) = Serial
size_t pos = 0;
while (pos < data.length()) {
if (data.substr(pos, 3) == "(01)") {
info.partNumber = extractGS1Field(data, pos + 3, 14);
} else if (data.substr(pos, 3) == "(10)") {
info.lotNumber = extractGS1Field(data, pos + 3);
} else if (data.substr(pos, 3) == "(17)") {
info.manufactureDate = extractGS1Field(data, pos + 3, 6);
} else if (data.substr(pos, 3) == "(21)") {
info.serialNumber = extractGS1Field(data, pos + 3);
}
pos = data.find('(', pos + 1);
if (pos == std::string::npos) break;
}
return info;
}
std::string extractGS1Field(const std::string& data, size_t start,
int fixedLength = -1) {
if (fixedLength > 0) {
return data.substr(start, fixedLength);
}
size_t end = data.find('(', start);
if (end == std::string::npos) end = data.length();
return data.substr(start, end - start);
}
};class MedicationScanner {
public:
struct MedicationInfo {
std::string ndc; // National Drug Code
std::string lotNumber;
std::string expirationDate;
std::string serialNumber;
};
std::optional<MedicationInfo> scanMedication(const ZXing::ImageView& image) {
auto options = ZXing::ReaderOptions()
.setFormats(ZXing::BarcodeFormat::DataMatrix |
ZXing::BarcodeFormat::QRCode)
.setTryHarder(true);
auto barcode = ZXing::ReadBarcode(image, options);
if (!barcode.isValid()) {
return std::nullopt;
}
// Parse GS1 DataBar or 2D barcode
return parseGS1Healthcare(barcode.text());
}
bool verifyMedication(const MedicationInfo& info) {
// Check expiration
if (isExpired(info.expirationDate)) {
return false;
}
// Verify against database
return checkDatabase(info.ndc, info.serialNumber);
}
private:
std::optional<MedicationInfo> parseGS1Healthcare(const std::string& data) {
MedicationInfo info;
// Parse GS1 format
// (01) = GTIN/NDC, (10) = Lot, (17) = Expiry, (21) = Serial
// Implementation similar to part tracking example
return info;
}
bool isExpired(const std::string& expiryDate) {
// Parse YYMMDD format and compare with current date
// Implementation details...
return false;
}
bool checkDatabase(const std::string& ndc, const std::string& serial) {
// Verify against pharmaceutical database
// Implementation details...
return true;
}
};class TicketValidator {
std::set<std::string> usedTickets;
public:
enum class ValidationResult {
Valid,
AlreadyUsed,
Invalid,
Expired
};
ValidationResult validateTicket(const ZXing::ImageView& image) {
auto options = ZXing::ReaderOptions()
.setFormats(ZXing::BarcodeFormat::QRCode |
ZXing::BarcodeFormat::Aztec)
.setTryHarder(true);
auto barcode = ZXing::ReadBarcode(image, options);
if (!barcode.isValid()) {
return ValidationResult::Invalid;
}
std::string ticketId = barcode.text();
// Check if already used
if (usedTickets.count(ticketId)) {
return ValidationResult::AlreadyUsed;
}
// Verify ticket validity (check signature, expiration, etc.)
if (!verifyTicketSignature(ticketId)) {
return ValidationResult::Invalid;
}
if (isTicketExpired(ticketId)) {
return ValidationResult::Expired;
}
// Mark as used
usedTickets.insert(ticketId);
return ValidationResult::Valid;
}
private:
bool verifyTicketSignature(const std::string& ticketId) {
// Verify cryptographic signature
// Implementation details...
return true;
}
bool isTicketExpired(const std::string& ticketId) {
// Check ticket expiration
// Implementation details...
return false;
}
};class InventoryScanner {
public:
struct InventoryItem {
std::string sku;
int quantity;
std::string location;
std::chrono::system_clock::time_point scannedAt;
};
std::vector<InventoryItem> scanShelf(const ZXing::ImageView& image,
const std::string& location) {
auto options = ZXing::ReaderOptions()
.setFormats(ZXing::BarcodeFormat::Any)
.setMaxNumberOfSymbols(50)
.setTryHarder(true);
auto barcodes = ZXing::ReadBarcodes(image, options);
std::map<std::string, int> itemCounts;
for (const auto& bc : barcodes) {
if (bc.isValid()) {
itemCounts[bc.text()]++;
}
}
std::vector<InventoryItem> items;
auto now = std::chrono::system_clock::now();
for (const auto& [sku, count] : itemCounts) {
items.push_back({sku, count, location, now});
}
return items;
}
void exportToCSV(const std::vector<InventoryItem>& items,
const std::string& filename) {
std::ofstream file(filename);
file << "SKU,Quantity,Location,Timestamp\n";
for (const auto& item : items) {
auto time_t = std::chrono::system_clock::to_time_t(item.scannedAt);
file << item.sku << ","
<< item.quantity << ","
<< item.location << ","
<< std::ctime(&time_t);
}
}
};auto barcode = ZXing::ReadBarcode(image);
if (barcode.isValid()) {
// Additional validation
if (barcode.format() == ZXing::BarcodeFormat::EAN13) {
if (!ZXing::GTIN::IsCheckDigitValid(barcode.text())) {
// Reject invalid check digit
return;
}
}
// Process valid barcode
processBarcode(barcode.text());
}struct ScanLog {
std::chrono::system_clock::time_point timestamp;
bool success;
std::string errorMessage;
ZXing::BarcodeFormat format;
std::string content;
};
std::vector<ScanLog> scanHistory;
void logScan(const ZXing::Barcode& barcode) {
ScanLog log;
log.timestamp = std::chrono::system_clock::now();
log.success = barcode.isValid();
if (barcode.isValid()) {
log.format = barcode.format();
log.content = barcode.text();
} else {
log.errorMessage = barcode.error().msg();
}
scanHistory.push_back(log);
}class RobustScanner {
std::queue<std::string> offlineQueue;
public:
void scanAndUpload(const ZXing::ImageView& image) {
auto barcode = ZXing::ReadBarcode(image);
if (barcode.isValid()) {
if (isOnline()) {
uploadToServer(barcode.text());
} else {
// Queue for later
offlineQueue.push(barcode.text());
saveToLocalStorage(barcode.text());
}
}
}
void syncOfflineScans() {
while (!offlineQueue.empty() && isOnline()) {
uploadToServer(offlineQueue.front());
offlineQueue.pop();
}
}
};