Skip to content

Commit

Permalink
Add ZebraCrossing utility from Renarde
Browse files Browse the repository at this point in the history
  • Loading branch information
melloware committed Nov 1, 2024
1 parent 963de95 commit 9856b62
Show file tree
Hide file tree
Showing 2 changed files with 230 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@
*/
package io.quarkiverse.barcode.it;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

Expand All @@ -32,42 +31,35 @@
import org.eclipse.microprofile.openapi.annotations.media.Schema;
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

import io.quarkiverse.barcode.zxing.ZebraCrossing;

@Path("/zxing")
@ApplicationScoped
public class ZxingResource extends BaseImageResource {

@GET
@Path("qr/png")
@APIResponse(responseCode = "200", description = "Document downloaded", content = @Content(mediaType = MediaType.APPLICATION_OCTET_STREAM, schema = @Schema(type = SchemaType.STRING, format = "binary")))
public Response qrCodePng() throws IOException, WriterException {
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
// QR Code writer
QRCodeWriter qrCodeWriter = new QRCodeWriter();

// Set error correction level and encoding options
Map<EncodeHintType, Object> hints = new HashMap<>();
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
public Response qrCodePng() {
// Set error correction level and encoding options
Map<EncodeHintType, Object> hints = new HashMap<>();
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
hints.put(EncodeHintType.CHARACTER_SET, StandardCharsets.UTF_8.name());

int width = 300;
int height = 300;
int width = 300;
int height = 300;

// Generate QR Code as BitMatrix
BitMatrix bitMatrix = qrCodeWriter.encode("Quarkus Rocks!", BarcodeFormat.QR_CODE, width, height, hints);
// Generate QR Code as BitMatrix
BitMatrix bitMatrix = ZebraCrossing.qrCode("Quarkus Rocks!", width, height, hints);

// Generate PNG
MatrixToImageWriter.writeToStream(bitMatrix, "PNG", outputStream);
// Generate PNG
byte[] png = ZebraCrossing.barcodetoPng(bitMatrix);

// return the image
return buildImageResponse(outputStream.toByteArray(), PNG_MIME_TYPE, "zxing-code128.png");
}
// return the image
return buildImageResponse(png, PNG_MIME_TYPE, "zxing-code128.png");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
package io.quarkiverse.barcode.zxing;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Map;

import com.google.zxing.*;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.datamatrix.DataMatrixWriter;
import com.google.zxing.oned.*;
import com.google.zxing.qrcode.QRCodeWriter;

/**
* The {@code ZebraCrossing} class provides static methods for generating
* various types of barcodes using the ZXing library. Supported barcode formats
* include Code 128, Code 39, Code 93, EAN-13, EAN-8, UPC-A, UPC-E, QR Code,
* and Data Matrix. Each barcode type has two encoding methods:
* one that uses default encoding hints and another that accepts a custom
* {@code hints} map to allow for custom encoding parameters.
*
* <p>
* Usage examples:
* </p>
*
* <pre>{@code
* // Generate a Code 128 barcode with default encoding hints
* BitMatrix code128Matrix = ZebraCrossing.code128("example", 200, 100);
* String code128Img = ZebraCrossing.code128Img("example", 200, 100);
*
* // Generate a QR Code with custom encoding hints
* Map<EncodeHintType, Object> hints = Map.of(EncodeHintType.CHARACTER_SET, "UTF-8");
* BitMatrix qrCodeMatrix = ZebraCrossing.qrCode("example", 200, 200, hints);
* String qrCodeImg = ZebraCrossing.qrCodeImg("example", 200, 200);
* }</pre>
*
* <p>
* Each image generation method returns a data URI that can be embedded in
* HTML for direct display in web applications.
* </p>
*
* <p>
* For convenience, this class includes helper methods for converting
* {@code BitMatrix} objects to PNG images and encoding them as base64 data URIs.
* </p>
*
* <p>
* Note: By default, the character set used for encoding is UTF-8.
* </p>
*
* @see com.google.zxing.Writer
* @see com.google.zxing.common.BitMatrix
* @see com.google.zxing.EncodeHintType
* @see <a href="https://github.com/zxing/zxing">ZXing Project</a>
*/
public class ZebraCrossing {

private ZebraCrossing() {
// prevent instantiation
}

public static BitMatrix code128(String value, int width, int height) {
return code128(value, width, height, getHints());
}

public static BitMatrix code128(String value, int width, int height, Map<EncodeHintType, ?> hints) {
Code128Writer writer = new Code128Writer();
return writer.encode(value, BarcodeFormat.CODE_128, width, height, hints);
}

public static String code128Img(String value, int width, int height) {
return dataUriImg(code128(value, width, height));
}

public static BitMatrix code39(String value, int width, int height) {
return code39(value, width, height, getHints());
}

public static BitMatrix code39(String value, int width, int height, Map<EncodeHintType, ?> hints) {
Code39Writer writer = new Code39Writer();
return writer.encode(value, BarcodeFormat.CODE_39, width, height, hints);
}

public static String code39Img(String value, int width, int height) {
return dataUriImg(code39(value, width, height));
}

public static BitMatrix code93(String value, int width, int height) {
return code93(value, width, height, getHints());
}

public static BitMatrix code93(String value, int width, int height, Map<EncodeHintType, ?> hints) {
Code93Writer writer = new Code93Writer();
return writer.encode(value, BarcodeFormat.CODE_93, width, height, hints);
}

public static String code93Img(String value, int width, int height) {
return dataUriImg(code93(value, width, height));
}

public static BitMatrix ean13(String value, int width, int height) {
return ean13(value, width, height, getHints());
}

public static BitMatrix ean13(String value, int width, int height, Map<EncodeHintType, ?> hints) {
EAN13Writer writer = new EAN13Writer();
return writer.encode(value, BarcodeFormat.EAN_13, width, height, hints);
}

public static String ean13Img(String value, int width, int height) {
return dataUriImg(ean13(value, width, height));
}

public static BitMatrix ean8(String value, int width, int height) {
return ean8(value, width, height, getHints());
}

public static BitMatrix ean8(String value, int width, int height, Map<EncodeHintType, ?> hints) {
EAN8Writer writer = new EAN8Writer();
return writer.encode(value, BarcodeFormat.EAN_8, width, height, hints);
}

public static String ean8Img(String value, int width, int height) {
return dataUriImg(ean8(value, width, height));
}

public static BitMatrix upcA(String value, int width, int height) {
return upcA(value, width, height, getHints());
}

public static BitMatrix upcA(String value, int width, int height, Map<EncodeHintType, ?> hints) {
UPCAWriter writer = new UPCAWriter();
return writer.encode(value, BarcodeFormat.UPC_A, width, height, hints);
}

public static String upcAImg(String value, int width, int height) {
return dataUriImg(upcA(value, width, height));
}

public static BitMatrix upcE(String value, int width, int height) {
return upcE(value, width, height, getHints());
}

public static BitMatrix upcE(String value, int width, int height, Map<EncodeHintType, ?> hints) {
UPCEWriter writer = new UPCEWriter();
return writer.encode(value, BarcodeFormat.UPC_E, width, height, hints);
}

public static String upcEImg(String value, int width, int height) {
return dataUriImg(upcE(value, width, height));
}

public static BitMatrix qrCode(String value, int width, int height) {
return qrCode(value, width, height, getHints());
}

public static BitMatrix qrCode(String value, int width, int height, Map<EncodeHintType, ?> hints) {
QRCodeWriter writer = new QRCodeWriter();
try {
return writer.encode(value, BarcodeFormat.QR_CODE, width, height, hints);
} catch (WriterException e) {
throw new RuntimeException(e);
}
}

public static String qrCodeImg(String value, int width, int height) {
return dataUriImg(qrCode(value, width, height));
}

public static BitMatrix dataMatrix(String value, int width, int height) {
return dataMatrix(value, width, height, getHints());
}

public static BitMatrix dataMatrix(String value, int width, int height, Map<EncodeHintType, ?> hints) {
DataMatrixWriter writer = new DataMatrixWriter();
return writer.encode(value, BarcodeFormat.DATA_MATRIX, width, height, hints);
}

public static String dataMatrixImg(String value, int width, int height) {
return dataUriImg(dataMatrix(value, width, height));
}

public static String dataUriImg(BitMatrix encoded) {
return dataUriImg(base64ToDataUri(pngToBase64(barcodetoPng(encoded))));
}

public static byte[] barcodetoPng(BitMatrix encoded) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
MatrixToImageWriter.writeToStream(encoded, "png", out);
} catch (IOException e) {
throw new RuntimeException(e);
}
return out.toByteArray();
}

public static String pngToBase64(byte[] png) {
return Base64.getEncoder().encodeToString(png);
}

public static String base64ToDataUri(String base64) {
return "data:image/png;base64," + base64;
}

public static String dataUriImg(String dataUri) {
return "<img src='" + dataUri + "'/>";
}

private static Map<EncodeHintType, ?> getHints() {
return Map.of(EncodeHintType.CHARACTER_SET, StandardCharsets.UTF_8.name());
}
}

0 comments on commit 9856b62

Please sign in to comment.