c# winform调用摄像头识别二维码

首先我们需要引用两个第三方组件:AForge和zxing。

Aforge是摄像头操作组件,zxing是二维码识别组件。都是开源项目。避免重复造*。

其实一些操作代码我也是参照别人的,若侵犯您的版权,请和我联系。

此博客仅供技术交流。

下载和用法大家可以自行搜索下。

c# winform调用摄像头识别二维码

首先获取所有可用的摄像头设备,并加入到comboBox1中

         private void getCamList()
{
try
{
//AForge.Video.DirectShow.FilterInfoCollection 设备枚举类
videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
//清空列表框
comboBox1.Items.Clear();
if (videoDevices.Count == )
throw new ApplicationException();
//全局变量,标示设备摄像头设备是否存在
DeviceExist = true;
//加入设备
foreach (FilterInfo device in videoDevices)
{
comboBox1.Items.Add(device.Name);
}
//默认选择第一项
comboBox1.SelectedIndex = ;
}
catch (ApplicationException)
{
DeviceExist = false;
comboBox1.Items.Add("未找到可用设备");
}
}

以下是启动按钮事件代码和一些其他代码。

         private void start_Click(object sender, EventArgs e)
{
if (start.Text == "Start")
{
if (DeviceExist)
{
//视频捕获设备
videoSource = new VideoCaptureDevice(videoDevices[comboBox1.SelectedIndex].MonikerString);
//捕获到新画面时触发
videoSource.NewFrame += new NewFrameEventHandler(video_NewFrame);
//先关一下,下面再打开。避免重复打开的错误
CloseVideoSource();
//设置画面大小
videoSource.DesiredFrameSize = new Size(, );
//启动视频组件
videoSource.Start();
start.Text = "Stop";
//启动定时解析二维码
timer1.Enabled = true;
//启动绘制视频中的扫描线
timer2.Enabled = true;
}
}
else
{
if (videoSource.IsRunning)
{
timer2.Enabled = false;
timer1.Enabled = false;
CloseVideoSource();
start.Text = "Start";
}
}
}
        /// <summary>
/// 全局变量,记录扫描线距离顶端的距离
/// </summary>
int top = ;
/// <summary>
/// 全局变量,保存每一次捕获的图像
/// </summary>
Bitmap img = null; private void video_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
img = (Bitmap)eventArgs.Frame.Clone(); } //close the device safely
private void CloseVideoSource()
{
if (!(videoSource == null))
if (videoSource.IsRunning)
{
videoSource.SignalToStop();
videoSource = null;
}
}

下面的代码是在画面中绘制扫描线。

         private void timer2_Tick(object sender, EventArgs e)
{
if (img == null)
{
return;
}
Bitmap img2 = (Bitmap)img.Clone();
Pen p = new Pen(Color.Red);
Graphics g = Graphics.FromImage(img2);
Point p1 = new Point(, top);
Point p2 = new Point(pictureBox1.Width, top);
g.DrawLine(p, p1, p2);
g.Dispose();
top += ; top = top % pictureBox1.Height;
pictureBox1.Image = img2; }

下面是解码二维码:

         private void timer1_Tick(object sender, EventArgs e)
{
if (img == null)
{
return;
}
#region 将图片转换成byte数组
MemoryStream ms = new MemoryStream();
img.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
byte[] bt = ms.GetBuffer();
ms.Close();
#endregion
LuminanceSource source = new RGBLuminanceSource(bt, img.Width, img.Height);
BinaryBitmap bitmap = new BinaryBitmap(new ZXing.Common.HybridBinarizer(source));
Result result;
try
{
//开始解码
result = new MultiFormatReader().decode(bitmap);
}
catch (ReaderException re)
{
return;
}
if (result != null)
{
textBox1.Text = result.Text; }
}

用了第三方组件,开发难度真是直线下降。内部具体怎么解码的,真的是一点不知道。还望有经验的高手不吝赐教。

上一篇:使用Groovy的sql模块操作mysql进行多种查询


下一篇:WPF textblock加入超链接