Java had a QR code creation library called QRGen that wrapped ZXing nicely, so I tried it.

Introduction

Speaking of libraries that create QR code in Java, it seems that Google's ZXing is often introduced. When I actually used it, I thought that I was a little worried that the source code would look like a relatively low layer.

Roughly written, it looks like this.

Source code for generating a QR image using ZXing


BitMatrix matrix = new QRCodeWriter().encode(
    "https://qiita.com/nimzo6689", BarcodeFormat.QR_CODE, 320, 320
);
BufferedImage qrCodeImage = MatrixToImageWriter.toBufferedImage(matrix);
ImageIO.write(qrCodeImage, "png", Files.newOutputStream(Paths.get("qrcode.png ")));

However, in most cases, it becomes more complicated in reality. For example, adjust the margins, change the character code, change to a different color instead of black and white, and so on. Also, I think there are cases where you want to output as an SVG file so that the image quality does not deteriorate even if you stretch it.

If you try to achieve the above, you will have more code with lower layers, If you use a library called QRGen created by wrapping ZXing, I recently learned that you can easily write a process to generate a QR image with a method chain. I tried to summarize how to use it.

Installation method

Basically as usual for package management tools such as Maven and Gradle It can be used by adding a dependency. However, there is one point to note, version 2.1.0 or later, We haven't released it to Maven Central It is necessary to add jitpack.io to the repository.

As it is on the official page, it is as follows in Gradle.

build.gradle


apply plugin: 'java'

sourceCompatibility = 1.12

repositories {
    maven {
        url "https://jitpack.io"
    }
}

dependencies {
    //When using with Java SE. On Android, the artifactId will be android.
    compile 'com.github.kenglxn.QRGen:javase:2.6.0'
}

With ZXing, you need to write core and javase, or android and two dependencies, With QRGen, you only need one, so you can enjoy it a little.

Example of use

I will post the source code I tried locally later. As the name suggests, QRGen is a dedicated library for generating QR codes, so It seems that you need to use ZXing's API if you want to scan.

The code posted in this article has been verified in the following environment.

Windows10 Pro, Java12(AdoptOpenJDK with HotSpot), IntelliJ IDEA 2019

The sample code in the article omits the import statement etc., so if you want to check the entire file, please refer to Gist.

Also, make sure that the generated QR image can be read by the Android app here. did.

Create and output a File object

First, how to create it with a File object.

Since QRCode # file creates an image file called QRCode.png in the temp directory, It is moving to the path where you want to output it.

I specified REPLACE_EXISTING so that I can write to the same file name as many times as I want.

QRGenToFile.java


File qrCode = QRCode.from("https://qiita.com/nimzo6689").file();
Files.copy(qrCode.toPath(), Paths.get("qrcode.png "), StandardCopyOption.REPLACE_EXISTING);

It has the same content as the sample code written at the beginning, but it is considerably simpler. You don't even have to know the ZXing API, which makes it easier to implement and easier to read.

Here is the QR image that was actually generated. If you don't specify any size, it seems to be 125x125.

qrcode.png

Generate and output ByteArrayOutputStream object

Next is how to create a ByteArrayOutputStream object.

QRGenToBaos.java


try (ByteArrayOutputStream qrCode = QRCode.from("https://qiita.com/nimzo6689").stream();
        OutputStream outputStream = Files.newOutputStream(Paths.get("qrcode.png "))) {

    qrCode.writeTo(outputStream);
    qrCode.flush();
}

The amount of code will be larger than that of QRCode # file, For example, ʻImageIO.read (new ByteArrayInputStream (qrCode.toByteArray ())) This seems to be useful when you want to generateBufferedImage` and do some image processing.

Also, I don't create a temp file, so the performance seems to be better.

Output to a generated OutputStream object

QRCode # stream was creating a new OutputStream, If you want to write a QR image to an output stream that has already been generated, you can use QRCode # writeTo.

QRGenToExistingOs.java


try (OutputStream os = Files.newOutputStream(Paths.get("qrcode.png "))) {
    QRCode.from("https://qiita.com/nimzo6689").writeTo(os);
    os.flush();
}

It requires less description than QRCode # stream.

Output by specifying various setting values

You can specify the image format, size, and color of the generated QR image. In addition, the settings specified in ʻEncodeHintType` in ZXing can also be set via the QRCode object.

QRGenWithHint.java


File qrCode = QRCode.from("https://qiita.com/nimzo6689")
        .to(ImageType.GIF)
        .withSize(320, 320)
        .withColor(0xFF6876B4, 0xFFF7F4F7)
        .withCharset("UTF-8")
        .withErrorCorrection(ErrorCorrectionLevel.L)
        .withHint(EncodeHintType.MARGIN, 2)
        .file();

Files.copy(qrCode.toPath(), Paths.get("qrcode.gif"), StandardCopyOption.REPLACE_EXISTING);

The value specified by withColor is in the format of transparency (2 bytes) + RGB (6 bytes).

The generated QR image is here.

qrcode.gif

Output as svg file

SVG conversion is only available for Java SE. Android is not available, but instead you can display the QR image in ImageView without file generation It seems that QRCode # bitmap is available. (Not verified this time)

QRGenToSvg.java


File qrCode = QRCode.from("https://qiita.com/nimzo6689").svg();
Files.copy(qrCode.toPath(), Paths.get("qrcode.svg"), StandardCopyOption.REPLACE_EXISTING);

The generated qrcode.svg will render properly when opened in Chrome etc.

When you are concerned about the image quality of QR images or when you want to stretch and print on large paper It's helpful because you don't have to prepare a large QR image.

Try different schemas

QR images are used for email addresses, location information, Wifi, etc. in addition to URLs, There are also some Schema objects that hold information for each of these data formats.

The README seems to support a total of 16 schemas, Looking at the source code, it seems that there are actually a few more. There is also KddiAu. ~~ Too high consciousness! ~~

Url schema

A schema that holds the URL of a web page. You can store http or a character string starting with https.

I don't think it's necessary to feed QRCode :: from via this object.

QRGenForUrl.java


Url url = Url.parse("https://qiita.com/nimzo6689");
File qrCode = QRCode.from(url).file();
Files.copy(qrCode.toPath(), Paths.get("qrcode.png "), StandardCopyOption.REPLACE_EXISTING);

Email schema

A schema that holds email addresses. You can store a string in the format mailto: email address.

For the time being, you can write new EMail ("mailto: [email protected]"), but In this case, verification processing such as whether it is a character string starting with mailto: is not performed, so Basically, I think it is appropriate to use ʻEMail :: parse`.

QRGenForEmail.java


EMail email = EMail.parse("mailto:[email protected]");
File qrCode = QRCode.from(email).file();
Files.copy(qrCode.toPath(), Paths.get("qrcode.png "), StandardCopyOption.REPLACE_EXISTING);

When I selected Gmail as the application to read and start, the email address embedded in the QR image was entered in To.

GeoInfo Schema

A schema that holds location information. You can store strings in the format geo: latitude, longitude.

QR images are generally used when you want to access web information from stores, etc., rather than distributing it on the website. It's hard to imagine a scene where the QR image of location information is used. I'm curious about how to use it.

QRGenForGeoInfo.java


GeoInfo geoInfo = GeoInfo.parse("geo:35.6761775,139.7173954");
File qrCode = QRCode.from(geoInfo).file();
Files.copy(qrCode.toPath(), Paths.get("qrcode.png "), StandardCopyOption.REPLACE_EXISTING);

In the QR code reader used in the verification, the "Display map" and "Search route" menus are displayed, and If you select "Display map", the map around the location information will be displayed. If you select "Search route", the route from your current location to the relevant location is displayed on Google Map.

in conclusion

It would be nice if the logo image could be placed in the center in a good way.

Recommended Posts

Java had a QR code creation library called QRGen that wrapped ZXing nicely, so I tried it.
[Android] A story that stumbled when introducing ZXing, a QR code function library
I had a hard time doing Java multithreading from scratch, so organize it
7 things I want you to keep so that it doesn't become a fucking code
Java SE 13 (JSR388) has been released so I tried it
I tried Tribuo published by Oracle. Tribuo --A Java prediction library (v4.0)
I tried learning Java with a series that beginners can understand clearly