Creating Barcodes with an XPage / Reading them with Flex

barcode2

Barcodes you have to love them, those little digital pictures can make life a lot easier when trying to tag a multitude of things but still be machine readable.

Already smart phones along with cheap / integrated webcams are putting potential barcode scanners at everyone’s fingertips, what we need is an easy way to create the barcode and then read it.

2D Barcodes

2D Barcodes like the Datamatrix and QR Code can encode a reasonably large amount of information, certainly enough to hold a unique key.

Creating a barcode with an XPage

Due to the ability for an XPage to easily leverage Java code it is quite straightforward to integrate an existing Java library, so when the XPage is called a rendered barcode is returned.

For this demo I have decided to use a commercial library – the code will operate in a demo mode and is reasonably priced if you decide to buy it.  For this demo I am only interested in the Datamatrix barcode so I downloaded that specific Jar file from here.

Setting Up

There are plenty of other great blogs which explain how to use existing Java libraries with X Pages – so I won’t go into any great detail here.  Heres a very good example from Stephen Wissel in fact I used his example as the basis for generating the barcode.

Image Format

PNG, GIF or JPEG?  If you decide to go for PNG or GIF as your file format you need to download some additional JARs which also need to be added – for PNG here, for GIF here.  Just make sure you have added to the them to the database the same way as the barcode Jar file.

I decided to use the PNG file format.

The XPage

Similar to Stephens example you need to make sure you add your SSJS to the beforeRenderResponse event of the XPage – this way we can return what we want back to the user.  This SSJS will call a java class which actually generates the barcode.

Note this code has been tested on a 8.52 server.

The SSJS code looks like this:

// Get the output streamvar exCon = facesContext.getExternalContext();var response = exCon.getResponse();var out = response.getOutputStream();   if(out==null){print("No Stream");}else{print("All good with the stream");}//Get key from URLvar key =(param.key||"");print("Encoding:"+ key);   // Set the MIME Type to image/PNG response.setContentType("image/png"); response.setHeader("Cache-Control","no-cache");   //Instantiate the BarcodeGenerator classvar bar:shinydesign.BarcodeGenerator=new shinydesign.BarcodeGenerator();//Example setting a width property bar.setImageWidth(400);//Call the generate method passing the key and the output stream bar.generateBarcode(key,out);   // Stop the page from further processing; facesContext.responseComplete(); out.close();

The Java Code

The Java code is not production ready (no error handling etc) so use at your own risk.

The class has some properties which allows you to set the height and width.

The main method – generateBarcode is passed the output stream and the code which needs to be converted to a barcode.  Remember in this case I am only interested in the datamatrix barcode and the image format is PNG.

In my case I wanted to not only stream the PNG back to the browser but I wanted to save a copy of the image on the file system (under the servers HTML directory).

This way in a real app I could generate a barcode for a document, return it live to the user and then when the document is saved attach the image to the document.  This means on subsequent viewing there is no need to generate the image again.

Add the following class within the shinydesign package:

packageshinydesign;importjava.io.FileInputStream;importjava.io.File;importjava.io.OutputStream;importjava.io.IOException;importcom.java4less.rbarcode.*;   publicclass BarcodeGenerator {   publicString filename;privateint imageWidth=200;//Default width for imageprivateint imageLength=200;//Default height for imageprivateboolean imageSaved;//Whether the class was successfull in saving the image to the filesystem   publicboolean isImageSaved(){return imageSaved;}   publicint getImageWidth(){return imageWidth;}   publicvoid setImageWidth(int imageWidth){this.imageWidth= imageWidth;}   publicint getImageLength(){return imageLength;}   publicvoid setImageLength(int imageLength){this.imageLength= imageLength;}   //This method generates a Barcode image and stores it on the server filesystem it then returns the image filenamepublicvoid generateBarcode(String code,OutputStream out)throwsIOException{   // create barcode com.java4less.rdatamatrix.RDataMatrix bc=new com.java4less.rdatamatrix.RDataMatrix(); bc.barType=com.java4less.rdatamatrix.RDataMatrix.DATAMATRIX; bc.code=code; bc.checkCharacter=true;   // work with pixels bc.X=1; bc.resolution=1; bc.topMarginCM=5; bc.leftMarginCM=5; bc.setSize(imageWidth,imageLength);   //Save image to file system//In this case a subdirectory under the servers HTML drectory - using PNG in this case BarCodeEncoder bce=new BarCodeEncoder(bc,"PNG","data/domino/html/app1/file"+code+".png");//Set a property with the result of the PNG encodingthis.imageSaved=bce.result;   try{File file1 =newFile("data/domino/html/app1/file"+code+".png");FileInputStream fs =newFileInputStream(file1);byte[] byteArray =newbyte[(int) file1.length()]; fs.read(byteArray); fs.close(); out.write(byteArray);}catch(Exception e){return;}}   }

Getting the Image

To display the barcode simply use the a normal HTML Image Tag like this:

Where test.xsp is your XPage which calls the Java Code and the key is the string that you wish to encode into a barcode.

The Gotcha

Currently there is an issue if you try and put multiple image tags on the same page – as an XPages beginner I am not sure quite what the problem is but the code will not render all of the images.  This is not a problem if you use the attach image method described above as you could just reference the stored files.

Using the Barcode

The following Adobe Flex application will read a generated Datamatrix barcode and display the result.

jungledragon

First print off some test datamatrix barcodes which I have encoded using the above technique.  Each one should bring back some information based on the amazing avatar images that Ferdy Christant has created for JungleDragon.  Many thanks to Ferdy for giving me permission to reuse the images here and if you haven’t looked at JungleDragon yet then its about time you did.

snowleopardbarcode cobrabarcode gorillabarcode lionbarcode bearbarcode owlbarcode

For this demo the information is stored within the application using a simple ArrayCollection but it could easily retrieve information from a Domino application / alternative system.  Don’t forget as its Adobe Flex it can easily be converted to an AIR application which can then run on mobiles.  For a mobile version we could then use the phones camera to pickup the barcode.

Mark Myers and I have some plans for some great little applications which will leverage this technology – stay tuned! In the meantime if you have any need for a barcode implementation within your software solutions then just drop me a line.

Link to Demo (Due to WordPress eating my HTML)