This tutorial shows how to use the LEADTOOLS Multimedia SDK to create a WinForms C# application that uses the CaptureCtrl
with the [LEAD Video Callback Filter] to perform live capture of barcodes using a supported video device, like a webcam.
Overview | |
---|---|
Summary | This tutorial covers how to implement live capture of barcodes from a supported video device (e.g., webcam) in a WinForms C# application. |
Completion Time | 30 minutes |
Visual Studio Project | Download tutorial project (10 KB) |
Platform | WinForms C# Application |
IDE | Visual Studio 2022 |
Development License | Download LEADTOOLS |
The [LEAD Video Callback Filter] is an in-place filter which calls a method or a user callback interface each time it receives a frame. It can be used to access image data for processing and recognition.
Get familiar with the basic steps of creating a project by reviewing the Add References and Set a License tutorial, before working on the Detect and Extract Barcodes Using Live Capture - WinForms C# tutorial.
Start with a copy of the project created in the Add References and Set a License tutorial. If the project is not available, follow the steps in that tutorial to create it.
If NuGet references are used, this tutorial requires the following NuGet package:
Leadtools.Barcode
Leadtools.Multimedia
If local DLL references are used, the following DLLs are needed. The DLLs are located at <INSTALL_DIR>\LEADTOOLS23\Bin\net
:
Leadtools.dll
Leadtools.Barcode.dll
Leadtools.Core.dll
Leadtools.Multimedia.dll
The tutorial also requires adding a reference to the following COM Library:
LEAD Video Callback Filter (2.0) Library
This tutorial also requires changing the target platform to x86
.
This can be found on the top navigation bar at: Build -> Configuration Manager -> Platform.
Note: Different SDK features require different references. For a complete list, refer to Multimedia Files You Must Include With Your Application. For a complete list of which non-Multimedia DLLs are required for your application, refer to Files to be Included With Your Application.
The License unlocks the features needed for the project. It must be set before any toolkit function is called. For details, including tutorials for different platforms, refer to Setting a Runtime License.
There are two types of runtime licenses:
Note: Adding LEADTOOLS NuGet and local references and setting a license are covered in more detail in the Add References and Set a License tutorial.
With the project created, the references added, and the license set, coding can begin.
In the Solution Explorer, right-click on the project and select Add -> New Item. Select the Class
option and name the class LMVMyUserCallback.cs
, then click Add.
The LMVMyUserCallback
class will use the frame received by the callback filter to instantiate a RasterImage
object with the image data and use a BarcodeReader
instance to detect any barcode in the image. If found, the detected BarcodeData
will be passed to an event handler in the form.
Add the following statements to the using
block at the top of the LMVMyUserCallback
class.
using Leadtools;
using Leadtools.Barcode;
using LMVCallbackLib;
Add the following code to create the event arguments class which will be used to pass the detected BarcodeData
to the form.
public class BarcodeFoundEventArgs : EventArgs
{
public BarcodeData data { get; private set; }
public BarcodeFoundEventArgs(BarcodeData barcodeData)
{
data = barcodeData;
}
}
Use the code below for LMVMyUserCallback
, which is a custom interface of the ILMVUserCallback
filter interface.
public class LMVMyUserCallback : ILMVUserCallback
{
// Event used in the form for when a barcode is found
public delegate void BarcodeFoundHandler(object sender, BarcodeFoundEventArgs e);
public event BarcodeFoundHandler OnBarcodeFound;
private BarcodeEngine engine = new BarcodeEngine();
private RasterImage img = null;
public LMVMyUserCallback()
{
engine.Reader.ImageType = BarcodeImageType.Picture;
}
public void ReceiveProc(int pData, int lWidth, int lHeight, int lBitCount, int lSize, int bTopDown)
{
try
{
// Create new RasterImage object using frame properties
RasterViewPerspective viewPerspective;
if (bTopDown == 1)
viewPerspective = RasterViewPerspective.TopLeft;
else
viewPerspective = RasterViewPerspective.BottomLeft;
if (img == null || img.IsDisposed)
{
img = new RasterImage(
RasterMemoryFlags.User,
lWidth,
lHeight,
lBitCount,
RasterByteOrder.Bgr,
viewPerspective,
null,
IntPtr.Zero,
0);
}
// Copy image data from callback
img.SetUserData(new IntPtr(pData), lSize);
// Detect and read barcode in image
var data = engine.Reader.ReadBarcode(img, LeadRect.Empty, BarcodeSymbology.Unknown);
// When found, pass the data to the event handler
if (data != null)
{
var barcodeFoundEvent = new BarcodeFoundEventArgs(data);
OnBarcodeFound(this, barcodeFoundEvent);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
if (img != null)
img.Dispose();
}
}
}
In the Solution Explorer, right-click on Form1.cs
and select View Code to display the code-behind the form. Add the following statements to the using
block at the top.
using Leadtools;
using Leadtools.Multimedia;
using LMVCallbackLib;
Add a CaptureCtrl
control, a LMVCallback
callback, and the LMVMyUserCallback
custom interface as global variables.
private CaptureCtrl capture1;
private LMVCallback lmvCallback;
private LMVMyUserCallback lmvMyUserCallback;
bool IsCapturing = false;
Add the CaptureCtrl
control to the form and call the InsertCallbackFilter()
method to insert the lmvCallBack
filter.
public Form1()
{
InitializeComponent();
SetLicense();
// Add Capture Control
capture1 = new CaptureCtrl { Dock = DockStyle.Fill };
capture1.VideoDevices.Selection = -1;
Controls.Add(capture1);
InsertCallbackFilter();
}
Create a new method named InsertCallbackFilter()
, which will be called inside Form1()
as shown above. Add the code below to insert the lmvCallBack
filter and assign an OnBarcodeFound
event handler that will trigger when a barcode is detected.
private void InsertCallbackFilter()
{
try
{
Processor videoCallback = capture1.VideoProcessors.Callback;
capture1.SelectedVideoProcessors.Add(videoCallback);
lmvCallback = (LMVCallback)capture1.GetSubObject(CaptureObject.SelVideoProcessor);
lmvMyUserCallback = new LMVMyUserCallback();
lmvCallback.ReceiveProcObj = lmvMyUserCallback;
lmvMyUserCallback.OnBarcodeFound += LmvMyUserCallback_OnBarcodeFound;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Add the code below to the OnBarcodeFound
event to display the barcode information to the user.
private void LmvMyUserCallback_OnBarcodeFound(object sender, BarcodeFoundEventArgs e)
{
MessageBox.Show(e.data.Symbology.ToString() + " Barcode Found. Value: " + e.data.Value);
StopCapture();
}
In the Solution Explorer, double-click Form1.cs
to display it in the Designer. Click the Events icon in the Properties Windows. Then, double-click the Load event to create an event handler, if one does not already exist.
Add the following code inside the Form1_Load
event handler. This will add the names of all available capture devices to a menu in the user interface. Clicking on the device's name will set it as a capture device for the CaptureCtrl
control.
private void Form1_Load(object sender, EventArgs e)
{
// Setup Capture Devices Menu
foreach (Device dev in capture1.VideoDevices)
{
ToolStripItem mi = new ToolStripMenuItem();
mi.Text = dev.FriendlyName;
mi.Click += videoDevices_click;
videoDeviceToolStripMenuItem.DropDownItems.Add(mi);
}
}
Add the code below to the videoDevices_click
event to set the selected capture device for the CaptureCtrl
control.
private void videoDevices_click(object sender, EventArgs e)
{
ToolStripItem ti = (ToolStripItem)sender;
capture1.EnterEdit();
try
{
capture1.VideoDevices.Selection = (ti.OwnerItem as ToolStripMenuItem).DropDownItems.IndexOf(ti);
}
catch (Exception)
{
MessageBox.Show("This video capture device is not available. Make sure no other program is using the device or try changing the display resolution", "Error");
}
}
Open Form1.cs
in the Designer. Inside the Toolbox, double-click MenuStrip, which will add a menu to the form.
Add two menu items with the text Video &Device and &Start. Leave the new items' names as videoDeviceToolStripMenuItem
and startCaptureToolStripMenuItem
.
Double-click the Start menu item to create its event handler. Add the following code in it:
private void startToolStripMenuItem_Click(object sender, EventArgs e)
{
if (!IsCapturing)
{
startCaptureToolStripMenuItem.Text = "Stop";
capture1.PreviewSource = CapturePreview.Video;
capture1.PreviewTap = CapturePreviewTap.Processors;
capture1.Preview = true;
capture1.ReadyCapture(CaptureMode.Video);
IsCapturing = true;
}
else
StopCapture();
}
Clicking Start will configure the CaptureCtrl
control so that a preview is generated from the video device. This will allow image frames to be passed to the lmvCallBack
filter for barcode detection.
Create a new method inside the Form1
class named StopCapture()
. This method will be called inside the startToolStripMenuItem_Click
event handler as shown above. Add the code below inside the StopCapture()
method to stop the CaptureCtrl
.
private void StopCapture()
{
startCaptureToolStripMenuItem.Text = "Start";
capture1.StopCapture();
IsCapturing = false;
}
Run the project by pressing F5, or by selecting Debug -> Start Debugging.
If the steps were followed correctly, the application runs and the form should appear. To test, follow the steps below:
Click on the Video Device dropdown menu and select your preferred device for capture.
Click Start to bring up the CaptureCtrl
preview. At this time the application will start gathering the frames from the device as RasterImages
, and running barcode detection.
Place the barcode you want to recognize in front of the camera.
When you are done, select Stop to stop capturing.
This tutorial showed how to detect barcodes in the frames of a live capture video device using the CaptureCtrl
and BarcodeReader
classes.