ByteScout Barcode Reader SDK - VB.NET - Read From Live Video Cam (WPF) - ByteScout
Announcement
Our ByteScout SDK products are sunsetting as we focus on expanding new solutions.
Learn More Open modal
Close modal
Announcement Important Update
ByteScout SDK Sunsetting Notice
Our ByteScout SDK products are sunsetting as we focus on our new & improved solutions. Thank you for being part of our journey, and we look forward to supporting you in this next chapter!

ByteScout Barcode Reader SDK – VB.NET – Read From Live Video Cam (WPF)

  • Home
  • /
  • Articles
  • /
  • ByteScout Barcode Reader SDK – VB.NET – Read From Live Video Cam (WPF)

ByteScout Barcode Reader SDK – VB.NET – Read From Live Video Cam (WPF)

Application.xaml.vb

Class Application

    ' Application-level events, such as Startup, Exit, and DispatcherUnhandledException
    ' can be handled in this file.

End Class

MainWindow.xaml.vb

Imports System.ComponentModel
Imports System.Drawing
Imports System.Drawing.Imaging
Imports System.IO
Imports System.Reflection
Imports System.Threading
Imports System.Windows.Threading
Imports Bytescout.BarCodeReader
Imports TouchlessLib

Public Class MainWindow

    ' Touchless lib manager object (to use it you should have TouchlessLib.dll and WebCamLib.dll)
    Private _touchlessMgr As TouchlessMgr

    ' USED IN POPUP MODE ONLY (see ShowScanPopup() method)
    ' Close or not on the first barcode found
    ' (results are saved in m_foundBarcodes)
    Public Property CloseOnFirstBarcodeFound As Boolean = False

    ' Indicates if the form is closed
    Public Property IsClosed As Boolean = False

    ' Background processing object
    Private _backgroundWorker As New BackgroundWorker()

    ' Barcode type to scan
    Private _barcodeTypeToFind As New BarcodeTypeSelector()

    ' Array with decoded barcodes from the last scanning session.
    Public Property FoundBarcodes As FoundBarcode() = Nothing

    ' Scanning delay (ms); default is to scan every 800 ms.
    Const ScanDelay As Integer = 800

    ' Internal varaible to indicate the status.
    Public Shared Status As Boolean = True

    Public Sub New()

        InitializeComponent()

        lblScanning.Visibility = Visibility.Collapsed

        _backgroundWorker.WorkerSupportsCancellation = True
        AddHandler _backgroundWorker.DoWork, AddressOf BackgroundWorker_DoWork
        AddHandler _backgroundWorker.RunWorkerCompleted, AddressOf BackgroundWorker_RunWorkerCompleted

    End Sub

    Delegate Sub MyDelegate()

    ' Searches for barcodes in bitmap object
    Private Function FindBarcodes(bitmap As Bitmap) As FoundBarcode()

        Dim reader As New Bytescout.BarCodeReader.Reader()

        Try
            reader.RegistrationName = "demo"
            reader.RegistrationKey = "demo"

            Me.Dispatcher.Invoke(DispatcherPriority.Normal, Sub() UpdateBarcodeTypeToFindFromCombobox())

            reader.BarcodeTypesToFind = _barcodeTypeToFind

            Dim result As FoundBarcode() = reader.ReadFrom(bitmap)
            Dim timeNow As String = String.Format("{0:HH:mm:ss:tt}", DateTime.Now)

            Dispatcher.Invoke(DispatcherPriority.Normal,
                              Sub()
                                  If result IsNot Nothing And result.Length > 0 Then
                                      textAreaBarcodes.SelectAll()
                                      textAreaBarcodes.Selection.Text = Environment.NewLine & "Time: " & timeNow & Environment.NewLine

                                      ' insert barcodes into text box
                                      For Each barcode As FoundBarcode In result
                                          ' make a sound that we found the barcode
                                          Console.Beep()
                                          'form the string with barcode value
                                          Dim barcodeValue As String = String.Format("Found: {0} {1}" & Environment.NewLine, barcode.Type, barcode.Value)
                                          ' add barcode to the text area output
                                          textAreaBarcodes.AppendText(barcodeValue & Environment.NewLine)
                                          ' add barcode to the list of saved barcodes
                                          lblFoundBarcodes.Content = String.Format("Found {0} barcodes:", result.Length)
                                      Next
                                  End If

                                  ' make "Scanning..." label flicker
                                  If lblScanning.Visibility = Visibility.Collapsed Then
                                      lblScanning.Visibility = Visibility.Visible
                                  Else
                                      lblScanning.Visibility = Visibility.Collapsed
                                  End If
                              End Sub)
            ' return found barcodes
            Return result

        Finally
            reader.Dispose()
        End Try

    End Function

    ' Updates barcode type filter according with combobox selection
    Private Sub UpdateBarcodeTypeToFindFromCombobox()

        Dim selectedItemText As String = cbBarCodeType.Text

        If String.IsNullOrEmpty(selectedItemText) Then Throw New Exception("Empty barcode type selection.")

        _barcodeTypeToFind.Reset()

        ' Iterate through BarcodeTypeSelector bool properties 
        ' and enable property by barcode name selected in the combobox
        For Each propertyInfo As PropertyInfo In GetType(BarcodeTypeSelector).GetProperties()

            ' Skip readonly properties
            If Not propertyInfo.CanWrite Then
                Continue For
            End If

            If propertyInfo.Name = selectedItemText Then
                propertyInfo.SetValue(_barcodeTypeToFind, True, Nothing)
            End If
        Next

    End Sub

    Private Sub Window_Loaded(sender As System.Object, e As RoutedEventArgs) Handles MyBase.Loaded

        'Populate barcode types into the combobox
        PopulateBarcodeTypesCombobox()

        InitCamera()

        StartDecoding()

    End Sub

    Private Sub InitCamera()

        Try
            ' Create Touchless lib manager to work with video camera
            _touchlessMgr = New TouchlessMgr()

            ' Iterate through available video camera devices
            For Each camera As Camera In _touchlessMgr.Cameras
                ' Add to list of available camera devices
                cbCamera.Items.Add(camera)
            Next

            ' Select first available camera
            cbCamera.SelectedItem = _touchlessMgr.Cameras(0)

            ' Setting default image dimensions; see also camera selection event.
            _touchlessMgr.Cameras(0).CaptureWidth = Integer.Parse(tbCameraWidth.Text)
            _touchlessMgr.Cameras(0).CaptureHeight = Integer.Parse(tbCameraHeight.Text)

        Catch exception As Exception
            MessageBox.Show("No video camera available. Please connect camera." + Environment.NewLine + exception.Message)
        End Try

    End Sub

    Sub StartDecoding()

        UpdateCameraSelection()

        ' Clear the text box output
        Dim txt As New TextRange(textAreaBarcodes.Document.ContentStart, textAreaBarcodes.Document.ContentEnd)
        txt.Text = ""

        ' Clean list of found barcodes
        FoundBarcodes = Nothing

        ' Check camera selected
        If cbCamera.SelectedIndex <> -1 Then

            ' Set status
            Status = True

            ' Update UI buttons
            btnStart.IsEnabled = False
            btnStop.IsEnabled = True
            cbBarCodeType.IsEnabled = False
            cbCamera.IsEnabled = False
            tbCameraHeight.IsEnabled = False
            tbCameraWidth.IsEnabled = False
            lblScanning.Content = "Scanning..."

            ' Start the decoding thread
            _backgroundWorker.RunWorkerAsync(CloseOnFirstBarcodeFound)

        Else
            MessageBox.Show("Please select camera")
        End If

    End Sub


    Private Sub Window_Closing(sender As System.Object, e As CancelEventArgs) Handles MyBase.Closing
        Deinitialize()
    End Sub

    Private Sub cbCamera_SelectionChanged(sender As System.Object, e As SelectionChangedEventArgs) Handles cbCamera.SelectionChanged
        UpdateCameraSelection()
    End Sub

    Private Sub btnStart_Click(sender As System.Object, e As RoutedEventArgs) Handles btnStart.Click
        StartDecoding()
    End Sub

    Private Sub btnStop_Click(sender As System.Object, e As RoutedEventArgs) Handles btnStop.Click
        StopDecoding()
    End Sub

    Private Sub btnExit_Click(sender As System.Object, e As RoutedEventArgs) Handles btnExit.Click
        Close()
    End Sub

    Private Sub btnTryPopup_Click(sender As System.Object, e As RoutedEventArgs) Handles btnTryPopup.Click

        ' Stop scan if any
        StopDecoding()

        ' Deinit the current camera
        DeinitCamera()

        ShowScanPopup()

        ' Reinit current camera
        InitCamera()

    End Sub

    Sub BackgroundWorker_DoWork(sender As Object, e As DoWorkEventArgs)

        Dim worker As BackgroundWorker = sender
        Dim closeOnFirstBarcode As Boolean = e.Argument

        While True

            ' Work till user canceled the scan
            If worker.CancellationPending Then
                e.Cancel = True
                Return
            End If

            ' Get current frame bitmap from camera using Touchless lib
            Dim bitmap As Bitmap = _touchlessMgr.CurrentCamera.GetCurrentImage()

            ' Search barcodes
            Dim result As FoundBarcode() = Nothing

            If bitmap IsNot Nothing Then result = FindBarcodes(bitmap)

            ' Check if we need to stop on first barcode found
            If closeOnFirstBarcode AndAlso result IsNot Nothing AndAlso result.Length > 0 Then
                e.Result = result
                Return
            End If

            ' Wait a little to lower CPU load
            Thread.Sleep(ScanDelay)

        End While


    End Sub

    Sub BackgroundWorker_RunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs)

        ' Clear last results
        FoundBarcodes = Nothing

        If e.Cancelled Then
            lblScanning.Content = "Canceled"
        ElseIf e.Error IsNot Nothing Then
            lblScanning.Content = "Error: " & e.Error.Message
        Else
            lblScanning.Content = "Done."
            FoundBarcodes = e.Result
        End If

        StopDecoding()

    End Sub

    ' Update picture box with the latest frame from video camera
    Sub CurrentCamera_OnImageCaptured(sender As Object, e As CameraEventArgs)
        ' You can change image dimensions if needed
        '_touchlessMgr.CurrentCamera.CaptureWidth = 320
        '_touchlessMgr.CurrentCamera.CaptureHeight = 240
        Dispatcher.Invoke(DispatcherPriority.Normal, Sub()
                                                         If _touchlessMgr IsNot Nothing Then

                                                             pictureVideoPreview.BeginInit()
                                                             Dim imageSource As BitmapImage = BitmapToImageSource(_touchlessMgr.CurrentCamera.GetCurrentImage(), ImageFormat.Png)

                                                             Dim st = New ScaleTransform()
                                                             st.ScaleX = 320.0F / imageSource.PixelWidth
                                                             st.ScaleY = 240.0F / imageSource.PixelHeight

                                                             pictureVideoPreview.Source = New TransformedBitmap(imageSource, st)
                                                             pictureVideoPreview.EndInit()
                                                             pictureVideoPreview.UpdateLayout()

                                                         End If
                                                     End Sub)
    End Sub

    Function BitmapToImageSource(bitmap As Bitmap, imageFormat As ImageFormat) As BitmapImage

        Using memoryStream As New MemoryStream

            bitmap.Save(memoryStream, imageFormat)
            memoryStream.Position = 0

            Dim bitmapImage As New BitmapImage()
            bitmapImage.BeginInit()
            bitmapImage.StreamSource = memoryStream
            bitmapImage.CacheOption = BitmapCacheOption.OnLoad
            bitmapImage.EndInit()

            Return bitmapImage
        End Using

    End Function

    Sub StopDecoding()

        _backgroundWorker.CancelAsync()

        ' Update UI elements
        lblScanning.Visibility = Visibility.Collapsed

        ' Change working status
        Status = False

        btnStart.IsEnabled = True
        btnStop.IsEnabled = False

        cbBarCodeType.IsEnabled = True
        cbCamera.IsEnabled = True

        tbCameraHeight.IsEnabled = True
        tbCameraWidth.IsEnabled = True

        If CloseOnFirstBarcodeFound Then
            If FoundBarcodes IsNot Nothing AndAlso FoundBarcodes.Length > 0 Then
                Close()
            End If
        End If

    End Sub

    Sub UpdateCameraSelection()

        If cbCamera.Items.Count > 0 And cbCamera.SelectedIndex > -1 Then

            If _touchlessMgr.CurrentCamera IsNot Nothing Then
                RemoveHandler _touchlessMgr.CurrentCamera.OnImageCaptured, AddressOf CurrentCamera_OnImageCaptured
            End If

            _touchlessMgr.CurrentCamera = Nothing

            Dim currentCamera As Camera = _touchlessMgr.Cameras(cbCamera.SelectedIndex)

            ' Setting camera output image dimensions
            currentCamera.CaptureWidth = Integer.Parse(tbCameraWidth.Text)
            currentCamera.CaptureHeight = Integer.Parse(tbCameraHeight.Text)

            _touchlessMgr.CurrentCamera = currentCamera
            AddHandler _touchlessMgr.CurrentCamera.OnImageCaptured, AddressOf CurrentCamera_OnImageCaptured

        End If
    End Sub

    Sub PopulateBarcodeTypesCombobox()

        cbBarCodeType.Items.Clear()
        Dim items As New List(Of String)()

        For Each propertyInfo As PropertyInfo In GetType(BarcodeTypeSelector).GetProperties()
            ' Skip readonly properties
            If Not propertyInfo.CanWrite Then
                Continue For
            End If

            items.Add(propertyInfo.Name)
        Next

        items.Sort()
        cbBarCodeType.ItemsSource = items

        ' Select first item in combobox (first is "Find All")
        cbBarCodeType.SelectedItem = cbBarCodeType.Items(0)

    End Sub

    Sub Deinitialize()

        ' Cancel decoding thread
        _backgroundWorker.CancelAsync()

        ' Deinit camera
        DeinitCamera()

        ' Mark as closed
        _isClosed = True

    End Sub

    Sub DeinitCamera()

        If _touchlessMgr IsNot Nothing Then
            RemoveHandler _touchlessMgr.CurrentCamera.OnImageCaptured, AddressOf CurrentCamera_OnImageCaptured
            _touchlessMgr.CurrentCamera = Nothing
        End If

        If cbCamera.SelectedItem IsNot Nothing Then
            cbCamera.SelectedItem = Nothing
        End If

        cbCamera.Items.Clear()
        _touchlessMgr = Nothing

        Thread.Sleep(500)

    End Sub

    Sub ShowScanPopup()

        ' Create another MainWindow instance to scan barcodes
        Dim popup As New MainWindow()
        ' Set new popup position shifted by 20 pixels
        popup.Left = Left + 20
        popup.Top = Top + 20

        ' Set the new popup window to close on first found barcode
        popup.CloseOnFirstBarcodeFound = True

        ' Hide btnTryPopup button 
        popup.btnTryPopup.Visibility = Visibility.Hidden
        popup.btnStop.Visibility = Visibility.Hidden
        popup.btnStart.Visibility = Visibility.Hidden

        ' Set the popup title
        popup.Title = "POPUP DIALOG - ONE-TIME SCAN"

        ' Show the dialog
        popup.Show()

        ' Now wait while the popup is closed (it will be closed on barcode found or canceled)
        While Not popup.IsClosed
            ' HACK: Simulate "DoEvents"
            Dispatcher.Invoke(DispatcherPriority.Background, Sub() Thread.Sleep(20))
            Thread.Sleep(20)
        End While

        ' Checking if one-time scan dialog found barcodes 
        If popup.FoundBarcodes IsNot Nothing AndAlso popup.FoundBarcodes.Length > 0 Then
            MessageBox.Show("Popup scan found the barcode: " & Environment.NewLine & popup.FoundBarcodes(0).Value, "POPUP RESULT")
        Else
            MessageBox.Show("Popup canceled. Returning to the main window")
        End If

        ' Close the dialog
        popup.Close()

    End Sub

End Class

Tutorials:

prev
next