https://github.com/aytchell/qrgen
A small java lib to generate QR codes
https://github.com/aytchell/qrgen
Last synced: 6 months ago
JSON representation
A small java lib to generate QR codes
- Host: GitHub
- URL: https://github.com/aytchell/qrgen
- Owner: aytchell
- License: apache-2.0
- Created: 2022-05-10T15:52:59.000Z (about 4 years ago)
- Default Branch: main
- Last Pushed: 2025-04-09T14:58:12.000Z (about 1 year ago)
- Last Synced: 2025-07-18T13:31:17.786Z (12 months ago)
- Language: Java
- Size: 343 KB
- Stars: 15
- Watchers: 1
- Forks: 4
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: Changelog.md
- License: LICENSE
Awesome Lists containing this project
README
# QR code generator
This library provides a class which is capable of generating QR codes. It is
a layer on top of the [ZXing](https://github.com/zxing/zxing) generator
which does the heavily lifting of actually computing the dot matrix. This
lib then adds the functionality to make image files.
This lib is inspired by [QRGen](http://kenglxn.github.io/QRGen/).
But since I'd like to have some structural changes plus more variations when
rendering the QR code, I wrote this new lib instead. The main
differences to QRGen are:
- you can configure a QrGenerator and then generate multiple QR codes from
it instead of repeating the configuration for each QR code
- this lib can overlay a logo over the QR code
- the 'pixels' of the code can be drawn with different styles
- you can select from a set of different styles for the three markers (the
big rectangles in the corners)
- no leaking of ZXing provided types
- no support for Android thus only one lib (instead of "core + javase + android")
## Table of contents
* [Introduction](#introduction)
* [Maven](#maven)
* [Configuration](#configuration)
* [Output file type](#conf_filetype)
* [Size and margin of the code](#conf_size)
* [Used colors](#conf_colors)
* [Error correction level](#conf_error)
* [Logo overlay](#conf_logo)
* [Styling](#conf_styling)
* [... the pixels](#conf_styling_pixels)
* [... the markers](#conf_styling_markers)
* [Character set of the encoded message](#conf_charset)
* [Actually writing the QR code](#write)
* [License](#license)
When starting with class `QrGenerator` usage of this lib is quite
self-explanatory (there's also javadoc available):
```java
final QrGenerator generator = new QrGenerator()
.withSize(300, 300)
.withMargin(3)
.as(ImageType.PNG)
.withErrorCorrection(ErrorCorrectionLevel.Q);
final Path img = generator
.writeToTmpFile("Hello, World!");
```
This library has a `modules-info.java` so it can be used as a Java 9 (Jigsaw)
module.
```xml
com.github.aytchell
qrgen
3.0.0
```
## Gradle
Groovy syntax:
```groovy
implementation 'com.github.aytchell:qrgen:3.0.0'
```
Kotlin syntax
```kotlin
implementation("com.github.aytchell:qrgen:3.0.0")
```
This section lists the possible configurations for the created QR codes. The
method calls to configure the generator can be chained and the resulting
configuration is collected by the instance. So to make things easier all
examples build on the same instance of `QrGenerator`.
```java
final QrGenerator generator = new QrGenerator();
```
The file format of the resulting QR code image can be selected to be
`png`, `gif`, `bmp` or `jpeg`:
```java
generator.as(ImageType.PNG);
```
### Size and margin of the code
The size of the resulting image (in pixels) can be configured as well
as a "quiet zone" around the code. This margin is an aid for QR code
scanners to easier distinguished the code from the surrounding environment.
The unit of the parameter for the margin's size is "number of dots used in
the QR code" so the actual size of the margin in pixels depends on the size
of the complete image as well as on the complexity of the QR code.
```java
generator
.withSize(300, 300)
.withMargin(3);
```
Usually QR codes are displayed in black and white as this gives the best
contrast and thus help a scanner in reading it. But there might be times,
when you want to have different colors.
The trivial variant is to set no colors at all. Then the lib will fall back to
the usual black/white pattern. The next level is to choose a color for
'the background' and another color for 'the pixels':
```java
final RgbValue daffodil = new RgbValue(0xff, 0xff, 0x31);
final RgbValue oxfordBlue = new RgbValue(0x00, 0x21, 0x47);
generator.withColors(daffodil, oxfordBlue);
```
Finally, it is possible to use up to four different colors:
- the background color (which is usually white)
- the "active parts" of the code (which form 'the pixels' in the mid of the code)
- the outer part of the three markers and
- the inner part of the three markers

However, you should choose such colors which provide a sufficient contrast.
Otherwise, it might get difficult for QR code scanners to read the code.
```java
final RgbValue white = new RgbValue(0xffffff);
final RgbValue alloyOrange = new RgbValue(196, 98, 16);
final RgbValue alabamaCrimson = new RgbValue(0xaf, 0x00, 0x2a);
final RgbValue black = new RgbValue(0x0);
generator.withColors(
black, // 'pixel' color
white, // background color
alloyOrange, // outer marker color
alabamaCrimson); // inner marker color
```
There's also a version with three parameters where the third color is used
for the complete markers' structure.
As the examples show, an RGB color value can be constructed with the three
parts separated as well as with one single raw integer value. Along with
the `RgbValue` there are some more possible color representations:
- `ArgbValue` — an RGB value with a leading alpha channel
- `RgbaValue` — same with the alpha channel given at the end
- `HslValue` — a color given via hue, saturation and lightness
- `HslaValue` — an HSL color value with an extra alpha channel
(Note that only `PNG` and `GIF` output image formats support alpha values.)
If you plan to put a logo onto your generated QR code or you're printing it
and the code gets dirty or damaged then information is lost and scanners
might not be able to correctly scan the code.
To circumvent this kind of problem the information encoded into the QR code
can be stored with different degrees of redundancy. The higher the level of
redundancy the better a scanner will be able to read a damaged or covered QR
code but this also means that the QR code becomes more dense ("more pixels").
In the end there is no simple algorithm which level to take but it depends on
the scenario how you want to use the QR code.
The specified levels are
- L - error correction rate of approximately 7%
- M - error correction rate of approximately 15%
- Q - error correction rate of approximately 25%
- H - error correction rate of approximately 30%
```java
generator.withErrorCorrection(ErrorCorrectionLevel.Q)
```
The generator is able to overlay the QR code with a centered logo. The file
format of the logo can be any of `gif`, `png`, `bmp` or `jpeg`. Alpha channel
is respected if the file format supports it.
Note however that the lib does not scale the logo to "fit" (whatever that
means); the logo will cover information from the QR code and increasing the
error correction level should be considered.
It's up to the caller to ensure that the QR code can be read with the
logo above it.
```java
try (final InputStream logo =
QrCodeExample.class.getResourceAsStream("github_logo.png")) {
// in real code check for null ...
generator.withLogo(logo);
}
final Path img = generator
.writeToTmpFile("Hello, Github!");
```


It is possible to change the appearance of 'the pixels' used to render the QR
code as well as the appearance of the three markers. Most QR code scanners
should be able to handle these shapes but keep in mind that you're diverging
from 'specified appearance'.
It is possible to change the style of the individual pixels used to render
the QR code. Currently, there are eight different styles available:
- `RECTANGLES` — The "standard" styling with rectangular pixels "touching" each other
- `SMALL_RECTANGLES` — A styling with smaller pixels so that a white grid between them appears
- `DOTS` — Dots instead of rectangles
- `ROUND_CORNERS` — rectangular pixels but with rounded corners
- `ROWS` — a style that makes the pixels appear like rows with Morse-code-like lines
- `COLUMNS` — a similar style but with columns instead of rows
- `SNAKES` — connected pixels with 'snakes-like' heads when there's no neighbor
- `WATER` — connected pixels which behave like adhesion of water surfaces
```java
final Path img = generator
.withPixelStyle(PixelStyle.DOTS)
.writeToTmpFile("Hello, Github!");
```
RECTANGLES
SMALL_RECTANGLES
DOTS
ROUND_CORNERS




ROWS
COLUMNS
SNAKES
WATER




It's also possible to change the styling of the three big markers.
Currently, there are nine different styles to chose from:
- `RECTANGLES` — the 'normal' rectangular markers
- `ROUND_CORNERS` — like `RECTANGLES` but with rounded corners
- `CIRCLES` — circles instead of rectangles
- `DROP_IN` — raindrops appearing to fall toward the inside of the code
- `DROP_OUT` — raindrops appearing to fall toward the outside of the code
- `ROUND_IN` — rectangular marker with the inner edge being rounded
- `ROUND_OUT` — rectangular marker with the outer edge being rounded
- `EDGE_IN` — like `ROUND_CORNERS` but the inner edge is a sharp one
- `EDGE_OUT` — as above but the outer edge is sharp
RECTANGLES
ROUND_CORNERS
CIRCLES
DROP_IN
DROP_OUT





ROUND_IN
ROUND_OUT
EDGE_IN
EDGE_OUT




### Character set of the encoded message
A QR code encode strings and to be more precise: a series of bytes. And at
this point we're entering the wide area of character encodings. You can
configure the character encoding which should be used when converting the
given payload to bytes.
In most cases UTF-8 (which is the default when not setting any character set)
will be perfectly OK.
```java
generator.withCharset(StandardCharsets.UTF_8);
```
## Actually writing the QR code
Once you've configured the QR code generator you can use it to write QR
codes. The method to write a payload to a QR code image file does not change
the state of the generator instance. So you can reuse the same generator
instance to write as many QR Code as you like (with different payloads).
```java
final Path img_1 = generator
.writeToTmpFile("Hello, World!");
final Path img_2 = generator
.writeToTmpFile("Hello again");
final Path img_3 = generator
.writeToTmpFile("Anybody out there?");
```
Note that the returned file will be created in the system's tmp folder with
the "delete on exit" flag set. The method does not change access permissions
of the created file so most probably (depending on the JRE and the OS) it will
be readable to anyone with access to the system.
Apache 2.0 License
Created and maintained by [Hannes Lerchl](mailto:hannes.lerchl@googlemail.com)
Feel free to send in pull requests. Please also add unit tests and adapt the
README if appropriate.