Okapi Barcode is an open-source barcode generator written entirely in Java, supporting over 50 encoding standards, including all ISO standards. Okapi Barcode is based on Zint, an open-source barcode encoding library developed in C, and builds on the years of work that have been invested in that project.
- Australia Post variants:
- Standard Customer
- Reply Paid
- Routing
- Redirection
- Aztec Code
- Aztec Runes
- Channel Code
- Codabar
- Codablock F
- Code 11
- Code 128
- Code 16k
- Code 2 of 5 variants:
- Matrix 2 of 5
- Industrial 2 of 5
- IATA 2 of 5
- Datalogic 2 of 5
- Interleaved 2 of 5
- ITF-14
- Deutsche Post Leitcode
- Deutsche Post Identcode
- Code 32 (Italian Pharmacode)
- Code 3 of 9 (Code 39)
- Code 3 of 9 Extended (Code 39 Extended)
- Code 49
- Code 93
- Code One
- Data Matrix
- DPD Code
- Dutch Post KIX Code
- EAN variants:
- EAN-13
- EAN-8
- Grid Matrix
- GS1 Composite
- GS1 DataBar variants:
- GS1 DataBar
- GS1 DataBar Stacked
- GS1 DataBar Stacked Omnidirectional
- GS1 DataBar Expanded variants:
- GS1 DataBar Expanded
- GS1 DataBar Expanded Stacked
- GS1 DataBar Limited
- Japan Post
- Korea Post
- LOGMARS
- MaxiCode
- MSI (Modified Plessey)
- PDF417 variants:
- PDF417
- Truncated PDF417 (Compact PDF417)
- Macro PDF417
- Micro PDF417
- Pharmacode
- Pharmacode Two-Track
- Plessey (UK Plessey)
- POSTNET / PLANET
- QR Code
- Royal Mail 4 State (RM4SCC)
- Swiss QR Code
- Telepen variants:
- Telepen
- Telepen Numeric
- UPC variants:
- UPC-A
- UPC-E
- UPN QR
- USPS OneCode (Intelligent Mail)
Okapi Barcode JARs are available for download from Maven Central.
To generate barcode images in your own code using the Okapi Barcode library, use one of the symbology classes linked above:
- instantiate the barcode class,
- customize any relevant settings,
- invoke
setContent(String)
, and then - pass the barcode instance to one of the available renderers (Java 2D, PostScript, SVG)
Code128 barcode = new Code128();
barcode.setFontName("Monospaced");
barcode.setFontSize(16);
barcode.setModuleWidth(2);
barcode.setBarHeight(50);
barcode.setHumanReadableLocation(HumanReadableLocation.BOTTOM);
barcode.setContent("123456789");
int width = barcode.getWidth();
int height = barcode.getHeight();
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
Graphics2D g2d = image.createGraphics();
Java2DRenderer renderer = new Java2DRenderer(g2d, 1, Color.WHITE, Color.BLACK);
renderer.render(barcode);
ImageIO.write(image, "png", new File("code128.png"));
If you'd like to use Okapi Barcode on the Android platform, the easiest approach is to use the
SVG renderer to render your barcode
to SVG, and then use a library like AndroidSVG to
draw the resultant SVG image on an Android Bitmap
or Canvas
:
Code128 barcode = new Code128();
barcode.setFontName("Monospaced");
barcode.setFontSize(16);
barcode.setModuleWidth(2);
barcode.setBarHeight(50);
barcode.setHumanReadableLocation(HumanReadableLocation.BOTTOM);
barcode.setContent("123456789");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
SvgRenderer renderer = new SvgRenderer(stream, 1, Color.WHITE, Color.BLACK, true);
renderer.render(barcode);
String content = new String(stream.toByteArray(), StandardCharsets.UTF_8);
SVG svg = SVG.getFromString(content);
svg.renderToCanvas(canvas);
To use the Swing GUI, just run the OkapiUI class. The GUI allows you to explore the supported barcode symbologies and test them with different configurations and data.
gradlew check
: Compiles and runs all quality checks, including the unit tests.
gradlew fuzz
: Runs barcode encoding fuzz tests using Jazzer.
gradlew jar
: Builds the JAR file.
gradlew publish
: Deploys to Maven Central (requires a modified gradle.properties file).
- Codablock F: allow user to customize row height
- Codablock F: allow user to customize module width
- Codablock F: improve check digit calculation
- Codablock F: fix encodation bugs in various corner cases
- Add optional rotation parameter to all renderers
- MaxiCode: improve handling of partial and malformed postal codes (modes 2 and 3)
- Code 11: allow empty content, if user requests it
- Micro QR Code: allow empty content, if user requests it
- Micro QR Code: fix last data character ignored during encoding in some scenarios
- Update build toolchain from Java 17 to Java 21 (minimum target runtime remains Java 8)
- SVG and EPS output: round up canvas dimensions when using decimal magnification factor
- MaxiCode: reduce memory use during encoding
- QR Code: reduce encode time by about 25%
- QR Code: allow FNC1 escape sequences in user-provided content
- Code 39 Extended: allow empty content, if user requests it
- QR Code: allow empty content, if user requests it
- UPC/EAN: allow empty content, if user requests it
- Telepen: allow empty content, if user requests it
- Code 128: allow user to restrict the code sets used to encode data
- First reproducible build
- Aztec Code: allow user to restrict sizes to compact or normal Aztec sizes
- Add support for UPN QR
- Add support for DPD Code
- Add support for Swiss QR Code
- Add support for specifying ECI mode explicitly
- PDF417: add support for forcing byte compaction mode
- QR Code: add support for forcing byte compaction mode
- Code 39 Extended: allow customization of module width ratio
- PDF417: add support for automatic splitting of structured append symbols
- PDF417: allow user to request byte compaction
- QR Code: improved encoding performance and efficiency
- Code 128: further optimize data encoding in some scenarios
- QR Code: fix broken Kanji encoding in some corner cases (found via fuzzing)
- Data Matrix: fix encoding of trailing extended ASCII characters in TEXT/C40 mode (found via fuzzing)
- Add
OkapiInputException
andOkapiInternalException
, to distinguish user vs. library errors
- DataBar Expanded: various small fixes and cleanup
- Update minimum Java runtime requirement from Java 7 to Java 8
- Update build Java runtime from Java 8 to Java 17
- Channel Code: fix
NullPointerException
when channel count not specified - MaxiCode: fix handling of custom quiet zones when rendering via
Java2DRenderer
- Code 128: fix encoding of line feeds when combined with lowercase characters (found via fuzzing)
- Code 128: fix encoding of shifted characters which also use extended encoding (found via fuzzing)
- Code 128: never try to shift in or out of extended mode while in code set C (found via fuzzing)
- Code 128: always exit extended mode before switching to code set C (found via fuzzing)
- Data Matrix: fix incorrect encoding of single ASCII characters within X12 data (found via fuzzing)
- Refactor to remove most uses of AWT classes in core Okapi classes (for Android users)
- Rename
HumanReadableAlignment
toTextAlignment
, move it tographics
package (for Android users)
- GS1 Composite: avoid ArrayIndexOutOfBoundsException in some rare corner cases
- PDF417: add
setContent(byte[])
method for binary data - PDF417: when using structured append (Macro PDF417), place padding before control block, not after
- PDF417: fix auto-calculation of row count when data is very small and column count is specified
- PDF417: add support for segment count and file name Macro PDF417 optional fields
- Royal Mail 4-State: fix bug in check digit calculation
- MSI Plessey: allow empty content
- MSI Plessey: improve symbol configurability (module width ratio, check digit visibility)
- Add support for the original Plessey symbology (also known as UK Plessey)
- Improve build times
- Code 128: allow empty content
- All GS1 symbols: improve GS1 AI validations
- Data Matrix: allow use of GS as the GS1 separator
- Data Matrix: fix data too long to fit in symbol issue
- Data Matrix: add trailing data characters to debug logs
- POSTNET: improve symbol configurability (module width ratio, short and long height percentages)
- USPS OneCode: improve symbol configurability (module width ratio, short and long height percentages)