DEV Community

Juan Sedano
Juan Sedano

Posted on • Originally published at jsedano.dev on

Simple web QR maker with zxing and Thymeleaf

Encode text into QR Code with zxing and display it using thymeleaf. Live demo here.

You can find the complete code for this here.

This is the method to encode a String into an image, and then encode the image into a base 64 String that represents the png, based around the code in this tutorial.

QRCreator.java

  private String unsafeCreateQRImage(String qrCodeText, int size)
      throws WriterException, IOException {
    // Create the ByteMatrix for the QR-Code that encodes the given String
    Hashtable<EncodeHintType, ErrorCorrectionLevel> hintMap = new Hashtable<>();
    hintMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
    BitMatrix byteMatrix =
        qrCodeWriter.encode(qrCodeText, BarcodeFormat.QR_CODE, size, size, hintMap);
    // Make the BufferedImage that are to hold the QRCode
    int matrixWidth = byteMatrix.getWidth();
    BufferedImage image = new BufferedImage(matrixWidth, matrixWidth, BufferedImage.TYPE_INT_RGB);
    image.createGraphics();

    Graphics2D graphics = (Graphics2D) image.getGraphics();
    graphics.setColor(Color.WHITE);
    graphics.fillRect(0, 0, matrixWidth, matrixWidth);
    // Paint and save the image using the ByteMatrix
    graphics.setColor(Color.BLACK);

    for (int i = 0; i < matrixWidth; i++) {
      for (int j = 0; j < matrixWidth; j++) {
        if (byteMatrix.get(i, j)) {
          graphics.fillRect(i, j, 1, 1);
        }
      }
    }
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    ImageIO.write(image, "png", bos);
    byte[] imageBytes = bos.toByteArray();

    Base64.Encoder encoder = Base64.getEncoder();
    return encoder.encodeToString(imageBytes);
  }
Enter fullscreen mode Exit fullscreen mode

Use this on the controller for the thymeleaf templates.

SimpleQRController.java

  @RequestMapping("/")
  public String newRandomSelect(Model model) {
    model.addAttribute("textAndQRImage", new TextAndQRImage());
    return "inputQR";
  }

  @RequestMapping("/show")
  public String showQR(Model model, TextAndQRImage textAndQRImage, HttpSession session) {
    if (Objects.isNull(textAndQRImage.getText()) || textAndQRImage.getText().isEmpty()) {
      return "redirect:/simpleqr/";
    }
    String qrImage = qrCreator.createQRImage(textAndQRImage.getText(), 800);
    if (Objects.isNull(qrImage) || qrImage.isEmpty()) {
      return "redirect:/simpleqr/";
    }
    textAndQRImage.setText(textAndQRImage.getText());
    textAndQRImage.setBase64Image(qrCreator.createQRImage(textAndQRImage.getText(), 800));

    model.addAttribute("textAndQRImage", textAndQRImage);
    return "showQR";
  }
Enter fullscreen mode Exit fullscreen mode

Part of inputQR.html that asks for the text that will be encoded into a QR code.

    <form action="/simpleqr/show" th:object="${textAndQRImage}" method="POST">

        <input type="text" placeholder="input text here" th:field="*{text}">

        <button type="submit">Generate QR</button>
    </form>
Enter fullscreen mode Exit fullscreen mode

And then we display the QR code in showQR.html template.

<body>

    <div>
        <img class="img-responsive" th:src="@{'data:image/png;base64,'+${textAndQRImage.base64Image}}"/>
    </div>

<h2 th:text=${textAndQRImage.text}></h2>
</body>
Enter fullscreen mode Exit fullscreen mode

Download the complete code for this here: simple-qr code. Live demo on: simple-qr live.

Top comments (0)