Article
QR (Quick Response) codes have become ubiquitous for storing and sharing information efficiently. This comprehensive guide covers generating, customizing, and scanning QR codes in Java applications using popular libraries like ZXing and QRGen.
QR Code Basics
QR Code Structure:
- Finder Patterns: Three squares for orientation
- Alignment Patterns: For correction perspective distortion
- Timing Patterns: Coordinate system for modules
- Data Area: Encoded information
- Error Correction: Reed-Solomon codes for damage recovery
Error Correction Levels:
- L (Low): 7% damage recovery
- M (Medium): 15% damage recovery
- Q (Quartile): 25% damage recovery
- H (High): 30% damage recovery
Project Setup and Dependencies
Maven Dependencies
<properties>
<zxing.version>3.5.1</zxing.version>
<qrgen.version>3.0</qrgen.version>
</properties>
<dependencies>
<!-- Core ZXing Library -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>${zxing.version}</version>
</dependency>
<!-- ZXing JavaSE extension for image generation -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>${zxing.version}</version>
</dependency>
<!-- QRGen for simplified QR code generation -->
<dependency>
<groupId>com.github.kenglxn.qrgen</groupId>
<artifactId>javase</artifactId>
<version>${qrgen.version}</version>
</dependency>
<!-- Image processing -->
<dependency>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio-core</artifactId>
<version>3.9.4</version>
</dependency>
<!-- Webcam capture for scanning -->
<dependency>
<groupId>com.github.sarxos</groupId>
<artifactId>webcam-capture</artifactId>
<version>0.3.12</version>
</dependency>
<!-- Spring Boot Web (for web applications) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.7.0</version>
</dependency>
</dependencies>
Gradle Dependencies
dependencies {
implementation 'com.google.zxing:core:3.5.1'
implementation 'com.google.zxing:javase:3.5.1'
implementation 'com.github.kenglxn.qrgen:javase:3.0'
implementation 'com.twelvemonkeys.imageio:imageio-core:3.9.4'
implementation 'com.github.sarxos:webcam-capture:0.3.12'
implementation 'org.springframework.boot:spring-boot-starter-web:2.7.0'
}
QR Code Generation with ZXing
1. Basic QR Code Generator
import com.google.zxing.BarcodeFormat;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;
import javax.imageio.ImageIO;
public class BasicQRCodeGenerator {
/**
* Generate basic QR code and save to file
*/
public static void generateQRCodeImage(String text, int width, int height, String filePath)
throws WriterException, IOException {
QRCodeWriter qrCodeWriter = new QRCodeWriter();
BitMatrix bitMatrix = qrCodeWriter.encode(text, BarcodeFormat.QR_CODE, width, height);
Path path = FileSystems.getDefault().getPath(filePath);
MatrixToImageWriter.writeToPath(bitMatrix, "PNG", path);
System.out.println("QR Code generated: " + filePath);
}
/**
* Generate QR code as BufferedImage
*/
public static BufferedImage generateQRCodeImage(String text, int width, int height)
throws WriterException {
QRCodeWriter qrCodeWriter = new QRCodeWriter();
BitMatrix bitMatrix = qrCodeWriter.encode(text, BarcodeFormat.QR_CODE, width, height);
return MatrixToImageWriter.toBufferedImage(bitMatrix);
}
/**
* Generate QR code as byte array
*/
public static byte[] generateQRCodeBytes(String text, int width, int height)
throws WriterException, IOException {
BufferedImage qrImage = generateQRCodeImage(text, width, height);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(qrImage, "PNG", baos);
return baos.toByteArray();
}
/**
* Generate QR code with custom configuration
*/
public static void generateCustomQRCode(String text, int width, int height,
String filePath, Map<String, Object> config)
throws WriterException, IOException {
QRCodeWriter qrCodeWriter = new QRCodeWriter();
// Default configuration
Map<com.google.zxing.EncodeHintType, Object> hints = new HashMap<>();
hints.put(com.google.zxing.EncodeHintType.CHARACTER_SET, "UTF-8");
hints.put(com.google.zxing.EncodeHintType.MARGIN, 2); // Quiet zone
// Add error correction level
if (config.containsKey("errorCorrection")) {
String errorCorrection = (String) config.get("errorCorrection");
hints.put(com.google.zxing.EncodeHintType.ERROR_CORRECTION,
getErrorCorrectionLevel(errorCorrection));
}
BitMatrix bitMatrix = qrCodeWriter.encode(text, BarcodeFormat.QR_CODE, width, height, hints);
Path path = FileSystems.getDefault().getPath(filePath);
MatrixToImageWriter.writeToPath(bitMatrix, "PNG", path);
System.out.println("Custom QR Code generated: " + filePath);
}
private static com.google.zxing.qrcode.decoder.ErrorCorrectionLevel getErrorCorrectionLevel(String level) {
switch (level.toUpperCase()) {
case "L": return com.google.zxing.qrcode.decoder.ErrorCorrectionLevel.L;
case "M": return com.google.zxing.qrcode.decoder.ErrorCorrectionLevel.M;
case "Q": return com.google.zxing.qrcode.decoder.ErrorCorrectionLevel.Q;
case "H": return com.google.zxing.qrcode.decoder.ErrorCorrectionLevel.H;
default: return com.google.zxing.qrcode.decoder.ErrorCorrectionLevel.M;
}
}
public static void main(String[] args) {
try {
// Generate basic QR code
generateQRCodeImage("https://www.example.com", 350, 350, "basic-qr.png");
// Generate custom QR code
Map<String, Object> config = new HashMap<>();
config.put("errorCorrection", "H"); // High error correction
generateCustomQRCode("Hello, QR Code!", 300, 300, "custom-qr.png", config);
} catch (Exception e) {
e.printStackTrace();
}
}
}
2. Advanced QR Code Generator with Styling
import com.google.zxing.BarcodeFormat;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.imageio.ImageIO;
public class StyledQRCodeGenerator {
/**
* Generate QR code with custom colors and styling
*/
public static BufferedImage generateStyledQRCode(String text, int width, int height,
QRCodeStyle style) throws WriterException {
QRCodeWriter qrCodeWriter = new QRCodeWriter();
Map<com.google.zxing.EncodeHintType, Object> hints = new HashMap<>();
hints.put(com.google.zxing.EncodeHintType.CHARACTER_SET, "UTF-8");
hints.put(com.google.zxing.EncodeHintType.MARGIN, style.getMargin());
hints.put(com.google.zxing.EncodeHintType.ERROR_CORRECTION, style.getErrorCorrectionLevel());
BitMatrix bitMatrix = qrCodeWriter.encode(text, BarcodeFormat.QR_CODE, width, height, hints);
return createStyledImage(bitMatrix, width, height, style);
}
/**
* Create styled image from bit matrix
*/
private static BufferedImage createStyledImage(BitMatrix matrix, int width, int height,
QRCodeStyle style) {
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = image.createGraphics();
// Set background
graphics.setColor(style.getBackgroundColor());
graphics.fillRect(0, 0, width, height);
// Enable anti-aliasing
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// Draw QR code modules
int matrixWidth = matrix.getWidth();
int matrixHeight = matrix.getHeight();
int pixelWidth = width / matrixWidth;
int pixelHeight = height / matrixHeight;
for (int x = 0; x < matrixWidth; x++) {
for (int y = 0; y < matrixHeight; y++) {
if (matrix.get(x, y)) {
// Check if this is part of a finder pattern
if (isFinderPattern(matrix, x, y, matrixWidth, matrixHeight)) {
graphics.setColor(style.getFinderPatternColor());
} else {
graphics.setColor(style.getForegroundColor());
}
// Draw rounded rectangles for better appearance
int xPos = x * pixelWidth;
int yPos = y * pixelHeight;
graphics.fillRoundRect(xPos, yPos, pixelWidth, pixelHeight,
style.getCornerRadius(), style.getCornerRadius());
}
}
}
graphics.dispose();
return image;
}
/**
* Detect finder patterns (the three corner squares)
*/
private static boolean isFinderPattern(BitMatrix matrix, int x, int y, int width, int height) {
// Check if we're in the top-left finder pattern (7x7 modules)
if (x < 7 && y < 7) return true;
// Check top-right finder pattern
if (x > width - 8 && y < 7) return true;
// Check bottom-left finder pattern
if (x < 7 && y > height - 8) return true;
return false;
}
/**
* Add logo to QR code center
*/
public static BufferedImage addLogoToQRCode(BufferedImage qrImage, BufferedImage logo) {
int qrWidth = qrImage.getWidth();
int qrHeight = qrImage.getHeight();
// Calculate logo size (20% of QR code size)
int logoWidth = qrWidth / 5;
int logoHeight = qrHeight / 5;
// Resize logo
BufferedImage resizedLogo = resizeImage(logo, logoWidth, logoHeight);
// Create new image with logo
BufferedImage combined = new BufferedImage(qrWidth, qrHeight, BufferedImage.TYPE_INT_RGB);
Graphics2D g = combined.createGraphics();
// Draw QR code
g.drawImage(qrImage, 0, 0, null);
// Draw logo in center
int x = (qrWidth - logoWidth) / 2;
int y = (qrHeight - logoHeight) / 2;
// Create white background for logo
g.setColor(Color.WHITE);
g.fillRect(x - 5, y - 5, logoWidth + 10, logoHeight + 10);
// Draw logo
g.drawImage(resizedLogo, x, y, null);
g.dispose();
return combined;
}
/**
* Resize image
*/
private static BufferedImage resizeImage(BufferedImage originalImage, int targetWidth, int targetHeight) {
BufferedImage resizedImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = resizedImage.createGraphics();
graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
graphics.drawImage(originalImage, 0, 0, targetWidth, targetHeight, null);
graphics.dispose();
return resizedImage;
}
/**
* Save image to file
*/
public static void saveImage(BufferedImage image, String filePath, String format) throws IOException {
File output = new File(filePath);
ImageIO.write(image, format, output);
System.out.println("Styled QR Code saved: " + filePath);
}
public static void main(String[] args) {
try {
// Create custom style
QRCodeStyle style = new QRCodeStyle()
.setForegroundColor(Color.BLUE)
.setBackgroundColor(Color.WHITE)
.setFinderPatternColor(Color.RED)
.setMargin(2)
.setCornerRadius(5)
.setErrorCorrectionLevel(com.google.zxing.qrcode.decoder.ErrorCorrectionLevel.H);
// Generate styled QR code
BufferedImage styledQR = generateStyledQRCode("Styled QR Code Example", 400, 400, style);
saveImage(styledQR, "styled-qr.png", "PNG");
// Add logo if available
try {
BufferedImage logo = ImageIO.read(new File("logo.png"));
BufferedImage qrWithLogo = addLogoToQRCode(styledQR, logo);
saveImage(qrWithLogo, "qr-with-logo.png", "PNG");
} catch (IOException e) {
System.out.println("Logo file not found, generating without logo");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* QR Code styling configuration
*/
class QRCodeStyle {
private Color foregroundColor = Color.BLACK;
private Color backgroundColor = Color.WHITE;
private Color finderPatternColor = Color.BLACK;
private int margin = 1;
private int cornerRadius = 0;
private com.google.zxing.qrcode.decoder.ErrorCorrectionLevel errorCorrectionLevel =
com.google.zxing.qrcode.decoder.ErrorCorrectionLevel.M;
// Fluent setters
public QRCodeStyle setForegroundColor(Color color) {
this.foregroundColor = color;
return this;
}
public QRCodeStyle setBackgroundColor(Color color) {
this.backgroundColor = color;
return this;
}
public QRCodeStyle setFinderPatternColor(Color color) {
this.finderPatternColor = color;
return this;
}
public QRCodeStyle setMargin(int margin) {
this.margin = margin;
return this;
}
public QRCodeStyle setCornerRadius(int radius) {
this.cornerRadius = radius;
return this;
}
public QRCodeStyle setErrorCorrectionLevel(com.google.zxing.qrcode.decoder.ErrorCorrectionLevel level) {
this.errorCorrectionLevel = level;
return this;
}
// Getters
public Color getForegroundColor() { return foregroundColor; }
public Color getBackgroundColor() { return backgroundColor; }
public Color getFinderPatternColor() { return finderPatternColor; }
public int getMargin() { return margin; }
public int getCornerRadius() { return cornerRadius; }
public com.google.zxing.qrcode.decoder.ErrorCorrectionLevel getErrorCorrectionLevel() { return errorCorrectionLevel; }
}
QR Code Generation with QRGen
1. Simplified QR Code Generation
import net.glxn.qrgen.core.image.ImageType;
import net.glxn.qrgen.javase.QRCode;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class QRGenGenerator {
/**
* Generate QR code with QRGen (simplified API)
*/
public static void generateWithQRGen(String text, String filePath) throws IOException {
ByteArrayOutputStream stream = QRCode.from(text)
.withSize(350, 350)
.to(ImageType.PNG)
.stream();
try (FileOutputStream fos = new FileOutputStream(filePath)) {
fos.write(stream.toByteArray());
}
System.out.println("QRGen QR Code generated: " + filePath);
}
/**
* Generate QR code with custom settings
*/
public static void generateCustomWithQRGen(String text, String filePath,
int width, int height, String errorCorrection)
throws IOException {
ByteArrayOutputStream stream = QRCode.from(text)
.withSize(width, height)
.withErrorCorrection(getErrorCorrection(errorCorrection))
.withCharset("UTF-8")
.to(ImageType.PNG)
.stream();
try (FileOutputStream fos = new FileOutputStream(filePath)) {
fos.write(stream.toByteArray());
}
System.out.println("Custom QRGen QR Code generated: " + filePath);
}
/**
* Generate QR code as byte array
*/
public static byte[] generateQRCodeBytes(String text, int width, int height) {
return QRCode.from(text)
.withSize(width, height)
.to(ImageType.PNG)
.stream()
.toByteArray();
}
private static net.glxn.qrgen.core.scheme.ECLevel getErrorCorrection(String level) {
switch (level.toUpperCase()) {
case "L": return net.glxn.qrgen.core.scheme.ECLevel.L;
case "M": return net.glxn.qrgen.core.scheme.ECLevel.M;
case "Q": return net.glxn.qrgen.core.scheme.ECLevel.Q;
case "H": return net.glxn.qrgen.core.scheme.ECLevel.H;
default: return net.glxn.qrgen.core.scheme.ECLevel.M;
}
}
public static void main(String[] args) {
try {
// Basic generation
generateWithQRGen("https://www.example.com", "qrgen-basic.png");
// Custom generation
generateCustomWithQRGen("Custom QR Code", "qrgen-custom.png",
400, 400, "H");
} catch (IOException e) {
e.printStackTrace();
}
}
}
QR Code Scanning and Decoding
1. Basic QR Code Scanner
import com.google.zxing.*;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.HybridBinarizer;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class BasicQRCodeScanner {
/**
* Decode QR code from image file
*/
public static String decodeQRCode(File qrCodeImage) throws IOException, NotFoundException {
BufferedImage bufferedImage = ImageIO.read(qrCodeImage);
return decodeQRCode(bufferedImage);
}
/**
* Decode QR code from BufferedImage
*/
public static String decodeQRCode(BufferedImage bufferedImage) throws NotFoundException {
LuminanceSource source = new BufferedImageLuminanceSource(bufferedImage);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
Map<DecodeHintType, Object> hints = new HashMap<>();
hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
Result result = new MultiFormatReader().decode(bitmap, hints);
return result.getText();
}
/**
* Decode QR code with detailed information
*/
public static QRCodeResult decodeQRCodeWithDetails(File qrCodeImage)
throws IOException, NotFoundException {
BufferedImage bufferedImage = ImageIO.read(qrCodeImage);
LuminanceSource source = new BufferedImageLuminanceSource(bufferedImage);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
Map<DecodeHintType, Object> hints = new HashMap<>();
hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
Result result = new MultiFormatReader().decode(bitmap, hints);
return new QRCodeResult(
result.getText(),
result.getBarcodeFormat(),
result.getResultMetadata(),
result.getResultPoints()
);
}
/**
* Try to decode multiple times with different settings
*/
public static String decodeQRCodeRobust(File qrCodeImage, int maxAttempts) {
for (int attempt = 0; attempt < maxAttempts; attempt++) {
try {
BufferedImage bufferedImage = ImageIO.read(qrCodeImage);
// Try different binarization strategies
LuminanceSource source = new BufferedImageLuminanceSource(bufferedImage);
BinaryBitmap bitmap;
if (attempt % 2 == 0) {
bitmap = new BinaryBitmap(new HybridBinarizer(source));
} else {
bitmap = new BinaryBitmap(new GlobalHistogramBinarizer(source));
}
Map<DecodeHintType, Object> hints = new HashMap<>();
hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
// Try different pure barcode modes
if (attempt > 1) {
hints.put(DecodeHintType.PURE_BARCODE, Boolean.TRUE);
}
Result result = new MultiFormatReader().decode(bitmap, hints);
return result.getText();
} catch (Exception e) {
System.out.println("Attempt " + (attempt + 1) + " failed: " + e.getMessage());
}
}
throw new RuntimeException("Failed to decode QR code after " + maxAttempts + " attempts");
}
public static void main(String[] args) {
try {
File qrCodeFile = new File("basic-qr.png");
// Basic decoding
String decodedText = decodeQRCode(qrCodeFile);
System.out.println("Decoded text: " + decodedText);
// Detailed decoding
QRCodeResult result = decodeQRCodeWithDetails(qrCodeFile);
System.out.println("Detailed result: " + result);
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* Detailed QR code decoding result
*/
class QRCodeResult {
private final String text;
private final BarcodeFormat format;
private final java.util.Map<ResultMetadataType, Object> metadata;
private final ResultPoint[] resultPoints;
public QRCodeResult(String text, BarcodeFormat format,
java.util.Map<ResultMetadataType, Object> metadata,
ResultPoint[] resultPoints) {
this.text = text;
this.format = format;
this.metadata = metadata;
this.resultPoints = resultPoints;
}
// Getters
public String getText() { return text; }
public BarcodeFormat getFormat() { return format; }
public java.util.Map<ResultMetadataType, Object> getMetadata() { return metadata; }
public ResultPoint[] getResultPoints() { return resultPoints; }
@Override
public String toString() {
return String.format("QRCodeResult{text='%s', format=%s, points=%d}",
text, format, resultPoints != null ? resultPoints.length : 0);
}
}
2. Webcam QR Code Scanner
import com.github.sarxos.webcam.Webcam;
import com.google.zxing.*;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.HybridBinarizer;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class WebcamQRCodeScanner {
private Webcam webcam;
private JFrame frame;
private JLabel imageLabel;
private boolean scanning = false;
private final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
public WebcamQRCodeScanner() {
initializeWebcam();
initializeUI();
}
private void initializeWebcam() {
webcam = Webcam.getDefault();
if (webcam != null) {
webcam.setViewSize(new Dimension(640, 480));
} else {
throw new RuntimeException("No webcam found");
}
}
private void initializeUI() {
frame = new JFrame("QR Code Scanner");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
imageLabel = new JLabel();
imageLabel.setHorizontalAlignment(SwingConstants.CENTER);
frame.add(imageLabel, BorderLayout.CENTER);
JButton startButton = new JButton("Start Scanning");
startButton.addActionListener(e -> startScanning());
JButton stopButton = new JButton("Stop Scanning");
stopButton.addActionListener(e -> stopScanning());
JPanel buttonPanel = new JPanel();
buttonPanel.add(startButton);
buttonPanel.add(stopButton);
frame.add(buttonPanel, BorderLayout.SOUTH);
frame.pack();
frame.setLocationRelativeTo(null);
}
public void startScanning() {
if (scanning) return;
scanning = true;
webcam.open();
executor.scheduleAtFixedRate(this::captureAndDecode, 0, 100, TimeUnit.MILLISECONDS);
frame.setVisible(true);
System.out.println("QR Code scanning started...");
}
public void stopScanning() {
scanning = false;
executor.shutdown();
if (webcam.isOpen()) {
webcam.close();
}
frame.dispose();
System.out.println("QR Code scanning stopped.");
}
private void captureAndDecode() {
if (!webcam.isOpen() || !scanning) return;
try {
BufferedImage image = webcam.getImage();
// Update UI
updateImage(image);
// Try to decode QR code
String result = decodeQRCode(image);
if (result != null) {
handleQRCodeDetected(result);
}
} catch (Exception e) {
System.err.println("Error during capture/decode: " + e.getMessage());
}
}
private String decodeQRCode(BufferedImage image) {
try {
LuminanceSource source = new BufferedImageLuminanceSource(image);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
Map<DecodeHintType, Object> hints = new HashMap<>();
hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
Result result = new MultiFormatReader().decode(bitmap, hints);
return result.getText();
} catch (NotFoundException e) {
// No QR code found in this frame
return null;
} catch (Exception e) {
System.err.println("Decoding error: " + e.getMessage());
return null;
}
}
private void updateImage(BufferedImage image) {
ImageIcon icon = new ImageIcon(image);
imageLabel.setIcon(icon);
frame.pack();
}
private void handleQRCodeDetected(String qrContent) {
System.out.println("QR Code detected: " + qrContent);
// Show dialog with detected content
JOptionPane.showMessageDialog(frame,
"QR Code Detected:\n" + qrContent,
"QR Code Found",
JOptionPane.INFORMATION_MESSAGE);
// Stop scanning after successful detection
stopScanning();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
try {
new WebcamQRCodeScanner().startScanning();
} catch (Exception e) {
JOptionPane.showMessageDialog(null,
"Error initializing scanner: " + e.getMessage(),
"Error",
JOptionPane.ERROR_MESSAGE);
}
});
}
}
Advanced QR Code Features
1. QR Code for Different Data Types
import com.google.zxing.BarcodeFormat;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
public class AdvancedQRCodeGenerator {
/**
* Generate QR code for URL
*/
public static void generateURLQRCode(String url, String filePath) throws WriterException, IOException {
generateQRCode(url, 350, 350, filePath);
}
/**
* Generate QR code for contact information (vCard)
*/
public static void generateContactQRCode(String name, String phone, String email,
String filePath) throws WriterException, IOException {
String vCard = String.format(
"BEGIN:VCARD\n" +
"VERSION:3.0\n" +
"FN:%s\n" +
"TEL:%s\n" +
"EMAIL:%s\n" +
"END:VCARD", name, phone, email);
generateQRCode(vCard, 350, 350, filePath);
}
/**
* Generate QR code for WiFi credentials
*/
public static void generateWiFiQRCode(String ssid, String password, String encryption,
String filePath) throws WriterException, IOException {
String wifiConfig = String.format(
"WIFI:S:%s;T:%s;P:%s;;", ssid, encryption, password);
generateQRCode(wifiConfig, 350, 350, filePath);
}
/**
* Generate QR code for calendar event
*/
public static void generateEventQRCode(String title, String description, String location,
String startTime, String endTime, String filePath)
throws WriterException, IOException {
String event = String.format(
"BEGIN:VEVENT\n" +
"SUMMARY:%s\n" +
"DESCRIPTION:%s\n" +
"LOCATION:%s\n" +
"DTSTART:%s\n" +
"DTEND:%s\n" +
"END:VEVENT", title, description, location, startTime, endTime);
generateQRCode(event, 400, 400, filePath);
}
/**
* Generate QR code for geographic location
*/
public static void generateLocationQRCode(double latitude, double longitude,
String filePath) throws WriterException, IOException {
String location = String.format("geo:%f,%f", latitude, longitude);
generateQRCode(location, 350, 350, filePath);
}
/**
* Generate QR code for email
*/
public static void generateEmailQRCode(String to, String subject, String body,
String filePath) throws WriterException, IOException {
String email = String.format("mailto:%s?subject=%s&body=%s", to, subject, body);
generateQRCode(email, 350, 350, filePath);
}
/**
* Generate QR code for SMS
*/
public static void generateSMSQRCode(String phoneNumber, String message,
String filePath) throws WriterException, IOException {
String sms = String.format("sms:%s?body=%s", phoneNumber, message);
generateQRCode(sms, 350, 350, filePath);
}
private static void generateQRCode(String text, int width, int height, String filePath)
throws WriterException, IOException {
QRCodeWriter qrCodeWriter = new QRCodeWriter();
Map<com.google.zxing.EncodeHintType, Object> hints = new HashMap<>();
hints.put(com.google.zxing.EncodeHintType.CHARACTER_SET, "UTF-8");
hints.put(com.google.zxing.EncodeHintType.MARGIN, 2);
BitMatrix bitMatrix = qrCodeWriter.encode(text, BarcodeFormat.QR_CODE, width, height, hints);
MatrixToImageWriter.writeToPath(bitMatrix, "PNG", Paths.get(filePath));
System.out.println("QR Code generated: " + filePath);
}
public static void main(String[] args) {
try {
// Generate different types of QR codes
generateURLQRCode("https://www.example.com", "url-qr.png");
generateContactQRCode("John Doe", "+1234567890", "[email protected]", "contact-qr.png");
generateWiFiQRCode("MyWiFi", "password123", "WPA", "wifi-qr.png");
generateEmailQRCode("[email protected]", "Hello", "This is a test email", "email-qr.png");
} catch (Exception e) {
e.printStackTrace();
}
}
}
2. Batch QR Code Generator
```java
import com.google.zxing.BarcodeFormat;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class BatchQRCodeGenerator {
private final ExecutorService executor;
private final QRCodeWriter qrCodeWriter;
public BatchQRCodeGenerator(int threadPoolSize) {
this.executor = Executors.newFixedThreadPool(threadPoolSize);
this.qrCodeWriter = new QRCodeWriter();
}
/**
* Generate multiple QR codes in batch
*/
public List<CompletableFuture<File>> generateBatchQRCodes(List<QRCodeData> qrCodeDataList,
String outputDirectory) {
List<CompletableFuture<File>> futures = new ArrayList<>();
// Create output directory if it doesn't exist
Path outputPath = Paths.get(outputDirectory);
try {
Files.createDirectories(outputPath);
} catch (IOException e) {
throw new RuntimeException("Failed to create output directory", e);
}
for (QRCodeData data : qrCodeDataList) {
CompletableFuture<File> future = CompletableFuture.supplyAsync(() -> {
try {
return generateSingleQRCode(data, outputDirectory);
} catch (Exception e) {
throw new RuntimeException("Failed to generate QR code for: " + data.getFileName(), e);
}
}, executor);
futures.add(future);
}