OpenPDF icon indicating copy to clipboard operation
OpenPDF copied to clipboard

QRCode support

Open marcoserafini2 opened this issue 3 years ago • 4 comments

It would be useful to add support also to the QR Code in addition to the 12 already supported Barcodes

marcoserafini2 avatar Jan 04 '23 13:01 marcoserafini2

Qrcode support would be much appreciated.

sdelamo avatar Jan 04 '24 07:01 sdelamo

Can we find existing code or a Java library to solve this QR code generation and copy/embed that inside OpenPDF?

https://github.com/topics/qr-code-generator?l=java

https://github.com/zxing/zxing

andreasrosdal avatar Jan 10 '24 06:01 andreasrosdal

This code generated by ChatGPT can be used for inspiration:

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;

public class QRCodeGenerator {

    public static void main(String[] args) {
        String qrCodeData = "https://www.example.com"; // Change this URL to the desired content
        String filePath = "generated_qrcode.png"; // Change this to the desired file path and name

        int size = 300; // Adjust the QR code size here
        try {
            BufferedImage image = createQRImage(qrCodeData, size);
            saveQRImage(image, filePath);
            System.out.println("QR Code generated successfully!");
        } catch (IOException e) {
            System.out.println("Error generating QR Code: " + e.getMessage());
        }
    }

    private static BufferedImage createQRImage(String qrCodeData, int size) {
        BufferedImage image = new BufferedImage(size, size, BufferedImage.TYPE_INT_RGB);
        Graphics2D graphics = image.createGraphics();

        graphics.setColor(Color.WHITE);
        graphics.fillRect(0, 0, size, size);
        graphics.setColor(Color.BLACK);

        int quietZone = 4; // Adjust the quiet zone size
        int qrCodeSize = size - 2 * quietZone;
        int scaleFactor = qrCodeSize / qrCodeData.length();

        try {
            int x = quietZone;
            int y = quietZone;

            for (int i = 0; i < qrCodeData.length(); i++) {
                if (qrCodeData.charAt(i) == '1') {
                    graphics.fillRect(x, y, scaleFactor, scaleFactor);
                }
                x += scaleFactor;
                if (x >= size - quietZone) {
                    x = quietZone;
                    y += scaleFactor;
                }
            }
        } finally {
            graphics.dispose();
        }

        return image;
    }

    private static void saveQRImage(BufferedImage image, String filePath) throws IOException {
        File file = new File(filePath);
        ImageIO.write(image, "png", file);
    }
}

andreasrosdal avatar Jan 10 '24 06:01 andreasrosdal

I ended up using:

ZXing with code such as:

private void generatePDF(OutputStream outputStream) throws IOException {
        try (Document document = new Document()) {
            PdfWriter.getInstance(document, outputStream);
            document.open();
            document.newPage();
            document.add(new Paragraph("Hello World"));
            String barcode = "4448423602139";
            int size = 200;
            generateQrCode(barcode, size, size).ifPresent(document::add);
        }
    }

    private Optional<Image> generateQrCode(String data, int height, int width)  {
        try {
        BitMatrix matrix = new MultiFormatWriter().encode(new String(data.getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8), BarcodeFormat.QR_CODE, width, height);
        BufferedImage qrImage = MatrixToImageWriter.toBufferedImage(matrix);
        return Optional.of(Image.getInstance(qrImage, null));
        } catch (WriterException | IOException e) {
            LOG.error("Error generating QR code", e);
        }
        return Optional.empty();
    }

I needed the following dependency:

    implementation("com.google.zxing:javase:3.5.3")

sdelamo avatar Feb 29 '24 16:02 sdelamo