Categories
Latest
Popular

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 stream
var 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 URL
var 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 class
var 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:

package shinydesign;
import java.io.FileInputStream;
import java.io.File;
import java.io.OutputStream;
import java.io.IOException;
import com.java4less.rbarcode.*;
 
public class BarcodeGenerator {
 
	public String filename;
	private int imageWidth=200; //Default width for image
	private int imageLength=200; //Default height for image
	private boolean imageSaved; //Whether the class was successfull in saving the image to the filesystem
 
	public boolean isImageSaved() {
		return imageSaved;
	}
 
	public int getImageWidth() {
		return imageWidth;
	}
 
	public void setImageWidth(int imageWidth) {
		this.imageWidth = imageWidth;
	}
 
	public int getImageLength() {
		return imageLength;
	}
 
	public void setImageLength(int imageLength) {
		this.imageLength = imageLength;
	}
 
	//This method generates a Barcode image and stores it on the server filesystem it then returns the image filename
	public void generateBarcode(String code,OutputStream out) throws IOException{
 
		// 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 encoding
		this.imageSaved=bce.result;
 
		try{
			   File file1 = new File("data/domino/html/app1/file"+code+".png");
			   FileInputStream fs = new FileInputStream(file1);
			   byte[] byteArray = new byte[(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:

<img src="http://192.168.1.30/barcodedemo.nsf/test.xsp?openxpage&key=Shiny Design"/>

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.

snowleopardbarcodecobrabarcodegorillabarcodelionbarcodebearbarcodeowlbarcode

 

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)

Discussion — 8 Responses

  • Kerr Rainey June 3, 2011 on 5:04 pm

    Any reason you didn’t use ZXing? http://code.google.com/p/zxing/

    It’s dirt easy to use. It took me a couple of minutes to get going in a plain old domino Java agent.

  • admin Kerr Rainey June 3, 2011 on 5:12 pm

    The client side decoding is pretty fast and saves having to upload a barcode image. I also found the ZXing barcode on Android to be quite slow.

  • Kerr Rainey June 3, 2011 on 5:24 pm

    I was mostly thinking of the server side generation, as that’s what I’ve been using it for. Was there a reason you went with the java4less lib for the generation over ZXing?

  • admin Kerr Rainey June 3, 2011 on 5:29 pm

    I see – no it appeared in google first – I was looking specifically for Datamatrix generation & java. I must admit if I wanted to use it in production I would have looked harder for a free one ;-) but for a demo it was easy to use.

  • David Barry June 6, 2011 on 3:20 am

    Hi Mark,

    Long term Domino developer having lots of fun with xPages. Been trying to add a QR Code for Contact Info to Personal Address book for quite a while. I know I can generate QR Codes with the gwt-user.jar. Their are great examples in zxing.appspot.com. I have the JAR added as a resource in my NSF. I have a button on the xpage.

    The SSJS to call the gwt-user.jar Library, sending the text to encode, collect resulting PNG and do the partial refresh of the xpage to display image is still beyond me.

    What would be a good place to start for s SSJS novice like me?

  • admin David Barry June 6, 2011 on 8:57 am

    Hi Dave.

    I am no expert by a long way – but it sounds like the method described would work except for the partial refresh – not sure how do to that to yet in conjunction with the Java resource. I would start by having an XPage generate the barcode onto the filesystem first – if you have the JAR attached as described by Stephen Wissel you should be able to call methods in the JAR from the SSJS – just remember to use the complete package name to each method if you haven’t declared it as a Java Bean. Extracting an argument from the URL Query String is in the example code above so you can pass this to your java encode method.

    Once you have the XPage generating the image on the file system you can just stream it back (again the code is above). If the partial refresh is an issue go for the same techinque I did which is to use a normal img tag which references the XPage – then when the contact is saved just pick up the image from the file system and attach it to the document – for file handling example code have a look at this Open NTF project – http://www.openntf.org/internal/home.nsf/project.xsp?action=openDocument&name=XPages%20Multiple%20File%20Uploader by Mark Leusink who is far more knowledgeable than me.

    For resources I would go to the normal places which i am sure your fully aware of – for this specific example I used Stephens blog & X Pages 101 by Matt White (highly recommended).

    If its any help I can send you the Notes DB for all its glory.

  • David Barry June 6, 2011 on 4:56 pm

    Thanks Matt Will keep pounding away. I would appreciate having a copy of your DB. It would be a good example since it is working. When I have my DB cleaned up with error code and pretty UI I plan to post on OPENNTF.