High quality QR Code generator library with comprehensive encoding options and absolute correctness
npx @tessl/cli install tessl/maven-io-nayuki--qrcodegen@1.8.0A high-quality Java library for generating QR Codes from text strings and byte arrays. This library provides absolute correctness, flexible options, and comprehensive support for all QR Code Model 2 specifications with optimal encoding algorithms.
pom.xml:
<dependency>
<groupId>io.nayuki</groupId>
<artifactId>qrcodegen</artifactId>
<version>1.8.0</version>
</dependency>import io.nayuki.qrcodegen.QrCode;
import io.nayuki.qrcodegen.QrSegment;For advanced features:
import io.nayuki.qrcodegen.QrSegmentAdvanced;
import io.nayuki.qrcodegen.DataTooLongException;import io.nayuki.qrcodegen.QrCode;
// Create QR Code from text
QrCode qr = QrCode.encodeText("Hello, World!", QrCode.Ecc.MEDIUM);
// Access the QR code properties
int size = qr.size; // Size in modules (21-177)
int version = qr.version; // Version number (1-40)
// Read individual modules
for (int y = 0; y < qr.size; y++) {
for (int x = 0; x < qr.size; x++) {
boolean isDark = qr.getModule(x, y);
// Use isDark to render the QR code
}
}import io.nayuki.qrcodegen.QrCode;
// Encode binary data
byte[] data = "Binary data example".getBytes("UTF-8");
QrCode qr = QrCode.encodeBinary(data, QrCode.Ecc.HIGH);import io.nayuki.qrcodegen.QrCode;
import io.nayuki.qrcodegen.QrSegment;
import java.util.List;
// Create optimized segments for mixed content
List<QrSegment> segments = QrSegment.makeSegments("ABC123");
QrCode qr = QrCode.encodeSegments(segments, QrCode.Ecc.MEDIUM);
// Manual segment creation with full control
segments = QrSegment.makeSegments("3141592653589793238462643383");
QrCode qr2 = QrCode.encodeSegments(
segments,
QrCode.Ecc.HIGH, // Error correction level
5, // Minimum version
5, // Maximum version
2, // Mask pattern (or -1 for auto)
false // Don't boost error correction
);The library provides a layered API design:
encodeText, encodeBinary) for common use casesencodeSegments) for custom data organizationKey components:
Core functionality for creating QR codes from various data types with automatic optimization.
// High-level text encoding
public static QrCode encodeText(
CharSequence text, // text to encode (Unicode supported)
Ecc ecl // error correction level (boostable)
)
// High-level binary encoding
public static QrCode encodeBinary(
byte[] data, // binary data to encode
Ecc ecl // error correction level (boostable)
)
// Mid-level segment encoding with automatic parameters
public static QrCode encodeSegments(
List<QrSegment> segs, // segments to encode
Ecc ecl // error correction level (boostable)
)
// Mid-level segment encoding with manual control
public static QrCode encodeSegments(
List<QrSegment> segs, // segments to encode (not null, not empty)
Ecc ecl, // error correction level (not null, boostable)
int minVersion, // minimum QR version (1 ≤ minVersion ≤ maxVersion ≤ 40)
int maxVersion, // maximum QR version (minVersion ≤ maxVersion ≤ 40)
int mask, // mask pattern (0-7 for fixed pattern, -1 for auto-select)
boolean boostEcl // boost ECC level if no version increase required
)
// Low-level constructor for complete control
public QrCode(
int ver, // version number (1-40)
Ecc ecl, // error correction level
byte[] dataCodewords, // data bytes (without ECC)
int msk // mask pattern (-1 for auto, 0-7 for fixed)
)Create and optimize data segments for efficient QR code encoding.
// Create segments from different data types
public static QrSegment makeBytes(byte[] data) // binary data
public static QrSegment makeNumeric(CharSequence digits) // digits 0-9 only
public static QrSegment makeAlphanumeric(CharSequence text) // 0-9,A-Z,space,$%*+-./:
public static List<QrSegment> makeSegments(CharSequence text) // auto-optimized segments
public static QrSegment makeEci(int assignVal) // ECI assignment number (0 ≤ assignVal < 1000000)
// Test segment encodability
public static boolean isNumeric(CharSequence text) // test for digits only
public static boolean isAlphanumeric(CharSequence text) // test for alphanumeric chars
// Manual segment construction
public QrSegment(
Mode md, // segment mode (not null)
int numCh, // character/byte count (0 ≤ numCh < 2^16 depending on version)
BitBuffer data // segment data bits (not null, cloned defensively)
)
// Access segment data
public BitBuffer getData() // returns defensive copySophisticated encoding optimization and Japanese kanji support.
// Optimal segment mode switching for minimal bit length
public static List<QrSegment> makeSegmentsOptimally(
CharSequence text, // text to encode (not null, Unicode supported)
QrCode.Ecc ecl, // error correction level (not null)
int minVersion, // minimum QR version (1 ≤ minVersion ≤ maxVersion ≤ 40)
int maxVersion // maximum QR version (minVersion ≤ maxVersion ≤ 40)
)
// Japanese kanji mode encoding
public static QrSegment makeKanji(CharSequence text) // kanji-encodable text only
public static boolean isEncodableAsKanji(CharSequence text) // test for kanji charsAccess QR code properties and module data for rendering.
// QR code properties
public final int version // Version number (1-40)
public final int size // Size in modules (21-177)
public final Ecc errorCorrectionLevel // Error correction level
public final int mask // Mask pattern (0-7)
// Module access
public boolean getModule(
int x, // x coordinate (0 to size-1)
int y // y coordinate (0 to size-1)
)
// Version constants - supported QR Code version range
public static final int MIN_VERSION = 1 // Minimum supported QR Code version (21×21 modules)
public static final int MAX_VERSION = 40 // Maximum supported QR Code version (177×177 modules)Low-level bit manipulation for custom segment creation.
// Bit buffer construction and access
public BitBuffer() // creates empty buffer (length 0)
public int bitLength() // returns current bit length (≥0)
public int getBit(int index) // returns bit at index (0 ≤ index < bitLength(), returns 0 or 1)
// Bit buffer modification
public void appendBits(
int val, // value to append (0 ≤ val < 2^len)
int len // number of low-order bits (0 ≤ len ≤ 31)
)
public void appendData(BitBuffer bb) // append another buffer's bits (bb not null)
public BitBuffer clone() // create defensive copypublic enum Ecc {
LOW, // ~7% error tolerance, format bits: 1
MEDIUM, // ~15% error tolerance, format bits: 0
QUARTILE, // ~25% error tolerance, format bits: 3
HIGH // ~30% error tolerance, format bits: 2
}public enum Mode {
NUMERIC, // Digits 0-9 only
ALPHANUMERIC, // 0-9, A-Z, space, $%*+-./:
BYTE, // Arbitrary binary data
KANJI, // Japanese kanji characters
ECI // Extended Channel Interpretation
}public class DataTooLongException extends IllegalArgumentException {
public DataTooLongException()
public DataTooLongException(String msg)
}// Automatically optimized for numeric content
QrCode qr = QrCode.encodeText("1234567890", QrCode.Ecc.LOW);
// Manual numeric segment
QrSegment numericSeg = QrSegment.makeNumeric("1234567890");
List<QrSegment> segs = Arrays.asList(numericSeg);
QrCode qr2 = QrCode.encodeSegments(segs, QrCode.Ecc.LOW);// Automatic mode switching for optimal encoding
String mixedData = "ABC123def456";
List<QrSegment> segments = QrSegmentAdvanced.makeSegmentsOptimally(
mixedData,
QrCode.Ecc.MEDIUM,
1,
40
);
QrCode qr = QrCode.encodeSegments(segments, QrCode.Ecc.MEDIUM);List<QrSegment> segments = QrSegment.makeSegments("Controlled encoding");
QrCode qr = QrCode.encodeSegments(
segments,
QrCode.Ecc.QUARTILE,
10, // Minimum version 10
15, // Maximum version 15
4, // Use mask pattern 4
true // Allow error correction boosting
);import java.nio.charset.StandardCharsets;
// Binary data with ECI for character set identification
List<QrSegment> segments = new ArrayList<>();
segments.add(QrSegment.makeEci(26)); // UTF-8 ECI assignment
segments.add(QrSegment.makeBytes("日本語".getBytes(StandardCharsets.UTF_8)));
QrCode qr = QrCode.encodeSegments(segments, QrCode.Ecc.HIGH);// Basic error handling for text encoding
try {
String longText = "Very long text that might not fit in any QR code version...";
QrCode qr = QrCode.encodeText(longText, QrCode.Ecc.LOW);
} catch (DataTooLongException e) {
System.err.println("Text too long: " + e.getMessage());
// Solutions: reduce text, use lower error correction, or split into multiple codes
}
// Error handling with version constraints
try {
List<QrSegment> segments = QrSegment.makeSegments("Medium length text");
QrCode qr = QrCode.encodeSegments(segments, QrCode.Ecc.HIGH, 1, 10, -1, false);
} catch (DataTooLongException e) {
System.err.println("Data doesn't fit in versions 1-10 at HIGH error correction");
// Solutions: increase maxVersion, reduce error correction level, or optimize segments
}
// Advanced error handling with fallback strategies
String data = "Text to encode with fallback strategies";
QrCode qr = null;
// Try HIGH error correction first
try {
qr = QrCode.encodeText(data, QrCode.Ecc.HIGH);
} catch (DataTooLongException e) {
try {
// Fallback to MEDIUM error correction
qr = QrCode.encodeText(data, QrCode.Ecc.MEDIUM);
} catch (DataTooLongException e2) {
try {
// Final fallback to LOW error correction
qr = QrCode.encodeText(data, QrCode.Ecc.LOW);
} catch (DataTooLongException e3) {
System.err.println("Data too long even for LOW error correction");
// Must reduce data size or split into multiple QR codes
}
}
}
// Parameter validation examples
try {
// Invalid version range will throw IllegalArgumentException
List<QrSegment> segs = QrSegment.makeSegments("test");
QrCode qr = QrCode.encodeSegments(segs, QrCode.Ecc.MEDIUM, 5, 3, -1, false); // minVersion > maxVersion
} catch (IllegalArgumentException e) {
System.err.println("Invalid parameters: " + e.getMessage());
}
try {
// Invalid mask pattern will throw IllegalArgumentException
List<QrSegment> segs = QrSegment.makeSegments("test");
QrCode qr = QrCode.encodeSegments(segs, QrCode.Ecc.MEDIUM, 1, 40, 8, false); // mask > 7
} catch (IllegalArgumentException e) {
System.err.println("Invalid mask pattern: " + e.getMessage());
}