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

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

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

MainForm.vb

Imports System.ComponentModel
Imports System.Drawing
Imports System.Media
Imports System.Reflection
Imports System.Text
Imports System.Threading
Imports System.Windows.Forms
Imports Bytescout.BarCodeReader
Imports TouchlessLib

Public Class MainForm

	' Scan delay, ms.
	Const SCAN_DELAY As Integer = 1500 ' scan barcodes every 1.5 sec

	' Touchless SDK library manager (to use it you should have TouchlessLib.dll referenced and WebCamLib.dll in the build output directory)
	Dim ReadOnly _touchlessLibManager As TouchlessMgr

	' Background thread for barcode scanning
	Dim ReadOnly _backgroundWorker As New BackgroundWorker
	' Synchronization event
	Dim ReadOnly _synchronizationEvent As New AutoResetEvent(False)

	' Form constructor
	Public Sub New()

		InitializeComponent()

		' Create Touchless library manager
		_touchlessLibManager = New TouchlessMgr()

		' Setup background worker
		_backgroundWorker.WorkerSupportsCancellation = True
		AddHandler _backgroundWorker.DoWork, AddressOf BackgroundWorker_DoWork
		AddHandler _backgroundWorker.RunWorkerCompleted, AddressOf BackgroundWorker_RunWorkerCompleted

	End Sub

	' On form loading 
	Private Sub MainForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load

		' Fill devices combobox with available video cameras
		For Each camera As Camera In _touchlessLibManager.Cameras
			cmbCamera.Items.Add(camera)
		Next

		' Select the first available camera. See also cmbCamera_SelectedIndexChanged event handler.
		If _touchlessLibManager.Cameras.Count > 0 Then
			cmbCamera.SelectedItem = _touchlessLibManager.Cameras(0)
		Else
			MessageBox.Show("No video camera available. Please connect the camera.")
		End If

		' Populate barcode types combobox
		PopulateBarcodeTypesCombobox()
		' Select some default barcode type
		cmbBarcodeType.SelectedItem = "QRCode"

	End Sub

	Private Sub PopulateBarcodeTypesCombobox()

		cmbBarcodeType.Items.Clear()

		For Each propertyInfo As PropertyInfo In GetType(BarcodeTypeSelector).GetProperties()
			cmbBarcodeType.Items.Add(propertyInfo.Name)
		Next

	End Sub

	' On camera selected
	Private Sub cmbCamera_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cmbCamera.SelectedIndexChanged

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

		If cmbCamera.SelectedIndex <> -1 Then

			Dim camera As Camera = _touchlessLibManager.Cameras(cmbCamera.SelectedIndex)

			If camera IsNot Nothing Then
				' Set camera output image dimensions
				camera.CaptureWidth = Integer.Parse(tbCameraWidth.Text)
				camera.CaptureHeight = Integer.Parse(tbCameraHeight.Text)

				AddHandler camera.OnImageCaptured, AddressOf CurrentCamera_OnImageCaptured

				' Select the camera
				_touchlessLibManager.CurrentCamera = camera

			End If

		End If

	End Sub

	Private Sub btnUpdateCameraImageDimensions_Click(sender As Object, e As EventArgs) Handles btnUpdateCameraImageDimensions.Click

		If _touchlessLibManager.CurrentCamera IsNot Nothing Then

			' Update camera's output image dimensions
			_touchlessLibManager.CurrentCamera.CaptureWidth = Integer.Parse(tbCameraWidth.Text)
			_touchlessLibManager.CurrentCamera.CaptureHeight = Integer.Parse(tbCameraHeight.Text)

		End If

	End Sub

	Private Sub StartDecoding()

		If cmbCamera.SelectedIndex = -1 Then
			Return
		End If

		' Clear the output text box
		rtbFoundBarcodes.Clear()

		' Check if we have camera selected
		If cmbCamera.SelectedIndex <> -1 Then

			' Start the decoding in the background thread
			Dim barcodeTypesToFind As BarcodeTypeSelector = GetBarcodeTypeFromCombobox()
			_backgroundWorker.RunWorkerAsync(barcodeTypesToFind)

			UpdateControls(True)
		Else
			MessageBox.Show("Please select the camera first!")
		End If

	End Sub

	Private Sub StopDecoding()

		_backgroundWorker.CancelAsync()

		' Wait until BackgroundWorker finished
		If _backgroundWorker.IsBusy Then
			_synchronizationEvent.WaitOne()
		End If

		UpdateControls(False)

	End Sub

	Private Sub UpdateControls(started As Boolean)

		If started Then
			btnStart.Enabled = False
			btnStop.Enabled = True
			cmbBarcodeType.Enabled = False
			cmbCamera.Enabled = False
			tbCameraHeight.Enabled = False
			tbCameraWidth.Enabled = False
			btnUpdateCameraImageDimensions.Enabled = False
			cbStopOnFirstBarcode.Enabled = False
			lblScanning.Visible = True
			lblScanning.Text = "Scanning..."
		Else
			btnStart.Enabled = True
			btnStop.Enabled = False
			cmbBarcodeType.Enabled = True
			cmbCamera.Enabled = True
			cbStopOnFirstBarcode.Enabled = True
			tbCameraHeight.Enabled = True
			tbCameraWidth.Enabled = True
			btnUpdateCameraImageDimensions.Enabled = True
			lblScanning.Visible = True
		End If

	End Sub

	Private Sub CurrentCamera_OnImageCaptured(sender As Object, e As CameraEventArgs)

		pictureBoxPreview.Image = e.Image

	End Sub

	Private Sub btnStart_Click(sender As Object, e As EventArgs) Handles btnStart.Click

		StartDecoding()

	End Sub

	Private Sub btnStop_Click(sender As Object, e As EventArgs) Handles btnStop.Click

		StopDecoding()

	End Sub

	' Background thread procedure used by BackgroundWorker
	Private Sub BackgroundWorker_DoWork(sender As Object, e As DoWorkEventArgs)

		Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)
		Dim barcodeTypesToFind As BarcodeTypeSelector = CType(e.Argument, BarcodeTypeSelector)

		' Create and setup barcode reader instance
		Using reader As New Reader

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

			reader.BarcodeTypesToFind = barcodeTypesToFind

			' Work while not canceled
			While True

				' Check cancellation
				If worker.CancellationPending Then
					e.Cancel = True
					_synchronizationEvent.Set()
					Return
				End If

				' Get image from camera by invoking method from UI thread
				Dim bitmap As Bitmap = CType(Invoke(New GetCameraImageDelegate(AddressOf GetCameraImage)), Bitmap)
				If bitmap Is Nothing Then
					e.Result = nothing
					return
				End If

				' Search the image for barcodes
				Dim result As FoundBarcode() = reader.ReadFrom(bitmap)

				' Update UI asynchronously
				BeginInvoke(New Action(Of FoundBarcode())(AddressOf UpdateStatus), New Object() { result })

				' Pause
				Thread.Sleep(SCAN_DELAY)

			End While

		End Using

	End Sub

	Delegate Function GetCameraImageDelegate() As Bitmap

	Private Function GetCameraImage() As Bitmap

		If Not IsDisposed and Not Disposing and _touchlessLibManager.CurrentCamera IsNot Nothing Then
			return _touchlessLibManager.CurrentCamera.GetCurrentImage()	
		End If

		Return Nothing

	End Function

	' Update UI with found barcodes information
	Private Sub UpdateStatus(foundBarcodes As FoundBarcode())

		If foundBarcodes IsNot Nothing And foundBarcodes.Length > 0 Then

			' Play sound if we found any barcode
			SystemSounds.Beep.Play()

			Dim stringBuilder As StringBuilder = New StringBuilder()

			stringBuilder.AppendFormat("Time: {0:HH:mm:ss:tt}", DateTime.Now)
			stringBuilder.AppendLine()

			' Display found barcodes in the output text box
			For Each barcode As FoundBarcode In foundBarcodes
				stringBuilder.AppendFormat("Found barcode: {0} {1}", barcode.Type, barcode.Value)
				stringBuilder.AppendLine()
			Next

			rtbFoundBarcodes.Text = stringBuilder.ToString()

			' Update status text with number of found barcodes
			lblFoundBarcodes.Text = String.Format("Found {0} barcodes:", foundBarcodes.Length)

		End If

		' Make "Scanning..." label flicker.
		lblScanning.Visible = Not lblScanning.Visible
		lblScanning.Refresh()

		' Check if we need to stop on first barcode found
		If cbStopOnFirstBarcode.Checked And foundBarcodes IsNot Nothing And foundBarcodes.Length > 0 Then
			StopDecoding()
		End If

	End Sub

	' Background thread is finished
	Private Sub BackgroundWorker_RunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs)

		' Update UI asynchronously
		BeginInvoke(New Action(Of RunWorkerCompletedEventArgs)(AddressOf OnBackgroundWorkerFinished), New Object() {e})

	End Sub

	Private Sub OnBackgroundWorkerFinished(completedEventArgs As RunWorkerCompletedEventArgs)

		If completedEventArgs.Cancelled Then
			lblScanning.Text = "Stopped"
		ElseIf completedEventArgs.Error IsNot Nothing Then
			lblScanning.Text = "Error: " + completedEventArgs.Error.Message
		Else
			lblScanning.Text = "Done!"
		End If

		UpdateControls(False)

	End Sub

	Private Function GetBarcodeTypeFromCombobox() As BarcodeTypeSelector

		Dim result As BarcodeTypeSelector = New BarcodeTypeSelector()

		Dim selectedBarcodeTypeName As String = CType(cmbBarcodeType.SelectedItem, String)

		Dim propertyInfo As PropertyInfo = GetType(BarcodeTypeSelector).GetProperty(selectedBarcodeTypeName)
		propertyInfo.SetValue(result, True, Nothing)

		Return result

	End Function

	Protected Overrides Sub OnClosing(e As CancelEventArgs)
		
		StopDecoding()
		
		_touchlessLibManager.Dispose()
		
		MyBase.OnClosing(e)

	End Sub

	Private Sub btnExit_Click(sender As Object, e As EventArgs) Handles btnExit.Click

		DialogResult = DialogResult.OK
		Close()

	End Sub

	Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

		Try
			if _touchlessLibManager.CurrentCamera IsNot Nothing
				_touchlessLibManager.CurrentCamera.ShowPropertiesDialog(Handle)
			End If
		Catch ex As Exception
			MessageBox.Show(ex.Message)
		End Try
		
	End Sub
End Class

Program.vb

Imports System.Collections.Generic
Imports System.Windows.Forms

NotInheritable Class Program
	Private Sub New()
	End Sub
	''' <summary>
	''' The main entry point for the application.
	''' </summary>
	<MTAThread> _
	Friend Shared Sub Main()
		Application.EnableVisualStyles()
		Application.SetCompatibleTextRenderingDefault(False)

		Dim dlg As New MainForm()
		dlg.ShowDialog()
	End Sub
End Class

prev
next