CFC for generating and reading 2D barcodes in ColdFusion
One of the projects I’ve been working on recently requires the ability to receive faxes and place them into a customer’s account. At first we looked at using optical character recognition to scan out the customer’s ID from the cover sheet, but this route was looking expensive and time consuming, and we weren’t sure we would be able to reliably read the customer IDs, since faxes are sometimes hard to read even with the human eye. We are providing a pre-filled out cover sheet, so the customer ID would be printed, not hand written, but I think it would still be difficult to read.
Just around this time I saw Jim Rising’s post on cf-talk saying that if you need to do this kind of thing, you really should be looking at using a 2D barcode instead of trying to OCR a number. So I did. He mentioned Java4Less, a company that sells reasonably priced (~$100) java libraries for reading and writing barcodes, including data matrix barcodes. A datamatrix barcode is a 2D barcode that can encode more data in less space than a traditional barcode. Its also much more durable, and can be read even when faxed several times. They look like this:

I’ve finally got this all working, and have packaged it up as a CFC. Here’s how its used:
<cfset BarCoder = CreateObject("component","2DBarCode_j4l").init()>
Reading Barcodes
<cfset results = BarCoder.readFromImage(myImageObject)>
or
<cfset results = BarCoder.readFromFile("myFile.png")>
These methods return an array of barcodes that were found in the image. Each element in the array contains the following structure:
| Key | Description |
| x | The x coordinate of where the barcode was found on the image. |
| y | The y coordinate of where the barcode was found on the image. |
| value | The value that was read from the barcode. |
If no barcodes were found, an empty array is returned.
Creating Barcodes
Basic example:
<cfset BCImage = BarCoder.createBarCode(text='my text to place into barcode')>
BCImage now contains a ColdFusion image object that you can write to file or send it to the browser or whatever you need to do. There are several other options you can pass to createBarCode(), they described in the readme file included in the download.
To make this all work you’ll need to get three jar files from Java4Less and place them into your {coldfusion-install-dir}/lib directory, or place them somewhere else and add the path to them in your java.class.path setting in jvm.config. The three files are rdmvision.jar, rbarcode.jar, and rvision.jar. These come from a combination of two Java4Less products: RDataMatrix and J4L Datamatrix Vision.
Java4Less.com does have evaluation versions of these libraries available for download, so you can play with this before spending any money. My cfc only deals with 2D/Data Matrix barcodes. Java4Less offers libraries for working with regular barcodes, but I have not used them.
I have to say that being on ColdFusion 8 made this project much easier. I think it may have still been possible to do in CF7, but it would have required a lot more psudo-java code to be written in CF.
You can download the cfc from RiaForge:
December 15th, 2007 at 2:56 pm
Ryan,
Awesome stuff…. nice job on this.
-mark
December 15th, 2007 at 3:18 pm
Very cool! I was working with some basic barcode stuff this spring so I can see how this could really come in handy.
Jimmy
December 17th, 2007 at 8:49 am
Thanks for publishing and sharing this! I can see some interesting possibilities here. Please let us know if anyone extends this and uses it with CF 7!
December 17th, 2007 at 12:31 pm
Great job…Thanks for SHARING it with the world!
Regards,
Troy
December 30th, 2007 at 11:02 am
Would it be easy to make the cfc to work with CF 7 or BlueDragon?
July 25th, 2008 at 3:38 am
In case anyone was wondering what the barcode said.
X-2E7EAB12-28BB-4095-97-86-9299CA865AD7
August 13th, 2008 at 10:29 am
Really awesome. I’ll want to use j4less Barcode1DReader Java class with CF 7. Your example for 2D help me so much. Do you have another example for CF 7?
August 13th, 2008 at 12:01 pm
I do not have any examples for CF7 or Blue Dragon. It should be possible, you’ll just have to code around the CF8 image stuff. Some of the java methods require passing in a BufferedImage object, and there may be some other things to watch for. Its not as simple as just swapping in ImageCFC for the reads and writes.
September 4th, 2008 at 12:02 pm
hey ryan… this rocks! i’ve had a client request a datamatrix implementation, for the same reasons you’re using it (fax cover pages). never worked with it before and i’m sure this will help me to get it done. thanks for making it available.
quick question if you don’t mind… we’d like the barcode to be as inconspicuous as possible, while at the same time being aware of keeping it legible over multiple instances of being faxed. have you done any tests on your own to determine what a decent size is to meet those requirements?
thanks again!
charlie
September 4th, 2008 at 12:47 pm
Charlie, to keep the barcode reading reliable, we were forced to use a barcode thats about 1.5 inches square. I would not characterize it as inconspicuous, but I think it looks ok at that size.
We had the need to read barcodes after they had been faxed at least twice, if you are only planning on faxing them once you may be able to get by with a smaller barcode.
September 4th, 2008 at 7:11 pm
Hi
I have no idea about the tech side of it but I am looking for a solution to do something like this.
we setting up the paperless office and I want all the staff to fax the documents to a number with a coversheet and then the fax automatically goes to where it should go in the database(we use Zoho CRM) for that client.
how can I do this ,how much would it cost,..
Thanks
Brad
September 5th, 2008 at 1:51 pm
I’m just curious, what is the recognition rate?
September 5th, 2008 at 1:56 pm
I believe its around 90%. Usually the ones that failed were ones that had a slight paper jam as the fax was going through. You aren’t going to be able to read that no matter what the size. Or ones that had been faxes many times, so that the squares were really no longer square.
Don’t forget that some of your faxes will come in upside down. I was originally only scanning the upper right (where we had placed our barcode), but that lead to not reading faxes that were sent upside down. Scanning the entire page is more time consuming by several seconds, so I changed it to first look in the upper right corner, then the lower left corner. You don’t need to worry about rotating the barcode or anything, the decoder will work no matter what orientation the barcode is in.
September 18th, 2008 at 12:27 pm
hi
what is the correct url on http://www.java4less.com to download the right trial package?
http://www.java4less.com/barcodes/barcodes.php?info=download
what is the name of the two .jar files?
i have always the same error: Class not found: com.java4less.vision.datamatrix.DatamatrixReader
thanks
September 18th, 2008 at 12:53 pm
jurli, I’m not positive but I think you need the first package listed on the page you linked to, rbard10.zip - in there you will find the rbarcode.jar file thats used for generating the barcodes.
Then from this page: http://www.java4less.com/vision/vision.php?info=download you’ll need the “Datamatrix Vision for Java” package (RDMVisionJava.zip) for reading the 2d barcodes. In the zip file you’ll find two jar files you need, rvision.jar and rdmvision.jar.
Update: Actually you need to have *three* jar files installed: rdmvision.jar, rbarcode.jar, and rvision.jar.
September 30th, 2008 at 7:55 am
I downloaded the RBarcode (1D, Post 4 state barcodes, PDF417 and RDataMatrix) trial version. Now I’m ready to buy it, but I wanted to make sure I’m choosing the right one to purchase. I am guessing it’s the RDataMatrix Binary (and J4L Datamatrix Vision (Java) to read). Do you need the versions with source code?
October 6th, 2008 at 10:44 am
How many characters does this encode? Mine does not seem to read the barcode if there are more than 230 characters in the string. Is this the maximum?
January 14th, 2009 at 10:59 am
Great stuff, Ryan, thanks. Saved us a fortune!