Core barcode encoding/decoding library supporting 17 formats including QR Code, Data Matrix, Aztec, PDF 417, and various 1D barcodes
—
Real-world usage patterns and recipes for common barcode scenarios. These patterns demonstrate best practices for typical applications using ZXing Core.
Scenario: Continuous scanning from camera preview frames in a mobile app.
Requirements:
import com.google.zxing.*;
import com.google.zxing.common.*;
import java.util.*;
public class MobileBarcodeScanner {
private final MultiFormatReader reader;
private final Map<DecodeHintType, Object> hints;
private long lastScanTime = 0;
private static final long SCAN_THROTTLE_MS = 500;
public MobileBarcodeScanner() {
reader = new MultiFormatReader();
// Configure for mobile scanning
hints = new EnumMap<>(DecodeHintType.class);
hints.put(DecodeHintType.POSSIBLE_FORMATS, Arrays.asList(
BarcodeFormat.QR_CODE,
BarcodeFormat.EAN_13,
BarcodeFormat.EAN_8,
BarcodeFormat.CODE_128
));
hints.put(DecodeHintType.TRY_HARDER, Boolean.FALSE); // Speed over accuracy
hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
reader.setHints(hints);
}
public Result scanPreviewFrame(byte[] yuvData, int width, int height) {
// Throttle scanning
long now = System.currentTimeMillis();
if (now - lastScanTime < SCAN_THROTTLE_MS) {
return null;
}
try {
// Use YUV data directly (Android camera format)
LuminanceSource source = new PlanarYUVLuminanceSource(
yuvData, width, height,
0, 0, width, height,
false
);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
Result result = reader.decode(bitmap);
lastScanTime = now;
return result;
} catch (NotFoundException e) {
// No barcode in this frame - normal
return null;
} catch (ChecksumException | FormatException e) {
// Damaged or invalid barcode
return null;
}
}
public void reset() {
reader.reset();
}
}Key Points:
PlanarYUVLuminanceSource for camera data (fastest)TRY_HARDER for real-time scanningScenario: Generate QR codes for URLs, ensuring reliable scanning on various devices.
import com.google.zxing.*;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.*;
public class QRCodeGenerator {
public static BufferedImage generateQRCode(String url, int size)
throws WriterException {
// Configure for high reliability
Map<EncodeHintType, Object> hints = new EnumMap<>(EncodeHintType.class);
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
hints.put(EncodeHintType.MARGIN, 2); // Smaller margin for web
// Generate QR code
QRCodeWriter writer = new QRCodeWriter();
BitMatrix matrix = writer.encode(url, BarcodeFormat.QR_CODE,
size, size, hints);
// Convert to image with colors
BufferedImage image = new BufferedImage(size, size,
BufferedImage.TYPE_INT_RGB);
for (int y = 0; y < size; y++) {
for (int x = 0; x < size; x++) {
int color = matrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF;
image.setRGB(x, y, color);
}
}
return image;
}
public static void saveQRCode(String url, String filename, int size)
throws Exception {
BufferedImage image = generateQRCode(url, size);
ImageIO.write(image, "PNG", new File(filename));
}
// Example: Generate QR code for product page
public static void main(String[] args) throws Exception {
String productUrl = "https://example.com/products/item-12345";
saveQRCode(productUrl, "product-qr.png", 300);
System.out.println("QR code generated successfully!");
}
}Key Points:
Scenario: Process scanned documents containing multiple barcodes, extract all data.
import com.google.zxing.*;
import com.google.zxing.common.*;
import com.google.zxing.multi.*;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.*;
public class BatchDocumentProcessor {
public static class DocumentData {
public String filename;
public List<BarcodeData> barcodes = new ArrayList<>();
public boolean processingError = false;
public String errorMessage;
}
public static class BarcodeData {
public BarcodeFormat format;
public String text;
public int x, y; // Location
}
public static List<DocumentData> processDocuments(File[] documentFiles) {
List<DocumentData> results = new ArrayList<>();
MultipleBarcodeReader reader = createMultiReader();
for (File file : documentFiles) {
DocumentData doc = new DocumentData();
doc.filename = file.getName();
try {
BufferedImage image = ImageIO.read(file);
doc.barcodes = extractBarcodes(image, reader);
} catch (Exception e) {
doc.processingError = true;
doc.errorMessage = e.getMessage();
}
results.add(doc);
}
return results;
}
private static MultipleBarcodeReader createMultiReader() {
MultiFormatReader delegate = new MultiFormatReader();
Map<DecodeHintType, Object> hints = new EnumMap<>(DecodeHintType.class);
hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
hints.put(DecodeHintType.POSSIBLE_FORMATS, Arrays.asList(
BarcodeFormat.CODE_128,
BarcodeFormat.QR_CODE,
BarcodeFormat.DATA_MATRIX,
BarcodeFormat.EAN_13
));
delegate.setHints(hints);
return new GenericMultipleBarcodeReader(delegate);
}
private static List<BarcodeData> extractBarcodes(
BufferedImage image, MultipleBarcodeReader reader)
throws NotFoundException {
List<BarcodeData> barcodes = new ArrayList<>();
// Convert to binary bitmap
int width = image.getWidth();
int height = image.getHeight();
int[] pixels = image.getRGB(0, 0, width, height, null, 0, width);
LuminanceSource source = new RGBLuminanceSource(width, height, pixels);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
// Decode all barcodes
Result[] results = reader.decodeMultiple(bitmap);
for (Result result : results) {
BarcodeData data = new BarcodeData();
data.format = result.getBarcodeFormat();
data.text = result.getText();
// Get location
ResultPoint[] points = result.getResultPoints();
if (points != null && points.length > 0) {
data.x = (int) points[0].getX();
data.y = (int) points[0].getY();
}
barcodes.add(data);
}
return barcodes;
}
// Example usage
public static void main(String[] args) {
File[] documents = new File("scanned-docs").listFiles();
List<DocumentData> results = processDocuments(documents);
for (DocumentData doc : results) {
System.out.println("\n" + doc.filename + ":");
if (doc.processingError) {
System.out.println(" ERROR: " + doc.errorMessage);
} else {
System.out.println(" Found " + doc.barcodes.size() + " barcodes");
for (BarcodeData bc : doc.barcodes) {
System.out.println(" - " + bc.format + ": " + bc.text);
}
}
}
}
}Key Points:
GenericMultipleBarcodeReader for mixed formatsTRY_HARDER acceptable for batch processing (not real-time)Scenario: Generate QR code for WiFi network credentials.
import com.google.zxing.*;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import java.util.*;
public class WiFiQRGenerator {
public enum Security {
WPA, WPA2, WEP, NOPASS
}
public static BitMatrix generateWiFiQR(String ssid, String password,
Security security, boolean hidden)
throws WriterException {
// Build WiFi configuration string
String wifiConfig = buildWiFiString(ssid, password, security, hidden);
// Generate QR code with high error correction
Map<EncodeHintType, Object> hints = new EnumMap<>(EncodeHintType.class);
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
hints.put(EncodeHintType.MARGIN, 1);
QRCodeWriter writer = new QRCodeWriter();
return writer.encode(wifiConfig, BarcodeFormat.QR_CODE,
400, 400, hints);
}
private static String buildWiFiString(String ssid, String password,
Security security, boolean hidden) {
StringBuilder wifi = new StringBuilder("WIFI:");
// Network type
wifi.append("T:").append(security.name()).append(";");
// SSID (escape special characters)
wifi.append("S:").append(escapeSpecialChars(ssid)).append(";");
// Password (if not open network)
if (security != Security.NOPASS && password != null) {
wifi.append("P:").append(escapeSpecialChars(password)).append(";");
}
// Hidden network flag
wifi.append("H:").append(hidden ? "true" : "false").append(";");
wifi.append(";"); // Terminator
return wifi.toString();
}
private static String escapeSpecialChars(String str) {
return str.replace("\\", "\\\\")
.replace(";", "\\;")
.replace(",", "\\,")
.replace(":", "\\:");
}
// Example usage
public static void main(String[] args) throws Exception {
BitMatrix qrCode = generateWiFiQR(
"MyHomeNetwork",
"SecurePassword123",
Security.WPA2,
false
);
System.out.println("WiFi QR code generated!");
System.out.println("Dimensions: " + qrCode.getWidth() + "x" +
qrCode.getHeight());
// Could save to file using ImageIO as in previous examples
}
}Key Points:
;, :, ,, \\)Scenario: Scan product barcodes (UPC/EAN) for inventory or checkout systems.
import com.google.zxing.*;
import com.google.zxing.common.*;
import com.google.zxing.client.result.*;
import java.util.*;
public class ProductScanner {
private final Reader reader;
private final Map<DecodeHintType, Object> hints;
public ProductScanner() {
reader = new MultiFormatReader();
// Configure for product barcodes
hints = new EnumMap<>(DecodeHintType.class);
hints.put(DecodeHintType.POSSIBLE_FORMATS, Arrays.asList(
BarcodeFormat.EAN_13,
BarcodeFormat.EAN_8,
BarcodeFormat.UPC_A,
BarcodeFormat.UPC_E
));
hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
}
public ProductInfo scanProduct(BinaryBitmap bitmap) {
try {
Result result = reader.decode(bitmap, hints);
// Parse as product barcode
ParsedResult parsed = ResultParser.parseResult(result);
if (parsed.getType() == ParsedResultType.PRODUCT) {
ProductParsedResult product = (ProductParsedResult) parsed;
return new ProductInfo(
product.getProductID(),
result.getBarcodeFormat(),
true,
null
);
}
// Not a product barcode
return new ProductInfo(
result.getText(),
result.getBarcodeFormat(),
false,
"Not a product barcode"
);
} catch (NotFoundException e) {
return new ProductInfo(null, null, false, "No barcode found");
} catch (ChecksumException e) {
return new ProductInfo(null, null, false, "Damaged barcode");
} catch (FormatException e) {
return new ProductInfo(null, null, false, "Invalid barcode format");
}
}
public static class ProductInfo {
public final String productId;
public final BarcodeFormat format;
public final boolean success;
public final String errorMessage;
public ProductInfo(String productId, BarcodeFormat format,
boolean success, String errorMessage) {
this.productId = productId;
this.format = format;
this.success = success;
this.errorMessage = errorMessage;
}
public String getFormattedId() {
if (productId == null) return null;
// Add check digit if missing for EAN-13
if (format == BarcodeFormat.EAN_13 && productId.length() == 12) {
return productId + calculateEAN13CheckDigit(productId);
}
return productId;
}
private static char calculateEAN13CheckDigit(String code) {
int sum = 0;
for (int i = 0; i < 12; i++) {
int digit = Character.getNumericValue(code.charAt(i));
sum += (i % 2 == 0) ? digit : digit * 3;
}
int checksum = (10 - (sum % 10)) % 10;
return (char) ('0' + checksum);
}
}
// Example usage
public static void main(String[] args) {
ProductScanner scanner = new ProductScanner();
// Simulate scanning (would use camera in real app)
// BinaryBitmap bitmap = ...;
// ProductInfo info = scanner.scanProduct(bitmap);
//
// if (info.success) {
// System.out.println("Product ID: " + info.getFormattedId());
// System.out.println("Format: " + info.format);
// } else {
// System.out.println("Error: " + info.errorMessage);
// }
}
}Key Points:
TRY_HARDER for better accuracyScenario: Generate Code 128 barcodes for shipping labels.
import com.google.zxing.*;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.oned.Code128Writer;
import java.util.*;
public class ShippingLabelGenerator {
public static BitMatrix generateTrackingCode(String trackingNumber)
throws WriterException {
// Validate tracking number
if (trackingNumber == null || trackingNumber.isEmpty()) {
throw new IllegalArgumentException("Tracking number cannot be empty");
}
// Configure for shipping labels
Map<EncodeHintType, Object> hints = new EnumMap<>(EncodeHintType.class);
hints.put(EncodeHintType.MARGIN, 10); // Adequate quiet zones
hints.put(EncodeHintType.CODE128_COMPACT, Boolean.FALSE);
// Generate Code 128 barcode
Code128Writer writer = new Code128Writer();
return writer.encode(
trackingNumber,
BarcodeFormat.CODE_128,
400, // Width
100, // Height
hints
);
}
public static BitMatrix generateGS1Barcode(String gs1Data)
throws WriterException {
// Configure for GS1-128
Map<EncodeHintType, Object> hints = new EnumMap<>(EncodeHintType.class);
hints.put(EncodeHintType.GS1_FORMAT, Boolean.TRUE);
hints.put(EncodeHintType.MARGIN, 10);
Code128Writer writer = new Code128Writer();
return writer.encode(
gs1Data,
BarcodeFormat.CODE_128,
500,
100,
hints
);
}
// Example usage
public static void main(String[] args) throws Exception {
// Standard tracking number
BitMatrix tracking = generateTrackingCode("1Z999AA10123456784");
System.out.println("Tracking barcode: " +
tracking.getWidth() + "x" + tracking.getHeight());
// GS1-128 with Application Identifiers
// (01) GTIN, (17) Expiry Date, (10) Lot Number
String gs1 = "01095011010209171719050810LOT12345";
BitMatrix gs1Barcode = generateGS1Barcode(gs1);
System.out.println("GS1 barcode generated");
}
}Key Points:
Scenario: Generate QR codes containing contact information (vCard format).
import com.google.zxing.*;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import java.util.*;
public class VCardQRGenerator {
public static class Contact {
public String firstName;
public String lastName;
public String organization;
public String title;
public String phone;
public String email;
public String website;
public String address;
}
public static BitMatrix generateVCardQR(Contact contact)
throws WriterException {
String vcard = buildVCard(contact);
Map<EncodeHintType, Object> hints = new EnumMap<>(EncodeHintType.class);
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
hints.put(EncodeHintType.MARGIN, 2);
QRCodeWriter writer = new QRCodeWriter();
return writer.encode(vcard, BarcodeFormat.QR_CODE, 400, 400, hints);
}
private static String buildVCard(Contact c) {
StringBuilder vcard = new StringBuilder();
vcard.append("BEGIN:VCARD\n");
vcard.append("VERSION:3.0\n");
// Name
if (c.firstName != null || c.lastName != null) {
vcard.append("N:")
.append(c.lastName != null ? c.lastName : "").append(";")
.append(c.firstName != null ? c.firstName : "").append(";;;\n");
vcard.append("FN:")
.append(c.firstName != null ? c.firstName + " " : "")
.append(c.lastName != null ? c.lastName : "").append("\n");
}
// Organization and title
if (c.organization != null) {
vcard.append("ORG:").append(c.organization).append("\n");
}
if (c.title != null) {
vcard.append("TITLE:").append(c.title).append("\n");
}
// Phone
if (c.phone != null) {
vcard.append("TEL;TYPE=CELL:").append(c.phone).append("\n");
}
// Email
if (c.email != null) {
vcard.append("EMAIL;TYPE=INTERNET:").append(c.email).append("\n");
}
// Website
if (c.website != null) {
vcard.append("URL:").append(c.website).append("\n");
}
// Address
if (c.address != null) {
vcard.append("ADR:;;").append(c.address).append(";;;;\n");
}
vcard.append("END:VCARD");
return vcard.toString();
}
// Example usage
public static void main(String[] args) throws Exception {
Contact contact = new Contact();
contact.firstName = "John";
contact.lastName = "Doe";
contact.organization = "Tech Corp";
contact.title = "Software Engineer";
contact.phone = "+1-555-1234";
contact.email = "john.doe@example.com";
contact.website = "https://johndoe.com";
BitMatrix qr = generateVCardQR(contact);
System.out.println("vCard QR code generated!");
}
}Key Points:
Scenario: Try fast scanning first, fall back to thorough scan if needed.
import com.google.zxing.*;
import com.google.zxing.common.*;
import java.util.*;
public class AdaptiveScanner {
private final MultiFormatReader reader;
public AdaptiveScanner() {
reader = new MultiFormatReader();
}
public Result scan(BinaryBitmap bitmap) {
// Strategy 1: Fast scan with common formats
Result result = tryFastScan(bitmap);
if (result != null) {
return result;
}
// Strategy 2: Try all formats
result = tryAllFormats(bitmap);
if (result != null) {
return result;
}
// Strategy 3: Try harder with all formats
result = tryHarderScan(bitmap);
if (result != null) {
return result;
}
// Strategy 4: Try inverted
return tryInvertedScan(bitmap);
}
private Result tryFastScan(BinaryBitmap bitmap) {
try {
Map<DecodeHintType, Object> hints = new EnumMap<>(DecodeHintType.class);
hints.put(DecodeHintType.POSSIBLE_FORMATS, Arrays.asList(
BarcodeFormat.QR_CODE,
BarcodeFormat.EAN_13,
BarcodeFormat.CODE_128
));
return reader.decode(bitmap, hints);
} catch (NotFoundException | ChecksumException | FormatException e) {
return null;
} finally {
reader.reset();
}
}
private Result tryAllFormats(BinaryBitmap bitmap) {
try {
return reader.decode(bitmap);
} catch (NotFoundException | ChecksumException | FormatException e) {
return null;
} finally {
reader.reset();
}
}
private Result tryHarderScan(BinaryBitmap bitmap) {
try {
Map<DecodeHintType, Object> hints = new EnumMap<>(DecodeHintType.class);
hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
return reader.decode(bitmap, hints);
} catch (NotFoundException | ChecksumException | FormatException e) {
return null;
} finally {
reader.reset();
}
}
private Result tryInvertedScan(BinaryBitmap bitmap) {
try {
Map<DecodeHintType, Object> hints = new EnumMap<>(DecodeHintType.class);
hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
hints.put(DecodeHintType.ALSO_INVERTED, Boolean.TRUE);
return reader.decode(bitmap, hints);
} catch (NotFoundException | ChecksumException | FormatException e) {
return null;
} finally {
reader.reset();
}
}
// Example usage
public static void main(String[] args) {
AdaptiveScanner scanner = new AdaptiveScanner();
// BinaryBitmap bitmap = ...;
// Result result = scanner.scan(bitmap);
//
// if (result != null) {
// System.out.println("Success: " + result.getText());
// } else {
// System.out.println("Failed to decode barcode");
// }
}
}Key Points:
Scenario: Optimize for real-time video frame processing with minimal CPU usage.
import com.google.zxing.*;
import com.google.zxing.common.*;
import java.util.*;
import java.util.concurrent.*;
public class VideoScanner {
private final MultiFormatReader reader;
private final ExecutorService executor;
private final Map<DecodeHintType, Object> hints;
private volatile boolean isScanning = false;
// Rate limiting
private static final long MIN_FRAME_INTERVAL_MS = 100;
private long lastFrameTime = 0;
// Deduplication
private String lastResult = null;
private long lastResultTime = 0;
private static final long RESULT_DEDUP_MS = 2000;
public VideoScanner() {
reader = new MultiFormatReader();
executor = Executors.newSingleThreadExecutor();
// Optimize for speed
hints = new EnumMap<>(DecodeHintType.class);
hints.put(DecodeHintType.POSSIBLE_FORMATS, Arrays.asList(
BarcodeFormat.QR_CODE,
BarcodeFormat.EAN_13,
BarcodeFormat.CODE_128
));
hints.put(DecodeHintType.TRY_HARDER, Boolean.FALSE);
hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
reader.setHints(hints);
}
public void scanFrameAsync(byte[] yuvData, int width, int height,
ScanCallback callback) {
// Rate limit frame processing
long now = System.currentTimeMillis();
if (now - lastFrameTime < MIN_FRAME_INTERVAL_MS) {
return;
}
lastFrameTime = now;
// Skip if already processing
if (isScanning) {
return;
}
isScanning = true;
executor.submit(() -> {
try {
Result result = scanFrame(yuvData, width, height);
if (result != null) {
// Deduplicate results
if (!isDuplicate(result.getText())) {
callback.onBarcodeDetected(result);
lastResult = result.getText();
lastResultTime = System.currentTimeMillis();
}
}
} finally {
isScanning = false;
}
});
}
private Result scanFrame(byte[] yuvData, int width, int height) {
try {
// Process center region only (faster)
int cropSize = Math.min(width, height) * 2 / 3;
int left = (width - cropSize) / 2;
int top = (height - cropSize) / 2;
LuminanceSource source = new PlanarYUVLuminanceSource(
yuvData, width, height,
left, top, cropSize, cropSize,
false
);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
return reader.decodeWithState(bitmap);
} catch (NotFoundException e) {
return null;
} catch (Exception e) {
return null;
}
}
private boolean isDuplicate(String text) {
if (lastResult == null) {
return false;
}
long now = System.currentTimeMillis();
return text.equals(lastResult) &&
(now - lastResultTime) < RESULT_DEDUP_MS;
}
public void shutdown() {
executor.shutdown();
}
public interface ScanCallback {
void onBarcodeDetected(Result result);
}
// Example usage
public static void main(String[] args) {
VideoScanner scanner = new VideoScanner();
ScanCallback callback = result -> {
System.out.println("Detected: " + result.getText());
System.out.println("Format: " + result.getBarcodeFormat());
};
// In camera preview callback:
// scanner.scanFrameAsync(yuvData, width, height, callback);
// When done:
// scanner.shutdown();
}
}Key Points:
decodeWithState() to maintain reader stateScenario: Validate generated barcodes can be reliably decoded.
import com.google.zxing.*;
import com.google.zxing.common.*;
import java.awt.image.BufferedImage;
public class BarcodeValidator {
public static class ValidationResult {
public boolean isReadable;
public String decodedText;
public String expectedText;
public boolean textMatches;
public BarcodeFormat detectedFormat;
public BarcodeFormat expectedFormat;
public boolean formatMatches;
public String errorMessage;
public int qualityScore; // 0-100
public boolean isValid() {
return isReadable && textMatches && formatMatches;
}
}
public static ValidationResult validate(BitMatrix matrix,
String expectedText,
BarcodeFormat expectedFormat) {
ValidationResult result = new ValidationResult();
result.expectedText = expectedText;
result.expectedFormat = expectedFormat;
try {
// Convert BitMatrix to BinaryBitmap
BufferedImage image = toBufferedImage(matrix);
int[] pixels = image.getRGB(0, 0, image.getWidth(),
image.getHeight(), null, 0,
image.getWidth());
LuminanceSource source = new RGBLuminanceSource(
image.getWidth(), image.getHeight(), pixels);
BinaryBitmap bitmap = new BinaryBitmap(
new HybridBinarizer(source));
// Try to decode
Reader reader = new MultiFormatReader();
Result decoded = reader.decode(bitmap);
result.isReadable = true;
result.decodedText = decoded.getText();
result.detectedFormat = decoded.getBarcodeFormat();
// Validate text
result.textMatches = expectedText.equals(decoded.getText());
// Validate format
result.formatMatches = expectedFormat == decoded.getBarcodeFormat();
// Calculate quality score
result.qualityScore = calculateQualityScore(
matrix, result.textMatches, result.formatMatches);
} catch (NotFoundException e) {
result.isReadable = false;
result.errorMessage = "Barcode not detectable";
result.qualityScore = 0;
} catch (ChecksumException e) {
result.isReadable = false;
result.errorMessage = "Checksum validation failed";
result.qualityScore = 20;
} catch (FormatException e) {
result.isReadable = false;
result.errorMessage = "Format validation failed";
result.qualityScore = 10;
}
return result;
}
private static int calculateQualityScore(BitMatrix matrix,
boolean textMatches,
boolean formatMatches) {
int score = 50; // Base score for being readable
if (textMatches) score += 25;
if (formatMatches) score += 25;
// Check size (larger is generally better)
int size = matrix.getWidth() * matrix.getHeight();
if (size >= 300 * 300) score = Math.min(100, score + 10);
else if (size < 150 * 150) score -= 10;
return Math.max(0, Math.min(100, score));
}
private static BufferedImage toBufferedImage(BitMatrix matrix) {
int width = matrix.getWidth();
int height = matrix.getHeight();
BufferedImage image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int color = matrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF;
image.setRGB(x, y, color);
}
}
return image;
}
// Example usage
public static void main(String[] args) throws Exception {
// Generate a barcode
Writer writer = new MultiFormatWriter();
BitMatrix matrix = writer.encode(
"TEST12345",
BarcodeFormat.CODE_128,
300,
100
);
// Validate it
ValidationResult validation = validate(
matrix,
"TEST12345",
BarcodeFormat.CODE_128
);
System.out.println("Is valid: " + validation.isValid());
System.out.println("Quality score: " + validation.qualityScore);
if (!validation.isValid()) {
System.out.println("Error: " + validation.errorMessage);
}
}
}Key Points: