I wanted to expand on my previous post about using Java with LabView.   While that is a good example to get your feet wet in using an existing Java library from within LabView, I really want to show how powerful it actually can be.  For example, there are many commercial friendly, open-source, projects available around the internet that can be used in a similar way to Apache Commons with LabView. A great example of one of these is ZXing.   ZXing (Zebra Crossing) is the library behind the Barcode Scanner app on the Android market.  As far as I can tell, it is the de facto standard for reading barcodes on Android. As such, this library is often embedded inside other Android apps to allow for easy barcode scanning.  We will be using this library to show a more advanced example by creating a QR Code with LabView. Before we start, if you have not already, please read our previous post on Java with LabView , which walks through the initial Maven setup and LabView explanations.  Once you have done that, and gotten the source for our example from GitHub, you are ready to build a QR Code with LabView.

Sources

I created two new Maven modules for this example.  The first, SimpleQrExample, includes a helper class to perform some operations on the Java side.  I am fairly positive we could have accomplished this with only LabView, but wanted to demonstrate how easy it is to encapsulate some simple business logic into a custom class, and then pass the operation on to a block in LabView.

SimpleQRService

This class contains two methods we are concerned with.  The naming is pretty straight forward; encodeStringToQRFile takes a String (and formatting parameters), creates a QR Code, and saves the generated code to a temporary file.  The method then returns the path, as a String, to the temporary file.  Here is what the method looks like:

    public String encodeStringToQRFile(String stringToEncode, int width, int height, boolean deleteFileOnExit, String format) throws SimpleQRException {
            QRCodeWriter writer = new QRCodeWriter();
            BitMatrix bitMatrix;

       try {
           File tempFile = File.createTempFile("qrcode", "." + format);
           if (deleteFileOnExit) {
               tempFile.deleteOnExit();
           }
           logger.log(Level.FINER, "Encoding to file: {0}", tempFile.getAbsolutePath());
           bitMatrix = writer.encode(stringToEncode, BarcodeFormat.QR_CODE, width, height);
           MatrixToImageWriter.writeToFile(bitMatrix, format, tempFile);
           return tempFile.getAbsolutePath();
       } catch (WriterException ex) {
           throw new SimpleQRException(ex);
       } catch (IOException ex) {
           throw new SimpleQRException(ex);
       }
    }

I provided some overrides to the method to allow for some default values as well, namely deleting the temp file when done and the “png” image format. A decode method is also available, decodeQRFileToString.

    public String decodeQRFileToString(String filePath) throws SimpleQRException {
       QRCodeReader reader = new QRCodeReader();
       try {
           File file = new File(filePath);
           BufferedImage qrImage = ImageIO.read(file);
           return reader.decode(new BinaryBitmap(new GlobalHistogramBinarizer(new BufferedImageLuminanceSource(qrImage)))).getText();
       } catch (NotFoundException ex) {
           throw new SimpleQRException(ex);
       } catch (ChecksumException ex) {
           throw new SimpleQRException(ex);
       } catch (FormatException ex) {
           throw new SimpleQRException(ex);
       } catch (IOException ex) {
           throw new SimpleQRException(ex);
       }
    }

Notice that these methods encapsulate the java.io.File operations.  I did this because it takes out several steps in LabView when dealing with Java File handles.  Both methods are run through a test class which demonstrates their use.

DLL

The second module that I added, SimpleQrExample-DLL, takes the previous module and converts it to a DLL. The IKVM plugin also tells ikvmc to merge all the dependencies into the resulting DLL as well. This way, we have both Commons-Codec and the ZXing library in our new DLL. I also explicitly set the build finalname to give our DLL a nice looking assembly name, Summit.QR.Example.dll. Notice too, that I used the maven buildhelper plugin to parse out the project version. DLL’s do not like maven’s SNAPSHOT tag in the version, but we really want to set a version number on our DLL (help us prevent DLL hell!).  One option that I omitted is the strong naming step.  IKVM allows us to strongly name our DLL’s so that the .NET framework will better manage different versions of our library, check the documentation on ikvmc at IKVM.NET.  LabView also warns us when the version number changes.  On our build server here, we append Jenkins’ build-number to the end of the DLL version, since we cannot use the SNAPSHOT tag.  I still have not decided how to define the version for a release of a DLL, but I will post here when I think of something. I want to make it clear here as well, that once we have this DLL, we can use this DLL in all of our .NET applications, not just LabView.  For instance, I can now take this library and generate QR-Codes from C# and VB in Visual Studio.

QR Code with LabView

If you followed along with the last entry, Java with LabView, you can use your existing LabView project to make these changes. Or, you can just open the stringToBase64QRCode VI included with the source code.  Either way, here are the changes:

  1. I added a button that kicks off the operations, instead of relying on the value change of the text control.
  2. I added two 2D Picture panels on the front panel. 1. One for showing a QR Code containing the raw text 2. Another for showing a QR Code containing the encoded text
  3. I added two more text indicators. 1. One for displaying the barcode information from the Base64 QR Code, as if it were read by an imager 2. Another for showing the string from the Base64 Barcode (the original text). Some of the fields may seem redundant, but it only made sense to me to have the data make a full round trip to cover all of our bases. This is what my front panel designer looks like:

qrExampleFrontPanel

Block Diagram

My installation of LabView already had some included VI’s for operating with images. I was able to find them by right-clicking on the 2D Picture blocks inside the block diagram, and selecting “Create”. I used the “Draw flattened image” blocks to actually render the images. From there, I found a “Read PNG File” block in the context menu of the drawing blocks. This block takes in a LabView “path” which can be created with a string converter block. My final block diagram looked like this (click on it to expand it):

Example Block

As you can see, I added blocks referencing the SimpleQRService. The SimpleQRService was created using a .NET constructor node, since I did not make it a static implementation. I also created property nodes to give me the width/heights of the image boxes. We can use these as input to the QR Service that was created in order to generate a QR Code that fits inside of our image window. Once your block diagram looks something like mine, you should be able to run it and see some QR Codes.

Example Finished

And to prove that this actually works I pulled out my cell phone to test:

To me, this seems to be a much more practical use for integrating Java with LabView. The only other suggestions I have found on generating QR Codes easily all use the Google infographics charting service, which has been officially deprecated. This also gives you the flexibility to use other symbologies as well, as ZXing works with many different barcode formats.