After showing how to create barcodes it only seems logical to show how to read them – your XAML NetAdvantage package of choice would not be complete if it only included a control to create barcodes. And, well, it is complete, since it includes the Infragistics Barcode Reader as well! Barcode representations have evolved in multiple standards to meet different requirements and no longer confine to just lines but also dots, rectangles and other shapes and patterns. They are all still referred to as barcodes – and it comes as no surprise their spread is now even wider (especially with mobiles) – and with that comes the demand for applications capable of reading them. Now all those machine-readable patterns mean nothing to the human eye(especially if you turn off the text on the few of them that have it, as per the blog linked above), so if and when you find yourself in need to provide the ability to read barcodes, you can count on the Infragistics Barcode reader to get the job done with great ease and flexibility.
The Infragistics Barcode Reader is a library available in both NetAdvantage for WPF and Silverlight as well as the NetAdvantage for Windows Phone. That makes it a cross-platform solution to your pattern-reading needs. As mentioned so far, there are plenty of standards that have emerged to handle different scenarios and this reader is well equipped in that area – it comes with support for the following barcode symbologies:
- Code 39 and Code 128 extensively used in shipping an packaging, as as the naming suggests one is more data packed and capable of encoding all 128 ASCII characters, while the other manages 39.
- EAN/UPC with a few variations of the same. They are also linear types of symbology, more specifically the ones you are very likely to see on every item in the store.
- Interleaved 2 of 5 are linear codes mostly used in packs/boxes with multiple products
- QR Code – the de-facto standard when targeting mobile devices these days.
And all that functionality is like you would expect very easy to use and it only requires you to point the reader to an image and collect and use the result as you see fit. That is an undeniable saving of your time and it gets better – the library is flexible enough not only with symbologies, but also can be customized in various ways which we’ll discuss later on.
You can start by picking a platform. The Barcode Reader’s work is mostly done in code-behind and it only requires an BitmapSource which is a base class available in WPF and both Silverlight/Windows Phone. That means that the code manipulating the reader can be shared across all platforms, but the way they may obtain the source image will vary. The assemblies required are slightly diffrent this time around as well, not just by name and include the basic platform assembly plus the Data Visualization one and the Barcode Reader:
Replace ‘SL5’ either ‘WPF4 or ‘WP7’. For Silverlight and Windows Phone applications, if you want to read QR codes (or create for that matter) you will have to include also the Encoding assembly:
For the purposes of this blog we’ll go through a full Silverlight demo and since it’ll be relatively easy to share most of the code and UI a Windows Phone app too. As far as WPF goes…well let’s say most of the app will be the same, but without using a web cam as a source for images as the need for plenty of code or external libraries made me skip that part. You could find such example in our Samples Browser.
Here’s how the Silverlight demo would look like:
We would use a single Image control(called ‘ImageContainer’) to set the source with whatever we see fit and that would also be the only source to provide for the Barcode reader. The reading process will be initiated in the button click handler and will use the Symbology selected in a combo box. But first – some setup required:
- using Infragistics.Controls.Barcodes;
Add a barcode to your class:
- BarcodeReader barcodeReader = new BarcodeReader();
And hook up the “Decode Complete” event and optionally set initial image and selected Symbology:
- barcodeReader.DecodeComplete += new EventHandler<ReaderDecodeArgs>(barcodeReader_DecodeComplete);
- //assign initial image
- ImageContainer.Source = image;
- //preselect symbology
- SymbologyCombo.SelectedIndex = 0;
Then you can start the decode process by calling the method:
- /// <summary>
- /// Start the barcode reader's decode method with some settings.
- /// </summary>
- private void Button_Click(object sender, RoutedEventArgs e)
- // Only read up to two barcode found on the image (usually the first two from left to right)
- barcodeReader.MaxNumberOfSymbolsToRead = 2;
- BitmapSource bs = (BitmapSource)ImageContainer.Source;
- // Decode the desired source using the symbology set in the combo!
- barcodeReader.Decode(bs, (Symbology)this.SymbologyCombo.SelectionBoxItem);
Note this is the overload with defined symbology to look for, but you could also decode with only the source available. Also, as naming suggests, this is a synchronous method and there is also an async version that you can invoke to perform a multi-thread multi-image decoding.
One important note – the Barcode Reader object does have a Filtered image property (a black and white version of the original source with the discovered symbol in it enclosed in a green rectangle as seen above). However, that filtered image only exists after decoding is complete so it is recommended that you only use it in the complete event handler or even better – use the arguments instead:
- void barcodeReader_DecodeComplete(object sender, ReaderDecodeArgs e)
- FilteredImageContainer.Source = e.FilteredImage;
- if (e.SymbolFound)
- resultText.Text += "\n Symbology: " + e.Symbology + "; Data: " + e.Value;
- resultText.Text = "Failed attempt.";
As you can see the Reader Decode Arguments provide the Filtered image along with more useful information, like the bool ‘SymbolFound‘ property to check if code was found, its Symbology and value. Keep in mind the event will be fired for each symbol decoded.
To make decoding barcodes more efficient we would ask the user to possibly identify the code type or ideally have it set in code if we know what it would be. For me the easiest way to do that is by using the Symbology Enum itself with a combo box or list control of some sorts. This can be achieved either in code:
- SymbologyCombo.ItemsSource = Enum.GetValues(typeof(Symbology));
Or in XAML by adding the Barcode namespace:\
- <Grid x:Name="LayoutRoot" Background="#FFF1EFEF">
- <ComboBox x:Name="SymbologyCombo" Width="112" Margin="5" >
What I find nicer about the XAML approach is the ease with which you can filter just the types you need in a specific order. Either way, defining symbology for decoding is extremely important – if not, the reader will assume all are possible and even if the first one yields a match, the reader will continue searching for each of the others. That naturally, means time lost with no additional benefit. In most cases the reader application would be designed with specific process or business in mind and the symbology expected would be known.
Another thing that would affect performance is, of course, the maximum number of symbols to read ( a property set to 2 above). Again it’s very logical, if you expect just one symbol, do not waste your time – the reader will continue searching even though one symbol is found. And it would get worse if no symbology is defined as it would mean searching again for each type.
Two more properties that can help you narrow down the work the control will have to do and with that improve performance. Barcode orientation enumeration – pretty straightforward, like symbology saves time looking for others. And the minimum symbol size that can be used for all linear types to reject too small symbols.
Lastly, the async decoding might be helpful, but keep in mind the decoding process can sometimes fail with damaged symbols (multiple times for that matter) before it reads it right. The synchronous implementation will handle that for you, but when you use the async method do not assume the event fired to be the final one.
There are plenty of ways to get an image to read, so let’s have a few interesting options. As you have noticed on the screenshot above there’s the web cam, the local file and the URL ones. For Silverlight there’s the default video capture device to use for snapshots, the local file is an obvious solution and the URL..let’s say a service is needed to download the images instead, due to cross-domain requests. Windows Phone implementations of the same are however very neat with the various available tasks. Like taking a snapshot:
- /// <summary>
- /// Start a capture task.
- /// </summary>
- private void StartCam_Click(object sender, RoutedEventArgs e)
- CameraCaptureTask cam = new CameraCaptureTask();
- cam.Completed += new EventHandler<PhotoResult>(cam_Completed);
- //and set the result to the cotainer.
- void cam_Completed(object sender, PhotoResult e)
- if (e.TaskResult == TaskResult.OK)
- BitmapImage bmp = new BitmapImage();
- ImageContainer.Source = bmp;
- //switch to main pane
- pivotCtrl.SelectedIndex = 0;
The very same method is used for local files with the Photo Chooser task and downloading remote images with the good old Web Client works just fine. Again pretty much all the layout is shared, excluding the fact it’s not on a single page but rather a Pivot-style app:
As you can see some codes, like QR, have built-in protection and some damage to their pattern might still not render them unreadable. You can even try this image I’ve drawn some on (you can copy it’s link or save it and use it in the demos) :
The first was even generated with our very own XamBarcode (see this sample) where you can control the error correction lever and size to combat damage on the symbol. This is also the integration meant in the first place – use the XamBarcode to encode you data, take an image of it and use the Barcode reader control to tell you what’s on it.
The reader is a tool capable of extracting information from multiple standards provided with just an image and in with the right tuning it can scale up or down to match your needs via multiple performance tweaks. The XamBarcodeReader completes the circle of functionality revolving around barcodes in the XAML NetAdvantage packages, so you can build great applications with great functionality for desktop, web and mobile!
You can download the Demos shown above for Silverlight and Windows Phone! You can find this and more controls in our samples on the Windows Phone market, follow the link above to download the WPF samples and visit the online Silverlight version, where you can find a much more complicated sample decoding from the live video feed rather than taking a snapshot!
Follow us on Twitter @Infragistics and join the competition on Facebook for a chance to win an iPad3!