Datamatrix for unique identification of Documents on Server Side with libdmtx
I had earlier written a post on how to use QR Code to take care of identification of printed documents and updating the DB based on the QR Code detection. However, we had to abandon the use of QR Codes in the document because the library wasn’t performing reliable, even with QR Codes from image files, which were direct screenshots of the PDF. Add to this, the fact that ZXing was also consuming a lot of memory. We believe that it was just not meant for use in a web application, even though it is a low traffic application which caters to a very specific niche.
We decided to try out DataMatrix. However, there was a dearth of Free java libraries to render/detect them and the cost of the paid libraries put us off, as well as the lack of clarity on the respective product sites about whether they can be used from inside a web application.
We found that we could use a free native library named libdmtx, which works on top of Imagemagick to take care of our requirements. There was a java wrapper around it, but we couldn’t get it working even though we tried the steps mentioned on their page. So after a lot of thought and the consideration that we were not going to migrate to a non Unix platform for any of the environments, we decided to use the library to create images and detect them using the libdmtx-utils.
The service code reads something like this.
[java]
def createAndReturnBytes(String text) {
File tmpFile = new File(System.getProperty(‘java.io.tmpdir’) + File.separator + ‘tempStringHolder.txt’) //Temporary file to hold the string to be encoded. Using ‘echo’ in the didn’t work
tmpFile.write(text)
def p = "dmtxwrite ${tmpFile.absolutePath} -o ${filename}".execute() //Execute the process
p.waitFor() //Wait for the process to complete before proceeding further
byte[] contents = new File(filename).bytes //Retrieve the bytes from the image file
new File(filename).delete()
return contents //Return the bytes for the image
}
String detectDataMatrix(File file){
def p = "dmtxread -N1 ${file.absolutePath}".execute().text //-N1 flag to break execution after the first datamatrix on the file has been detected
return p
}
[/java]
This has been working very reliably for us. To enhance the images further, we may use ImageMagick to crop the area, where we think the datamatrix is and zoom on it before sending the file to the datamatrix service for detection.
Hope this helps someone
Vivek
Hi Mike,
The approach would still be valid. However, I am not sure whether any changes would be needed in the code I wrote because I have not tried this on a Windows system.
Thanks for the feedback. 🙂
Vivek,
It’s worth noting that the dmtxread/dmtxwrite utilities run on Linux, UNIX, and Windows so if you ever need to migrate server platforms your approach is still valid. Thanks for posting the sample code!