Zebra printer GC420t not printing an image EPL 2 GW

3.3k views Asked by At

Using JasperReport to generate an image, and then trying to print that image on a Zebra printer GC420t. The image is generated but not printing. I have double checked the connection and ports. I have read this SO link and also the calibration one, but nothing works.

Code:

public void generateReport(Map<String, Object> parameters, List<Label> labels)
            throws JRException, IOException, ConnectionException, ZebraPrinterLanguageUnknownException{
        // TODO Auto-generated method stub
        JRBeanCollectionDataSource dataSource = new JRBeanCollectionDataSource(labels);
        System.out.println(" Wait !!");
        JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, dataSource);
        if(jasperPrint != null && jasperPrint.getPages()!=null && jasperPrint.getPages().size()>=0){
            FileOutputStream fos = new FileOutputStream("C:\\Users\\desktop\\Labels.png");
            //JasperExportManager.exportReportToPdfStream(jasperPrint, fos);
            BufferedImage rendered_image = null;
            rendered_image = (BufferedImage) JasperPrintManager.printPageToImage(jasperPrint, 0, 1.6f);
            ImageIO.write(rendered_image, "png", fos);
            Connection thePrinterConn = new DriverPrinterConnection("GC420t");
            try{
                for (DiscoveredPrinterDriver printer : UsbDiscoverer.getZebraDriverPrinters()){
                    System.out.println(printer);
                }
                thePrinterConn.open();
                if(zPrinter==null){
                    zPrinter = ZebraPrinterFactory.getInstance(thePrinterConn);
                }
                PrinterStatus printerStatus = zPrinter.getCurrentStatus();
                if(printerStatus.isReadyToPrint){
                    System.out.println("Ready to print !!");
                    DocFlavor flavor = DocFlavor.INPUT_STREAM.AUTOSENSE;
                    DocAttributeSet das = new HashDocAttributeSet();
                    FileInputStream fis = new FileInputStream("C:\\Users\\desktop\\Labels.png");
                    Doc mydoc = new SimpleDoc(fis, flavor, das);
                    PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
                    aset.add(OrientationRequested.PORTRAIT);
                    @SuppressWarnings("unused")
                    PrinterJob pj = PrinterJob.getPrinterJob();
                    PrintService[] services = PrintServiceLookup.lookupPrintServices(flavor, aset);
                    PrintService defaultService = PrintServiceLookup.lookupDefaultPrintService();
                    for (int i = 0; i < services.length; i++){
                      System.out.println(services[i].getName());
                    }
                    if(services.length == 0){
                        if(defaultService == null){
                         //no printer found
                        }
                        else{
                            //print using default
                            DocPrintJob job = defaultService.createPrintJob();
                            try{
                                job.print(mydoc, aset);
                            }catch (PrintException e){
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                        }
                    }
                    else{
                         PrintService service = ServiceUI.printDialog(null, 200, 200, services, defaultService, flavor, aset);
                         if (service != null){
                             DocPrintJob job = service.createPrintJob();
                             try{
                                 job.print(mydoc, aset);
                             }catch(PrintException e){
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                             }
                        }
                   }
                   //ZebraImageI image = ZebraImageFactory.getImage("C:\\Users\\desktop\\Labels.png");
                }
                else{
                    System.out.println("Something went wrong");
                }
            }finally{
                thePrinterConn.close();
            }
            System.out.println("Report generated !!");
        }
    }

I read the EPL 2 manual and converted the image into binary graphic data for immediate printing.

Code:

private byte[] getEplGraphics(int top, int left, BufferedImage bufferedImage) throws IOException {
        ByteArrayOutputStream fs = new ByteArrayOutputStream();

        //int canvasWidth = bufferedImage.getWidth();
        // loop from top to bottom
        System.out.println(bufferedImage.getHeight());
        System.out.println(bufferedImage.getWidth());

        int maxY = bufferedImage.getHeight() + (64- bufferedImage.getHeight()%64);
        int maxX = bufferedImage.getWidth() + (64- bufferedImage.getWidth()%64);
        System.out.println(maxX);
        System.out.println(maxY);
        int p3 = maxX / 8;
        int p4 = maxY/ 8;
        int len = 0;
        String gw = "N\nGW0,0," + p3 + "," + p4 + ",";
        fs.write(gw.getBytes());
        for (int y = 0; y < maxY; ++y) {
            // from left to right
            for (int x = 0; x < maxX;) {
                byte abyte = 0;
                // get 8 bits together and write to memory

                for (int b = 0; b < 8; ++b, ++x) {
                    // set 1 for white,0 for black
                    int dot = 1;

                    // pixel still in width of bitmap,
                    // check luminance for white or black, out of bitmap set to white

                    if (x < bufferedImage.getWidth() && y < bufferedImage.getHeight()) {
                        int c = bufferedImage.getRGB(x, y);
                        int red = (c & 0x00ff0000) >> 16;
                        int green = (c & 0x0000ff00) >> 8;
                        int blue = c & 0x000000ff;
                        Color color = new Color(red, green, blue);
                        int luminance = (int) ((color.getRed() * 0.3) + (color.getGreen() * 0.59)
                                + (color.getBlue() * 0.11));
                        dot = luminance > 127 ? 1 : 0;

                    }

                    abyte |= (byte) (dot << (7 - b)); // shift left,
                    // then OR together to get 8 bits into a byte
                }

                // System.out.print( (char)(abyte + 48 ) );
                // write here
                len++;
                fs.write(abyte);
            }
        }
        System.out.println("GW Length::"+len);
        // Assign memory position here
        // fs.write('\n');
        fs.write("\nP1".getBytes());
        fs.flush();
        // System.out.println(fs);
        return fs.toByteArray();
    }

After converting the image into binary graphics data, it's not printing the data.

How can I get the printer to print the image?

1

There are 1 answers

26
Petter Friberg On

Using jasper-reports, render an image, convert image to EPL and send to zebra printer, is normally not the correct solution to print on a thermal printer. This kind of code is not only slower, but you can also have lower resolution (which may produce problems for example with barcodes)

You have two standard options

  1. Use the printer protocol and send a text file.

  2. Install the printer driver and use the JRPrintServiceExporter

Using the printer protocol

This is what I normally use (mostly to get code bars printed perfectly, no image, but direct command to print code bar). You will not use jasper-reports for this, instead you setup your txt file (you can use a design program in your case zebra-designer) and then you use libraries like freemarker to replace/insert dynamic data in your direct protocol file. When done you send it directly to printer for example via serial port (also wireless using bluetooth-serial adapter)

Using printer driver

In this solution you need to install the correct printer driver and then you use this driver to send a print job. In jasper-report to send a printer job you use code like:

PrintRequestAttributeSet printRequestAttributeSet = new HashPrintRequestAttributeSet();
//set page size etc if you need to
PrintServiceAttributeSet printServiceAttributeSet = new HashPrintServiceAttributeSet();
//set print service attributes
JRPrintServiceExporter exporter = new JRPrintServiceExporter();
exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
SimplePrintServiceExporterConfiguration expConfig = new SimplePrintServiceExporterConfiguration();
String printerName = "myPrinterName"; //Check the name of printer
PrintService service = Printerlookup.getPrintservice(printerName, Boolean.TRUE, Boolean.TRUE);
expConfig.setPrintService(service);
expConfig.setPrintRequestAttributeSet(printRequestAttributeSet);
expConfig.setPrintServiceAttributeSet(printServiceAttributeSet);
expConfig.setDisplayPageDialog(Boolean.FALSE);
exporter.setConfiguration(expConfig);
exporter.exportReport(); 

If your are not printing correctly your debug method is to export to pdf and then use the print dialog from pdf to print to printer (remember you are using driver, so you can select it in dialog)

With pdf

  • it prints correctly! - Crap, that's strange but you have a workaround (export to pdf and print that)

  • it does not print correctly! - Crap, the driver is not working as it should be (contact supplier), and while they are working try with different image types (I would try with .bmp), check all settings in printer dialog (these you can set to later to printRequestAttributeSet).

I don't care, I'm actually only interested in converting png to EPL2 language

Please update question, remove jasper and instead show png image, show expected output and show current output, this is some code that can help you with this, but be sure first that you really don't care:

Use ZEBRA SDK see printImage command

ZebraPrinter printer = ZebraPrinterFactory.getInstance(connection);
printer.printImage("sample.jpg", x, y);

Using the EPL2 GW command it's in C# but languages are similar

How to convert image to PCX see code.zip file ToPCX.java