Skip to main content
Skip table of contents

How to generate 2D barcode as vector image?

Why are our barcode pages coming out completely black?


I am generating 2D barcodes using iText API, but these barcodes are placed into the PDF document as raster images, hence reducing the quality of the barcode on low resolution printers. As a result, we're unable to scan the barcode. This is our code:


BarcodePDF417 pdf417 = new BarcodePDF417();
String text = "BarcodePDF417 barcode";
pdf417.setText(text);
Image img = pdf417.getImage();
document.add(img);
I discoved the placeBarcode() method that is supposed to create a vector image. I tried using it like this:


Rectangle pageSize = new Rectangle(w * 72, h * 72);
Document doc = new Document(pageSize, 1f, 1f, 1f, 1f);
PdfWriter writer = PdfWriter.getInstance(doc, getOutputStream());
doc.open();
PdfContentByte cb = writer.getDirectContent();
BarcodePDF417 pf = new BarcodePDF417();
pf.setText("BarcodePDF417 barcode");
Rectangle rc = pf.getBarcodeSize();
pf.placeBarcode(cb, BaseColor.BLACK, rc.getHeight(), rc.getWidth());
doc.close();

This result in a page that is completely black.


Posted on StackOverflow on May 12, 2015 by Dhorrairaajj

Please take a look at the BarcodePlacement example. In this example, we create three PDF417 barcodes:

Image img = createBarcode(1, 1, pdfDoc);
doc.add(new Paragraph(String.format("This barcode measures %s by %s user units",
    img.getImageScaledWidth(), img.getImageScaledHeight())));
doc.add(img);
img = createBarcode(3, 3, pdfDoc);
doc.add(new Paragraph(String.format("This barcode measures %s by %s user units",
    img.getImageScaledWidth(), img.getImageScaledHeight())));
doc.add(img);
img = createBarcode(3, 1, pdfDoc);
doc.add(new Paragraph(String.format("This barcode measures %s by %s user units",
    img.getImageScaledWidth(), img.getImageScaledHeight())));
doc.add(img);

The result looks like this on the outside:

Bar codes

Bar codes

One particular barcode looks like this on the inside:

Vector data

Vector data

I'm adding this inside view to show that the 2D barcode is not added as a raster image (as was the case with the initial approach you've tried). It is a vector image consisting of a series of small rectangles. You can check this for yourself by taking a look at the barcode_placement.pdf file.

Please don't be confused because I use an Image object. If you look at the createBarcode() method, you can see that the Image is, in fact, a vector image:

public Image createBarcode(float mw, float mh, PdfDocument pdfDoc) {
    BarcodePDF417 barcode = new BarcodePDF417();
    barcode.setCode("BarcodePDF417 barcode");
    return new Image(barcode.createFormXObject(Color.BLACK, pdfDoc)).scale(mw, mh);
}

The height and the width passed to the scale() method, define the height and the width of the small rectangles that are drawn. If you look at the inside view, you can see for instance:

0 21 3 1 re

This is a rectangle with x = 0, y = 21, width 3 and height 1.

When you ask the barcode for its size, you get the number of rectangles that will be drawn. Hence the dimensions of the barcode is:

Rectangle size = barcode.getBarcodeSize();
float width = mw * size.getWidth();
float height = mh * size.getHeight();

Your assumption that size is a size in user units is only correct if mw and mh are equal to 1.

I use these values to create a PdfFormXObject instance and wrap it inside an Image. I can then add this Image to the document just like any other image. The main difference with ordinary images, is that this image is a vector image.

Click How to generate 2D barcode as vector image? if you want to see how to answer this question in iText 5.

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.