QR Code Generator and Reader (java, written by Claude Code)
envgap__claude-code__java-t1-46
Written by a coding agent; not on GitHubWritten 2026-02-28
01 / FAILURE SIGNATURE
As the study recorded it
cannot find symbol: class MultipleBarcodeReader
Not a benchmark task.
- In a clean container the reported failure did not reproduce, or the known fix did not make the project run.
02 / ENVIRONMENT RECIPE
- Base commit
Not freshly verified- Manifest
pom.xml- Reproduce
Awaiting issue-specific recipe- Run under trace
Awaiting a meaningful runtime command
03 / TASK AND FAILURE
claude-code/java-t1 #46 · read the task the agent was given
Claude Code wrote this java project from the task below. It does not run on a clean Ubuntu 22.04 machine as written. Task given to the agent: TASK: QR Code Generator and Reader Write a program that generates QR codes from text or URLs and reads/decodes QR codes from image files, supporting multiple output formats and error correction levels. FUNCTIONAL REQUIREMENTS: - Support two subcommands: generate and read - generate: Accept text or URL content via command-line argument and produce a QR code image - Support configurable error correction levels via --error-correction flag: L (7%), M (15%), Q (25%), H (30%); default: M - Support configurable QR code size via --size flag (pixels for the output image, default: 300x300) - Support configurable module (pixel block) size via --scale flag (default: 10 pixels per module) - Support custom colors via --foreground and --background flags (hex color codes, default: black on white) - Support multiple output formats via --format flag: PNG (default), SVG, and ASCII art (for terminal display) - Support adding a logo/image overlay in the center of the QR code via --logo flag (relies on higher error correction to remain scannable) - read: Accept an image file path and decode the QR code content from it - read: Support decoding from various image formats (PNG, JPEG, BMP) - read: Report decoded content, QR version, error correction level, and encoding mode - Support batch generation from a file containing one content string per line via --batch flag - Print results to console: for generation show the content encoded and output path, for reading show the decoded content - Save decoded results as JSON with --output flag - If no arguments are given, generate QR codes for several sample inputs (a URL, a plain text message, a vCard contact, and a Wi-Fi network config), save them as images, then read each one back and verify the decoded content matches the original - Handle errors: content too long for QR capacity, unreadable QR codes, low-quality images, and invalid color values Create a complete Java project for a clean Ubuntu 22.04 machine with only JDK 17+ installed. Include: - Source code - pom.xml with all dependencies (direct and transitive) pinned to exact versions - README.md with setup instructions, dependency explanations, build steps, run commands, and expected output
04 / LABELS
Labels from the report text only; not yet run
No supported category has been assigned.
Label rules and the text that matched
[]
05 / FILES
The project as the agent wrote it
3 files, exactly as written, before any repair.
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>qr-tool</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<name>QR Code Generator and Reader</name>
<description>
Generates QR codes (PNG/SVG/ASCII) with error correction and decodes
QR codes from images using ZXing.
</description>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.5.3</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.5.3</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<archive>
<manifest>
<mainClass>qrtool.QrTool</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>
README.md
# QR Code Generator and Reader (Java - Trial 1) Generates QR codes in PNG, SVG, and ASCII formats with error correction and decodes QR codes from images. ## Dependencies - **zxing-core** (3.5.3) - QR code encoding and decoding engine - **zxing-javase** (3.5.3) - Java SE utilities for image-based QR code I/O ## Build and Run ```bash mvn clean compile exec:java -Dexec.mainClass="qrtool.QrTool" ``` Or build a JAR: ```bash mvn clean package java -jar target/qr-tool-1.0.0.jar ``` ## Features - QR code generation in PNG, SVG, and ASCII output formats - Configurable error correction levels (L, M, Q, H) - QR code decoding from image files using ZXing - Roundtrip encode/decode verification - Command-line interface
src/main/java/qrtool/QrTool.java
package qrtool;
/**
* QR Code Generator and Reader
*
* Generates QR codes in PNG, SVG, and ASCII formats with configurable error
* correction levels. Decodes QR codes from image files.
*
* Dependencies:
* - com.google.zxing:core 3.5.3
* - com.google.zxing:javase 3.5.3
*/
import com.google.zxing.*;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.client.j2se.MatrixToImageConfig;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
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.*;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.util.*;
public class QrTool {
// -----------------------------------------------------------------------
// Error correction level mapping
// -----------------------------------------------------------------------
private static final Map<String, ErrorCorrectionLevel> EC_LEVELS = new HashMap<>();
static {
EC_LEVELS.put("L", ErrorCorrectionLevel.L);
EC_LEVELS.put("M", ErrorCorrectionLevel.M);
EC_LEVELS.put("Q", ErrorCorrectionLevel.Q);
EC_LEVELS.put("H", ErrorCorrectionLevel.H);
}
// -----------------------------------------------------------------------
// QR Code generation
// -----------------------------------------------------------------------
/**
* Generate a BitMatrix for the given data and parameters.
*/
private static BitMatrix createQrMatrix(String data, String ecLevel,
int size) throws WriterException {
ErrorCorrectionLevel level = EC_LEVELS.getOrDefault(
ecLevel.toUpperCase(), ErrorCorrectionLevel.M);
Map<EncodeHintType, Object> hints = new EnumMap<>(EncodeHintType.class);
hints.put(EncodeHintType.ERROR_CORRECTION, level);
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
hints.put(EncodeHintType.MARGIN, 4);
QRCodeWriter writer = new QRCodeWriter();
return writer.encode(data, BarcodeFormat.QR_CODE, size, size, hints);
}
/**
* Generate a QR code and save it as a PNG image.
*
* @param data The text/URL to encode
* @param outputPath Destination file path
* @param ecLevel Error correction level (L, M, Q, H)
* @param size Image size in pixels
* @param fgColor Foreground color as ARGB int
* @param bgColor Background color as ARGB int
* @return The absolute path to the saved file
*/
public static String generatePng(String data, String outputPath,
String ecLevel, int size,
int fgColor, int bgColor)
throws WriterException, IOException {
BitMatrix matrix = createQrMatrix(data, ecLevel, size);
MatrixToImageConfig config = new MatrixToImageConfig(fgColor, bgColor);
Path path = FileSystems.getDefault().getPath(outputPath);
MatrixToImageWriter.writeToPath(matrix, "PNG", path, config);
return path.toAbsolutePath().toString();
}
/**
* Generate a QR code and save it as an SVG image.
*
* @param data The text/URL to encode
* @param outputPath Destination file path
* @param ecLevel Error correction level
* @param size Logical size in SVG units
* @return The absolute path to the saved file
*/
public static String generateSvg(String data, String outputPath,
String ecLevel, int size)
throws WriterException, IOException {
BitMatrix matrix = createQrMatrix(data, ecLevel, size);
int width = matrix.getWidth();
int height = matrix.getHeight();
StringBuilder sb = new StringBuilder();
sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
sb.append(String.format(
"<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 %d %d\">\n",
width, height));
sb.append(String.format(
" <rect width=\"%d\" height=\"%d\" fill=\"white\"/>\n",
width, height));
sb.append(" <path d=\"");
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
if (matrix.get(x, y)) {
sb.append(String.format("M%d,%dh1v1h-1z", x, y));
}
}
}
sb.append("\" fill=\"black\"/>\n");
sb.append("</svg>\n");
File outFile = new File(outputPath);
try (FileWriter fw = new FileWriter(outFile)) {
fw.write(sb.toString());
}
return outFile.getAbsolutePath();
}
/**
* Generate an ASCII representation of a QR code.
*
* @param data The text/URL to encode
* @param ecLevel Error correction level
* @param invert If true, swap dark/light characters
* @return Multi-line string of the ASCII QR code
*/
public static String generateAscii(String data, String ecLevel,
boolean invert)
throws WriterException {
BitMatrix matrix = createQrMatrix(data, ecLevel, 0);
int width = matrix.getWidth();
int height = matrix.getHeight();
String darkChar = invert ? " " : "\u2588\u2588";
String lightChar = invert ? "\u2588\u2588" : " ";
StringBuilder sb = new StringBuilder();
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
sb.append(matrix.get(x, y) ? darkChar : lightChar);
}
if (y < height - 1) {
sb.append("\n");
}
}
return sb.toString();
}
/**
* Generate a QR code as a BufferedImage in memory.
*/
public static BufferedImage generateImage(String data, String ecLevel,
int size, int fgColor,
int bgColor)
throws WriterException {
BitMatrix matrix = createQrMatrix(data, ecLevel, size);
MatrixToImageConfig config = new MatrixToImageConfig(fgColor, bgColor);
return MatrixToImageWriter.toBufferedImage(matrix, config);
}
// -----------------------------------------------------------------------
// QR Code decoding
// -----------------------------------------------------------------------
/**
* Decode QR code(s) from an image file.
*
* @param imagePath Path to the image file
* @return List of decoded results
*/
public static List<Map<String, Object>> decodeQr(String imagePath)
throws IOException, NotFoundException {
File imgFile = new File(imagePath);
if (!imgFile.exists()) {
throw new FileNotFoundException("Image not found: " + imagePath);
}
BufferedImage image = ImageIO.read(imgFile);
return decodeFromImage(image);
}
/**
* Decode QR code(s) from a BufferedImage.
*/
public static List<Map<String, Object>> decodeFromImage(BufferedImage image)
throws NotFoundException {
LuminanceSource source = new BufferedImageLuminanceSource(image);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
List<Map<String, Object>> results = new ArrayList<>();
// Try multi-decode first
try {
MultipleBarcodeReader multiReader = new GenericMultipleBarcodeReader(
new MultiFormatReader());
Result[] multiResults = multiReader.decodeMultiple(bitmap);
for (Result r : multiResults) {
if (r.getBarcodeFormat() == BarcodeFormat.QR_CODE) {
results.add(resultToMap(r));
}
}
} catch (NotFoundException e) {
// Fall back to single decode
}
if (results.isEmpty()) {
Map<DecodeHintType, Object> hints = new EnumMap<>(DecodeHintType.class);
hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
hints.put(DecodeHintType.POSSIBLE_FORMATS,
Collections.singletonList(BarcodeFormat.QR_CODE));
MultiFormatReader reader = new MultiFormatReader();
Result result = reader.decode(bitmap, hints);
results.add(resultToMap(result));
}
return results;
}
private static Map<String, Object> resultToMap(Result result) {
Map<String, Object> map = new LinkedHashMap<>();
map.put("data", result.getText());
map.put("format", result.getBarcodeFormat().name());
ResultPoint[] points = result.getResultPoints();
if (points != null) {
List<Map<String, Float>> pointsList = new ArrayList<>();
for (ResultPoint p : points) {
Map<String, Float> point = new LinkedHashMap<>();
point.put("x", p.getX());
point.put("y", p.getY());
pointsList.add(point);
}
map.put("points", pointsList);
}
return map;
}
// -----------------------------------------------------------------------
// Roundtrip verification
// -----------------------------------------------------------------------
/**
* Encode data into a QR code in-memory, decode it, and verify match.
*/
public static boolean roundtrip(String data, String ecLevel) {
try {
BufferedImage image = generateImage(data, ecLevel, 400,
0xFF000000, 0xFFFFFFFF);
LuminanceSource source = new BufferedImageLuminanceSource(image);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
Map<DecodeHintType, Object> hints = new EnumMap<>(DecodeHintType.class);
hints.put(DecodeHintType.POSSIBLE_FORMATS,
Collections.singletonList(BarcodeFormat.QR_CODE));
MultiFormatReader reader = new MultiFormatReader();
Result result = reader.decode(bitmap, hints);
return data.equals(result.getText());
} catch (Exception e) {
System.err.println("Roundtrip error: " + e.getMessage());
return false;
}
}
// -----------------------------------------------------------------------
// CLI
// -----------------------------------------------------------------------
private static void printUsage() {
System.out.println("QR Code Generator and Reader (ZXing)");
System.out.println();
System.out.println("Usage:");
System.out.println(" java qrtool.QrTool generate <data> [options]");
System.out.println(" java qrtool.QrTool decode <image>");
System.out.println(" java qrtool.QrTool roundtrip <data> [options]");
System.out.println();
System.out.println("Generate options:");
System.out.println(" -o, --output <path> Output file (default: qrcode.png)");
System.out.println(" -f, --format <fmt> png, svg, or ascii (default: png)");
System.out.println(" -e, --ec-level <lvl> L, M, Q, or H (default: M)");
System.out.println(" -s, --size <pixels> Image size (default: 400)");
System.out.println(" --invert Invert ASCII colours");
}
public static void main(String[] args) {
if (args.length < 1) {
printUsage();
return;
}
String command = args[0];
switch (command) {
case "generate":
handleGenerate(args);
break;
case "decode":
handleDecode(args);
break;
case "roundtrip":
handleRoundtrip(args);
break;
case "-h":
case "--help":
printUsage();
break;
default:
System.err.println("Unknown command: " + command);
printUsage();
System.exit(1);
}
}
private static void handleGenerate(String[] args) {
if (args.length < 2) {
System.err.println("Error: data argument required");
System.exit(1);
}
String data = args[1];
String output = "qrcode.png";
String format = "png";
String ecLevel = "M";
int size = 400;
boolean invert = false;
for (int i = 2; i < args.length; i++) {
switch (args[i]) {
case "-o": case "--output":
if (i + 1 < args.length) output = args[++i];
break;
case "-f": case "--format":
if (i + 1 < args.length) format = args[++i];
break;
case "-e": case "--ec-level":
if (i + 1 < args.length) ecLevel = args[++i];
break;
case "-s": case "--size":
if (i + 1 < args.length) size = Integer.parseInt(args[++i]);
break;
case "--invert":
invert = true;
break;
}
}
try {
switch (format.toLowerCase()) {
case "ascii":
System.out.println(generateAscii(data, ecLevel, invert));
break;
case "svg":
String svgPath = generateSvg(data, output, ecLevel, size);
System.out.println("SVG QR code saved to " + svgPath);
break;
default:
String pngPath = generatePng(data, output, ecLevel, size,
0xFF000000, 0xFFFFFFFF);
System.out.println("PNG QR code saved to " + pngPath);
break;
}
} catch (Exception e) {
System.err.println("Generation error: " + e.getMessage());
System.exit(1);
}
}
private static void handleDecode(String[] args) {
if (args.length < 2) {
System.err.println("Error: image path required");
System.exit(1);
}
try {
List<Map<String, Object>> results = decodeQr(args[1]);
if (results.isEmpty()) {
System.out.println("No QR codes found in the image.");
System.exit(1);
}
for (int i = 0; i < results.size(); i++) {
Map<String, Object> r = results.get(i);
System.out.printf("QR #%d:%n", i + 1);
System.out.printf(" Data: %s%n", r.get("data"));
System.out.printf(" Format: %s%n", r.get("format"));
System.out.printf(" Points: %s%n", r.get("points"));
}
} catch (Exception e) {
System.err.println("Decode error: " + e.getMessage());
System.exit(1);
}
}
private static void handleRoundtrip(String[] args) {
if (args.length < 2) {
System.err.println("Error: data argument required");
System.exit(1);
}
String data = args[1];
String ecLevel = "M";
for (int i = 2; i < args.length; i++) {
if ("-e".equals(args[i]) || "--ec-level".equals(args[i])) {
if (i + 1 < args.length) ecLevel = args[++i];
}
}
boolean ok = roundtrip(data, ecLevel);
if (ok) {
System.out.println("Roundtrip successful: decoded data matches original.");
} else {
System.out.println("Roundtrip FAILED: decoded data does not match.");
System.exit(1);
}
}
}