c# winform调用摄像头识别二维码
首先我们需要引用两个第三方组件:AForge和zxing。Aforge是摄像头操作组件,zxing是二维码识别组件。都是开源项目。避免重复造轮子。
其实一些操作代码我也是参照别人的,若侵犯您的版权,请和我联系。此博客仅供技术交流。下载和用法大家可以自行搜索下。
首先获取所有可用的摄像头设备,并加入到comboBox1中
private void getCamList(){
try {
//AForge.Video.DirectShow.FilterInfoCollection 设备枚举类
videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
//清空列表框
comboBox1.Items.Clear();
if (videoDevices.Count == 0)
throw new ApplicationException();
//全局变量,标示设备摄像头设备是否存在
DeviceExist = true;
//加入设备
foreach (FilterInfo device in videoDevices) {
comboBox1.Items.Add(device.Name);
}
//默认选择第一项
comboBox1.SelectedIndex = 0;
}
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(160, 120);
//启动视频组件
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 = 0;
/// <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(0, top);
Point p2 = new Point(pictureBox1.Width, top);
g.DrawLine(p, p1, p2);
g.Dispose();
top += 2;
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;
}
}
用了第三方组件,开发难度真是直线下降。内部具体怎么解码的,真的是一点不知道。还望有经验的高手不吝赐教。
本文由 创作,采用 知识共享署名4.0 国际许可协议进行许可。本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名。最后编辑时间为: 2020/07/31 02:30