Creating A Barcode And QR Code Scanner For Windows Phone 8.1 RT

In this article I will show you how to  write a barcode and QR scanner for Windows Phone 8.1 Runtime Apps. So let's start.

Step 1: Firstly, create a Windows Phone RT Project.

Create a Windows phone RT Project

Step 2: Now Go to References, then Manage Nuget Packages and search now Add Zxing Nuget Package to your app as in the following screenshots:

Manage Nuget Packages

Add Zxing Nuget Package

Accept the Agreement and Install the Nuget Package.

Step 3: Now first we start with creating UI for our App Go to MainPage.xaml, open the Designer.write xaml code like the following code snippet and you have to upload your own images and fonts.

  1. <Grid x:Name="LayoutRoot" Height="640" Margin="0,0.333,0,-0.333" HorizontalAlignment="Left" VerticalAlignment="Top" Background="#163146">  
  2.     <Grid.RowDefinitions>  
  3.         <RowDefinition Height="Auto" />  
  4.   
  5.   
  6.         <RowDefinition Height="*" />  
  7.     </Grid.RowDefinitions>  
  8.     <StackPanel Grid.Row="0" Height="110" Background=" #36B4A8" Orientation="Horizontal">  
  9.   
  10.   
  11.         <TextBlock Margin="12,40,0,0" FontFamily="Fonts/HelveticaNeue Thin.ttf#HelveticaNeue" FontSize="38" Foreground="White" Text="QR & BARCODE SCAN" />  
  12.     </StackPanel>  
  13.     <Grid Grid.Row="1" Background="#FFFFFF">  
  14.   
  15.   
  16.         <StackPanel Margin="12,100" HorizontalAlignment="Stretch" VerticalAlignment="Top" Orientation="Vertical">  
  17.             <StackPanel Height="50" Orientation="Horizontal" Tapped="StackPanel_Tapped">  
  18.   
  19.   
  20.                 <Image HorizontalAlignment="Left" Source="Assets/QR Code-50.png" Stretch="Uniform" />  
  21.                 <TextBlock Margin="8,8" FontFamily="Fonts/HelveticaNeue Thin.ttf#HelveticaNeue" FontSize="32" Foreground="#36B4A8" Text="Scan" />  
  22.             </StackPanel>  
  23.   
  24.   
  25.             <StackPanel Height="50" Margin="0,30" Orientation="Horizontal" Tapped="StackPanel_Tapped_1">  
  26.   
  27.   
  28.                 <Image HorizontalAlignment="Left" Source="Assets/View File-50.png" Stretch="Uniform" />  
  29.                 <TextBlock Margin="8,8" FontFamily="Fonts/HelveticaNeue Thin.ttf#HelveticaNeue" FontSize="32" Foreground="#36B4A8" Text="View" />  
  30.             </StackPanel>  
  31.         </StackPanel>  
  32.     </Grid>  
  33. </Grid>  
Output

run

Under Tap Events Navigate write the following code snippet to navigate respective pages.

this.Frame.Navigate(typeof(MainPage)); like this whatever the page name put there.

main page

Step 4: Add another blank page to your project, add the following code to UI (Make sure Add to Navigate To This Page in Tapped Event of Scan) as shown above.
  1. <Grid x:Name="LayoutRoot" Background="#163146" HorizontalAlignment="Left" VerticalAlignment="Top">  
  2.    <CaptureElement x:Name="captureElement" Stretch="UniformToFill" />  
  3. </Grid>  
Now let's start coding the backend. Add using ZXing; Namespace declare properties and constructors below sealed class.
  1. private MediaCapture _mediaCapture;  
  2. private byte[] imageBuffer;  
  3. public int exit = 0;  
  4. private MessageDialog dialog;  
  5. private ApplicationView currentView = ApplicationView.GetForCurrentView();  
Go to OnNavigatedTo Event and write the following code to Initialize the Scanner:
  1. protected override void OnNavigatedTo(NavigationEventArgs e)  
  2. {  
  3.    exit = 0;  
  4.    ScanQrCode();  
  5. }  
Step 5: Scan QR code method. In this first we need to initialize the camera before decoding the captured image.
  1. private async void ScanQrCode() {  
  2.     try {  
  3.         await InitializeQrCode();  
  4.   
  5.   
  6.         var imgProp = new ImageEncodingProperties {  
  7.             Subtype = "BMP", Width = 380, Height = 380  
  8.         };  
  9.         var bcReader = new BarcodeReader();  
  10.   
  11.   
  12.         while (exit == 0) {  
  13.             var stream = new InMemoryRandomAccessStream();  
  14.             await _mediaCapture.CapturePhotoToStreamAsync(imgProp, stream);  
  15.   
  16.   
  17.             stream.Seek(0);  
  18.             var wbm = new WriteableBitmap(380, 380);  
  19.             await wbm.SetSourceAsync(stream);  
  20.             var result = bcReader.Decode(wbm);  
  21.   
  22.   
  23.             if (result != null) {  
  24.                 var torch = _mediaCapture.VideoDeviceController.TorchControl;  
  25.                 if (torch.Supported) torch.Enabled = false;  
  26.                 await _mediaCapture.StopPreviewAsync();  
  27.                 var msgbox = new MessageDialog(result.Text);  
  28.                 await msgbox.ShowAsync();  
  29.   
  30.   
  31.                 try {  
  32.                     StorageFolder folder = ApplicationData.Current.LocalFolder;  
  33.                     if (folder != null) {  
  34.                         //Saving Scan Text  
  35.                         StorageFile sampleFile = await folder.CreateFileAsync("sample.txt", CreationCollisionOption.ReplaceExisting);  
  36.                         await Windows.Storage.FileIO.WriteTextAsync(sampleFile, "Swift as a shadow");  
  37.   
  38.                         //Saving Scan Image  
  39.   
  40.                         StorageFile file = await folder.CreateFileAsync("imagefile" + ".jpg", CreationCollisionOption.ReplaceExisting);  
  41.                         using(var storageStream = await file.OpenAsync(FileAccessMode.ReadWrite)) {  
  42.                             var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, storageStream);  
  43.                             var pixelStream = wbm.PixelBuffer.AsStream();  
  44.                             var pixels = new byte[pixelStream.Length];  
  45.                             await pixelStream.ReadAsync(pixels, 0, pixels.Length);  
  46.   
  47.   
  48.                             encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore, (uint) wbm.PixelWidth, (uint) wbm.PixelHeight, 48, 48, pixels);  
  49.                             await encoder.FlushAsync();  
  50.                         }  
  51.   
  52.                     }  
  53.                     MyImage.Source = wbm;  
  54.   
  55.                     exit = 1;  
  56.                 } catch (Exception ex) {  
  57.                     MessageDialog dialog = new MessageDialog("Error while initializing media capture device: " + ex.Message);  
  58.                     dialog.ShowAsync();  
  59.                     GC.Collect();  
  60.                 }  
  61.   
  62.   
  63.                 //  
  64.             }  
  65.         }  
  66.     } catch {}  
  67. }  
Step 6: Camera Initialization with required features. So to scan perfectly we are enabling torch and continuous focus so that scanning QR| Barcode becomes fast and simpler.
  1. private async Task InitializeQrCode() {  
  2.     string error = null;  
  3.     try {  
  4.         //if (_mediaCapture == null)  
  5.         //{  
  6.         // Find all available webcams  
  7.         DeviceInformationCollection webcamList = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture);  
  8.   
  9.   
  10.         // Get the proper webcam (default one)  
  11.         DeviceInformation backWebcam = (from webcam in webcamList where webcam.IsEnabled select webcam).FirstOrDefault();  
  12.   
  13.   
  14.         // Initializing MediaCapture  
  15.   
  16.   
  17.         _mediaCapture = new MediaCapture();  
  18.         await _mediaCapture.InitializeAsync(new MediaCaptureInitializationSettings {  
  19.             VideoDeviceId = backWebcam.Id,  
  20.                 AudioDeviceId = "",  
  21.                 StreamingCaptureMode = StreamingCaptureMode.Video,  
  22.                 PhotoCaptureSource = PhotoCaptureSource.VideoPreview  
  23.         });  
  24.   
  25.   
  26.         // Adjust camera rotation for Phone  
  27.         _mediaCapture.SetPreviewRotation(VideoRotation.Clockwise90Degrees);  
  28.         _mediaCapture.SetRecordRotation(VideoRotation.Clockwise90Degrees);  
  29.   
  30.   
  31.         // Set the source of CaptureElement to MediaCapture  
  32.         captureElement.Source = _mediaCapture;  
  33.         await _mediaCapture.StartPreviewAsync();  
  34.   
  35.   
  36.         _mediaCapture.FocusChanged += _mediaCapture_FocusChanged;  
  37.   
  38.   
  39.         // Seetting Focus & Flash(if Needed)  
  40.   
  41.   
  42.         var torch = _mediaCapture.VideoDeviceController.TorchControl;  
  43.         if (torch.Supported) torch.Enabled = true;  
  44.   
  45.   
  46.         await _mediaCapture.VideoDeviceController.FocusControl.UnlockAsync();  
  47.         var focusSettings = new FocusSettings();  
  48.         focusSettings.AutoFocusRange = AutoFocusRange.FullRange;  
  49.         focusSettings.Mode = FocusMode.Continuous;  
  50.         focusSettings.WaitForFocus = true;  
  51.         focusSettings.DisableDriverFallback = false;  
  52.         _mediaCapture.VideoDeviceController.FocusControl.Configure(focusSettings);  
  53.         await _mediaCapture.VideoDeviceController.FocusControl.FocusAsync();  
  54.   
  55.   
  56.         //}  
  57.     } catch (Exception ex) {  
  58.         dialog = new MessageDialog("Error: " + ex.Message);  
  59.         dialog.ShowAsync();  
  60.     }  
  61. }  
Step 7: In Step 5 we are saving the result of scan in the storage folder, so that we can retrieve the image for cross verifying.

code

We have to encode the image properly while saving image to storage folder (like shown above) or else we will get blank images while retrieving the image .

Step 8: Now we have to stop the camera and unsubscribe from all camera related events in BacKkeyPress Event:
  1. protected override void OnNavigatedTo(NavigationEventArgs e) {  
  2.     Windows.Phone.UI.Input.HardwareButtons.BackPressed += HardwareButtons_BackPressed;  
  3. }  
  4.   
  5. private async void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e) {  
  6.     exit = 1;  
  7.     _mediaCapture.Dispose();  
  8.     if (this.Frame.CanGoBack) {  
  9.         e.Handled = true;  
  10.         this.Frame.GoBack();  
  11.     }  
  12. }  
Step 9: Now let's start creating UI for viewing image and create a blank template, name it View.

Create A Blank Template
  1. <Grid x:Name="LayoutRoot" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="#163146">  
  2.     <Grid.RowDefinitions>  
  3.         <RowDefinition Height="100" />  
  4.         <RowDefinition Height="Auto" />  
  5.         <RowDefinition Height="*" />  
  6.     </Grid.RowDefinitions>  
  7.     <StackPanel Grid.Row="1">  
  8.         <Image x:Name="myimage" Width="300" Height="300" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Stretch="Fill" />  
  9.         <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="20" Text="" TextWrapping="Wrap" />  
  10.     </StackPanel>  
  11. </Grid>  
Go to View.xaml.cs and write the following code in OnNavigatedTo Event.
  1. protected async override void OnNavigatedTo(NavigationEventArgs e) {  
  2.   
  3.     try {  
  4.         string fileName = "imagefile.jpg";  
  5.         StorageFolder myfolder = ApplicationData.Current.LocalFolder;  
  6.   
  7.   
  8.         BitmapImage bitmapImage = new BitmapImage();  
  9.   
  10.   
  11.         StorageFile sampleFile = await storageFolder.GetFileAsync("sample.txt");  
  12.         string text = await Windows.Storage.FileIO.ReadTextAsync(sampleFile);  
  13.         result.Text = text.ToString();  
  14.         StorageFile file = await myfolder.GetFileAsync(fileName);  
  15.   
  16.   
  17.         if (file != null) {  
  18.             var image = await Windows.Storage.FileIO.ReadBufferAsync(file);  
  19.   
  20.   
  21.             Uri uri = new Uri(file.Path);  
  22.   
  23.   
  24.             BitmapImage img = new BitmapImage(new Uri(file.Path));  
  25.   
  26.   
  27.             myimage.Source = img;  
  28.         } else {  
  29.             var messgeDialog = new MessageDialog("Something went Wrong ");  
  30.             messgeDialog.Commands.Add(new UICommand("Yes"));  
  31.             messgeDialog.Commands.Add(new UICommand("No"));  
  32.             messgeDialog.DefaultCommandIndex = 0;  
  33.             messgeDialog.CancelCommandIndex = 1;  
  34.             var result = await messgeDialog.ShowAsync();  
  35.             if (result.Label.Equals("Yes")) {}  
  36.         }  
  37.     } catch (Exception ex) {  
  38.         var messgeDialog = new MessageDialog("Theres no image to view :( ");  
  39.         messgeDialog.Commands.Add(new UICommand("ok"));  
  40.   
  41.   
  42.         messgeDialog.DefaultCommandIndex = 0;  
  43.         messgeDialog.CancelCommandIndex = 1;  
  44.         var result = await messgeDialog.ShowAsync();  
  45.         if (result.Label.Equals("ok")) {  
  46.             if (this.Frame.CanGoBack) {  
  47.                 this.Frame.GoBack();  
  48.   
  49.   
  50.             }  
  51.         }  
  52.     }   
  53. }  
Output of scan

Output

Now go to View

Now go to View

Feedback Note

Please share your thoughts, what you think about this post, Is this post really helpful for you? I always welcome if you drop comments on this post.

 


Similar Articles