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.
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:
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.
- <Grid x:Name="LayoutRoot" Height="640" Margin="0,0.333,0,-0.333" HorizontalAlignment="Left" VerticalAlignment="Top" Background="#163146">
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto" />
-
-
- <RowDefinition Height="*" />
- </Grid.RowDefinitions>
- <StackPanel Grid.Row="0" Height="110" Background=" #36B4A8" Orientation="Horizontal">
-
-
- <TextBlock Margin="12,40,0,0" FontFamily="Fonts/HelveticaNeue Thin.ttf#HelveticaNeue" FontSize="38" Foreground="White" Text="QR & BARCODE SCAN" />
- </StackPanel>
- <Grid Grid.Row="1" Background="#FFFFFF">
-
-
- <StackPanel Margin="12,100" HorizontalAlignment="Stretch" VerticalAlignment="Top" Orientation="Vertical">
- <StackPanel Height="50" Orientation="Horizontal" Tapped="StackPanel_Tapped">
-
-
- <Image HorizontalAlignment="Left" Source="Assets/QR Code-50.png" Stretch="Uniform" />
- <TextBlock Margin="8,8" FontFamily="Fonts/HelveticaNeue Thin.ttf#HelveticaNeue" FontSize="32" Foreground="#36B4A8" Text="Scan" />
- </StackPanel>
-
-
- <StackPanel Height="50" Margin="0,30" Orientation="Horizontal" Tapped="StackPanel_Tapped_1">
-
-
- <Image HorizontalAlignment="Left" Source="Assets/View File-50.png" Stretch="Uniform" />
- <TextBlock Margin="8,8" FontFamily="Fonts/HelveticaNeue Thin.ttf#HelveticaNeue" FontSize="32" Foreground="#36B4A8" Text="View" />
- </StackPanel>
- </StackPanel>
- </Grid>
- </Grid>
Output 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.
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.
- <Grid x:Name="LayoutRoot" Background="#163146" HorizontalAlignment="Left" VerticalAlignment="Top">
- <CaptureElement x:Name="captureElement" Stretch="UniformToFill" />
- </Grid>
Now let's start coding the backend. Add using ZXing; Namespace declare properties and constructors below sealed class.
- private MediaCapture _mediaCapture;
- private byte[] imageBuffer;
- public int exit = 0;
- private MessageDialog dialog;
- private ApplicationView currentView = ApplicationView.GetForCurrentView();
Go to OnNavigatedTo Event and write the following code to Initialize the Scanner:
- protected override void OnNavigatedTo(NavigationEventArgs e)
- {
- exit = 0;
- ScanQrCode();
- }
Step 5: Scan QR code method. In this first we need to initialize the camera before decoding the captured image.
- private async void ScanQrCode() {
- try {
- await InitializeQrCode();
-
-
- var imgProp = new ImageEncodingProperties {
- Subtype = "BMP", Width = 380, Height = 380
- };
- var bcReader = new BarcodeReader();
-
-
- while (exit == 0) {
- var stream = new InMemoryRandomAccessStream();
- await _mediaCapture.CapturePhotoToStreamAsync(imgProp, stream);
-
-
- stream.Seek(0);
- var wbm = new WriteableBitmap(380, 380);
- await wbm.SetSourceAsync(stream);
- var result = bcReader.Decode(wbm);
-
-
- if (result != null) {
- var torch = _mediaCapture.VideoDeviceController.TorchControl;
- if (torch.Supported) torch.Enabled = false;
- await _mediaCapture.StopPreviewAsync();
- var msgbox = new MessageDialog(result.Text);
- await msgbox.ShowAsync();
-
-
- try {
- StorageFolder folder = ApplicationData.Current.LocalFolder;
- if (folder != null) {
-
- StorageFile sampleFile = await folder.CreateFileAsync("sample.txt", CreationCollisionOption.ReplaceExisting);
- await Windows.Storage.FileIO.WriteTextAsync(sampleFile, "Swift as a shadow");
-
-
-
- StorageFile file = await folder.CreateFileAsync("imagefile" + ".jpg", CreationCollisionOption.ReplaceExisting);
- using(var storageStream = await file.OpenAsync(FileAccessMode.ReadWrite)) {
- var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, storageStream);
- var pixelStream = wbm.PixelBuffer.AsStream();
- var pixels = new byte[pixelStream.Length];
- await pixelStream.ReadAsync(pixels, 0, pixels.Length);
-
-
- encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore, (uint) wbm.PixelWidth, (uint) wbm.PixelHeight, 48, 48, pixels);
- await encoder.FlushAsync();
- }
-
- }
- MyImage.Source = wbm;
-
- exit = 1;
- } catch (Exception ex) {
- MessageDialog dialog = new MessageDialog("Error while initializing media capture device: " + ex.Message);
- dialog.ShowAsync();
- GC.Collect();
- }
-
-
-
- }
- }
- } catch {}
- }
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.
- private async Task InitializeQrCode() {
- string error = null;
- try {
-
-
-
- DeviceInformationCollection webcamList = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture);
-
-
-
- DeviceInformation backWebcam = (from webcam in webcamList where webcam.IsEnabled select webcam).FirstOrDefault();
-
-
-
-
-
- _mediaCapture = new MediaCapture();
- await _mediaCapture.InitializeAsync(new MediaCaptureInitializationSettings {
- VideoDeviceId = backWebcam.Id,
- AudioDeviceId = "",
- StreamingCaptureMode = StreamingCaptureMode.Video,
- PhotoCaptureSource = PhotoCaptureSource.VideoPreview
- });
-
-
-
- _mediaCapture.SetPreviewRotation(VideoRotation.Clockwise90Degrees);
- _mediaCapture.SetRecordRotation(VideoRotation.Clockwise90Degrees);
-
-
-
- captureElement.Source = _mediaCapture;
- await _mediaCapture.StartPreviewAsync();
-
-
- _mediaCapture.FocusChanged += _mediaCapture_FocusChanged;
-
-
-
-
-
- var torch = _mediaCapture.VideoDeviceController.TorchControl;
- if (torch.Supported) torch.Enabled = true;
-
-
- await _mediaCapture.VideoDeviceController.FocusControl.UnlockAsync();
- var focusSettings = new FocusSettings();
- focusSettings.AutoFocusRange = AutoFocusRange.FullRange;
- focusSettings.Mode = FocusMode.Continuous;
- focusSettings.WaitForFocus = true;
- focusSettings.DisableDriverFallback = false;
- _mediaCapture.VideoDeviceController.FocusControl.Configure(focusSettings);
- await _mediaCapture.VideoDeviceController.FocusControl.FocusAsync();
-
-
-
- } catch (Exception ex) {
- dialog = new MessageDialog("Error: " + ex.Message);
- dialog.ShowAsync();
- }
- }
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.
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:
- protected override void OnNavigatedTo(NavigationEventArgs e) {
- Windows.Phone.UI.Input.HardwareButtons.BackPressed += HardwareButtons_BackPressed;
- }
-
- private async void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e) {
- exit = 1;
- _mediaCapture.Dispose();
- if (this.Frame.CanGoBack) {
- e.Handled = true;
- this.Frame.GoBack();
- }
- }
Step 9: Now let's start creating UI for viewing image and create a blank template, name it View.
- <Grid x:Name="LayoutRoot" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="#163146">
- <Grid.RowDefinitions>
- <RowDefinition Height="100" />
- <RowDefinition Height="Auto" />
- <RowDefinition Height="*" />
- </Grid.RowDefinitions>
- <StackPanel Grid.Row="1">
- <Image x:Name="myimage" Width="300" Height="300" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Stretch="Fill" />
- <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="20" Text="" TextWrapping="Wrap" />
- </StackPanel>
- </Grid>
Go to View.xaml.cs and write the following code in OnNavigatedTo Event.
- protected async override void OnNavigatedTo(NavigationEventArgs e) {
-
- try {
- string fileName = "imagefile.jpg";
- StorageFolder myfolder = ApplicationData.Current.LocalFolder;
-
-
- BitmapImage bitmapImage = new BitmapImage();
-
-
- StorageFile sampleFile = await storageFolder.GetFileAsync("sample.txt");
- string text = await Windows.Storage.FileIO.ReadTextAsync(sampleFile);
- result.Text = text.ToString();
- StorageFile file = await myfolder.GetFileAsync(fileName);
-
-
- if (file != null) {
- var image = await Windows.Storage.FileIO.ReadBufferAsync(file);
-
-
- Uri uri = new Uri(file.Path);
-
-
- BitmapImage img = new BitmapImage(new Uri(file.Path));
-
-
- myimage.Source = img;
- } else {
- var messgeDialog = new MessageDialog("Something went Wrong ");
- messgeDialog.Commands.Add(new UICommand("Yes"));
- messgeDialog.Commands.Add(new UICommand("No"));
- messgeDialog.DefaultCommandIndex = 0;
- messgeDialog.CancelCommandIndex = 1;
- var result = await messgeDialog.ShowAsync();
- if (result.Label.Equals("Yes")) {}
- }
- } catch (Exception ex) {
- var messgeDialog = new MessageDialog("Theres no image to view :( ");
- messgeDialog.Commands.Add(new UICommand("ok"));
-
-
- messgeDialog.DefaultCommandIndex = 0;
- messgeDialog.CancelCommandIndex = 1;
- var result = await messgeDialog.ShowAsync();
- if (result.Label.Equals("ok")) {
- if (this.Frame.CanGoBack) {
- this.Frame.GoBack();
-
-
- }
- }
- }
- }
Output of scan 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.