JasperReports with Barcode Code128 (Barcode4J): PNG differs from PDF

2.3k views Asked by At

I'm printing a label with following number "1000049722ABCD2F" as a barcode, using a Jasper-template and the barcode-element "Code128" from Barcode4J. Printed as a PDF, the barcode is perfect and scannable. Printing same barcode as a PNG-file, the barcode is not scannable and it obviously differs from the PDF-barcode:

Same barcode: PDF (upper part of an image) and PNG (lower part of an image):

Same barcode: PDF (upper) and PNG (lower)

Following code is used to generate the PDF-barcode:

    byte[] data = JasperExportManager.exportReportToPdf(jasperPrint);

To generate PNG, it's not that simple:

    ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();
    ImageOutputStream imageOutputStream = ImageIO.createImageOutputStream(byteOutputStream);
    ImageWriter imageWriter = ImageIO.getImageWritersBySuffix("png").next();
    imageWriter.setOutput(imageOutputStream);

    float zoom = getZoomFactor(jasperPrint);

    BufferedImage image = new BufferedImage(
            (int)(jasperPrint.getPageWidth() * zoom ) + 1,
            (int)(jasperPrint.getPageHeight() * zoom) + 1,
            BufferedImage.TYPE_INT_RGB);

    JRGraphics2DExporterNoAntialias exporter = new JRGraphics2DExporterNoAntialias();
    exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
    exporter.setParameter(JRGraphics2DExporterParameter.GRAPHICS_2D, image.getGraphics());
    exporter.setParameter(JRExporterParameter.PAGE_INDEX, Integer.valueOf(page));
    exporter.setParameter(JRGraphics2DExporterParameter.ZOOM_RATIO, new Float(zoom));
    exporter.exportReport();

    IIOMetadata imageMetaData = imageWriter.getDefaultImageMetadata(new ImageTypeSpecifier(image), null);

    // DPI = 200, inch = 25.4
    double dotsPerMilli = 200 / 25.4;

    IIOMetadataNode horiz = new IIOMetadataNode("HorizontalPixelSize");
    horiz.setAttribute("value", Double.toString(dotsPerMilli));

    IIOMetadataNode vert = new IIOMetadataNode("VerticalPixelSize");
    vert.setAttribute("value", Double.toString(dotsPerMilli));

    IIOMetadataNode dim = new IIOMetadataNode("Dimension");
    dim.appendChild(horiz);
    dim.appendChild(vert);

    IIOMetadataNode root = new IIOMetadataNode("javax_imageio_1.0");
    root.appendChild(dim);

    imageMetaData.mergeTree("javax_imageio_1.0", root);

    imageWriter.write(null, new IIOImage(image, null, imageMetaData), null);
    imageOutputStream.close();
    imageWriter.dispose();
    byte[] data = byteOutputStream.toByteArray();

I am using: barcode4j-2.1 / jasperreports-5.0.0 / 200 DPI is a required size for my label printer

I tried to change quite some settings (BufferedImage.TYPE-value, width of barcode, Barbecue-barcode 128B and others), but there is always a difference between the PDF and PNG-barcode.

GOAL: PNG-barcode should be exactly the same as the PDF-barcode.

Could anyone help me with this? I would greatly appreciate it!

1

There are 1 answers

0
Aza Suhaza On

Instead of using ImageWriter, why don't you try using MimeTypes.MIME_PNG from org.krysalis.barcode4j.tools.MimeTypes (from barcode4j-2.1.jar itself).

I'll not repeat my answer but you can refer to my codes. Here's the link to my other stackoverflow:

Barcode4j as png image

and I've never face this issue (unable to scan barcode) using the program.