LibrePDF / OpenPDF

OpenPDF is a free Java library for creating and editing PDF files, with a LGPL and MPL open source license. OpenPDF is based on a fork of iText. We welcome contributions from other developers. Please feel free to submit pull-requests and bugreports to this GitHub repository.
Other
3.61k stars 597 forks source link

iTextPdf 5.x class BarcodeQRCode missing in OpenPdf report? #1160

Open ctoabidmaqbool1 opened 6 months ago

ctoabidmaqbool1 commented 6 months ago

Hi! I am CTO Abid Maqbool from Maqbool Solutions (SMC-Pvt) Ltd. an IT Company & Computer Software Houser, Pakistan!

I was using iText Pdf 5.x in my projects, as it is very old one and for the case of 7.x I can't use due to license issue.

So I am trying to switch to foked version Open Pdf 2.x, which is still active and latest one!

I have 100+ reports in old itextpdf 5, after switching to OpenPdf I foud that not major chaned, just imports changes!

  1. com.itextpdf.text. -> com.lowagie.text.
  2. com.itextpdf.text.pdf. -> com.lowagie.text.pdf.
  3. com.itextpdf.text.BaseColor -> java.awt.Color

The problem is I am not finind any related class in OpdfPdf for BarcodeQRCode, how to fix the issue?

com.itextpdf.text.pdf.BarcodeQRCode barcodeQRCode = new com.itextpdf.text.pdf.BarcodeQRCode(fbrInvoiceNo, 100, 100, null);
Image imgQRCode = barcodeQRCode.getImage();

PdfPCell pCellQrCode = new PdfPCell(imgQRCode);
pCellQrCode.setHorizontalAlignment(Element.ALIGN_CENTER);
pCellQrCode.setVerticalAlignment(Element.ALIGN_MIDDLE);
pCellQrCode.setRowspan(2);
pdfTableFBR.addCell(pCellQrCode);

Question: Is latest version of OpenPDF 2.0.2 is better then iTextPdf version 5.5.13.3 in all cases!

Note; iText 7.x is not an option, as some of it's features are Paid, e.g. for Arabic / Urdu language support!

ctoabidmaqbool commented 6 months ago

Hi! Someone was provide me very nice response / answer, which was a lot helpfull, I i think this is removed, why?

andreasrosdal commented 6 months ago

Hello! OpenPDF 2.0.2 is possibly the best PDF library for Java with a LGPL and MPL license.

See: https://github.com/zxing/zxing or find some other Java QR code library.

BarcodeQRCode was added in itext 5.0.2, while OpenPDF is a fork of iText 4 a long time ago. https://github.com/itext/itextpdf/blob/master/itext/src/main/java/com/itextpdf/text/pdf/BarcodeQRCode.java

ctoabidmaqbool commented 6 months ago

Hi! I have copied iTextPDF -> BarcodeQRCode and do changes what are required!

and implement here: OpenPDF\openpdf\src\main\java\com\lowagie\text\pdf\BarcodeQRCode.java

Note: It solve my problme, currently, but it will be more better, if this class official suported and implemented in OpenPDF Library, please!

package com.lowagie.text.pdf;

import java.awt.Color;
import java.awt.image.MemoryImageSource;
import java.util.Map;

import com.lowagie.text.BadElementException;
import com.lowagie.text.ExceptionConverter;
import com.lowagie.text.Image;
import com.lowagie.text.pdf.codec.CCITTG4Encoder;
import com.lowagie.text.Rectangle;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.EncodeHintType;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.WriterException;

public class BarcodeQRCode {

    private final BitMatrix bm;

    public BarcodeQRCode(String content, int width, int height, Map<EncodeHintType, Object> hints) {
        try {
            QRCodeWriter qc = new QRCodeWriter();
            bm = qc.encode(content, BarcodeFormat.QR_CODE, width, height, hints);
        } catch (WriterException ex) {
            throw new ExceptionConverter(ex);
        }
    }

    private byte[] getBitMatrix() {
        int width = bm.getWidth();
        int height = bm.getHeight();
        int stride = (width + 7) / 8;
        byte[] b = new byte[stride * height];
        for (int y = 0; y < height; ++y) {
            for (int x = 0; x < width; ++x) {
                if (bm.get(x, y)) {
                    int offset = stride * y + x / 8;
                    b[offset] |= (byte) (0x80 >> (x % 8));
                }
            }
        }
        return b;
    }

    public Image getImage() throws BadElementException {
        byte[] b = getBitMatrix();
        byte g4[] = CCITTG4Encoder.compress(b, bm.getWidth(), bm.getHeight());
        return Image.getInstance(bm.getWidth(), bm.getHeight(), false, Image.CCITTG4, Image.CCITT_BLACKIS1, g4, null);
    }

    // AWT related methods (remove this if you port to Android / GAE)

    public java.awt.Image createAwtImage(Color foreground, Color background) {
        int f = foreground.getRGB();
        int g = background.getRGB();
        java.awt.Canvas canvas = new java.awt.Canvas();

        int width = bm.getWidth();
        int height = bm.getHeight();
        int pix[] = new int[width * height];
        for (int y = 0; y < height; ++y) {
            for (int x = 0; x < width; ++x) {
                pix[y * width + x] = bm.get(x, y) ? f : g;
            }
        }

        java.awt.Image img = canvas.createImage(new MemoryImageSource(width, height, pix, 0, width));
        return img;
    }

    public void placeBarcode(PdfContentByte cb, Color foreground, float moduleSide) {
        int width = bm.getWidth();
        int height = bm.getHeight();

        cb.setColorFill(foreground);

        for (int y = 0; y < height; ++y) {
            for (int x = 0; x < width; ++x) {
                if (bm.get(x, y)) {
                    cb.rectangle(x * moduleSide, (height - y - 1) * moduleSide, moduleSide, moduleSide);
                }
            }
        }
        cb.fill();
    }

    public Rectangle getBarcodeSize() {
        return new Rectangle(0, 0, bm.getWidth(), bm.getHeight());
    }
}

And maven dependency: OpenPDF\openpdf\pom.xml

<dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>core</artifactId>
    <version>3.5.3</version>
  </dependency>
asturio commented 6 months ago

@ctoabidmaqbool just to be sure. You want to create QR-Codes, right? There are many implementations of Barcodes in OpenPDF, but as @andreasrosdal mentioned, the QR-Code aren't part of OpenPDF. And copying the implementation of iText is not an option. So we need a new fresh implementation, where we can probably use some library. There are some libraries which implement already QR-Codes. ZXing seems to be the most popular one.

At the other hand we want to keep the number of dependencies small.

So we need a fresh implementation using an optional dependency, or let the users use ZXing on their side, using e.g. a code like the one you posted here.