C#调用摄像头(AForge)实现扫描条码解析(Zxing)功能

网上找了很多代码,都比较零散,以下代码纯自己手写,经过测试。下面有链接,下载后可以直接使用。

 

介绍:

自动识别:点击Start按钮会调用PC摄像头,代码内置Timer,会每100毫秒识别一下当前摄像头图像中的图像,并调用条码识别功能判定是否有条码,如果有的话就直接停止,否则继循环识别。

 

截图:也可以手动截图,截图后存在运行目录,请自行查找。

 

补充:识别通过率取决于摄像头的像素,我的笔记本比较烂,所以通过率不高。高像素的摄像头通过率很高。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
 
using AForge;
using AForge.Controls;
using AForge.Imaging;
using AForge.Video;
using AForge.Video.DirectShow;
using System.Drawing.Imaging;
 
using ZXing;
using ZXing.Common;
using ZXing.QrCode;
using ZXing.QrCode.Internal;
 
 
/// <summary>
/// 20190515 by hanfre
/// 关于原理:
/// C#调用摄像头+存储图片+Zxing/Zbar图片识别.当开启摄像头的时候利用Timer对当前图片进行解析处理,识别条码;
/// 关于条码解析:
/// 这个DEMO含两个条码解析组件,分别是Zxing和Zbar,使用哪个可以自己切换;
/// 关于作者:
/// Hanfre
/// </summary>
namespace WindowsFormsApplication1
{
    /// <summary>
    /// 20190515 by hanfre
    /// </summary>
    public partial class Form1 : Form
    {
        #region 全局变量定义
        FilterInfoCollection videoDevices;
        VideoCaptureDevice videoSource;
        public int selectedDeviceIndex = 0;
        #endregion
 
        public Form1()
        {
            InitializeComponent();
 
            InitializeView();
        }
 
        #region 事件
        /// <summary>
        /// 启动
        /// 20190515 by hanfre
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BtnStart_Click(object sender, EventArgs e)
        {
            PbxScanner.Image = null;
        
            videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
            selectedDeviceIndex = 0;
            videoSource = new VideoCaptureDevice(videoDevices[selectedDeviceIndex].MonikerString);//连接摄像头
 
            videoSource.NewFrame += new NewFrameEventHandler(VspContainerClone);//捕获画面事件
 
            videoSource.VideoResolution = videoSource.VideoCapabilities[selectedDeviceIndex];
            VspContainer.VideoSource = videoSource;
            VspContainer.Start();
 
            StartVideoSource();
        }
 
        /// <summary>
        /// 停止
        /// 20190515 by hanfre
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BtnStop_Click(object sender, EventArgs e)
        {
            CloseVideoSource();
        }
 
        /// <summary>
        /// 保存
        /// 20190515 by hanfre
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BtnScanner_Click(object sender, EventArgs e)
        {
            if (videoSource == null)
                return;
            Bitmap bitmap = VspContainer.GetCurrentVideoFrame();
            string fileName = DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss-ff") + ".jpg";
 
            bitmap.Save(Application.StartupPath + "\\" + fileName, ImageFormat.Jpeg);
            bitmap.Dispose();
        }
 
        /// <summary>
        /// 同步事件
        /// 20190515 by hanfre
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="eventArgs"></param>
        private void VspContainerClone(object sender, NewFrameEventArgs eventArgs)
        {
            PbxScanner.Image = (Bitmap)eventArgs.Frame.Clone();
        }
 
        /// <summary>
        /// Timer定时器
        /// 20190515 by hanfre
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TmScanner_Tick(object sender, EventArgs e)
        {
            if (PbxScanner.Image != null)
            {
                TmScanner.Enabled = false;
                Bitmap img = (Bitmap)PbxScanner.Image.Clone();
                if (DecodeByZxing(img))
                ///if (DecodeByZbar(img))   
                {
                    CloseVideoSource();
                }
                else
                {
                    TmScanner.Enabled = true;
                }
            }
        }
        #endregion
 
        #region 方法
        /// <summary>
        /// 初始化
        /// 20190515 by hanfre
        /// </summary>
        private void InitializeView()
        {
            BtnScanner.Enabled = false;
            BtnStop.Enabled = false;
        }
 
        /// <summary>
        /// 启动
        /// 20190515 by hanfre
        /// </summary>
        private void StartVideoSource()
        {
            TmScanner.Enabled = true;
            BtnStart.Enabled = false;
            BtnStop.Enabled = true;
            BtnScanner.Enabled = true;
        }
        /// <summary>
        /// 关闭
        /// 20190515 by hanfre
        /// </summary>
        private void CloseVideoSource()
        {
            if (!(videoSource == null))
            {
                if (videoSource.IsRunning)
                {
                    videoSource.SignalToStop();
                    videoSource = null;
                }
            }
 
            VspContainer.SignalToStop();
            //videoSourcePlayer1.Stop();
            //videoSourcePlayer1.Dispose();
 
            TmScanner.Enabled = false;
            BtnScanner.Enabled = false;
            BtnStart.Enabled = true;
            BtnStop.Enabled = false;
        }
        #endregion
 
        #region 方法/Zxing&Zbar
        /// <summary>
        /// 解码
        /// 20190515 by hanfre
        /// </summary>
        /// <param name="b"></param>
        /// <returns></returns>
        private bool DecodeByZxing(Bitmap b)
        {
            try
            {
                BarcodeReader reader = new BarcodeReader();
                reader.AutoRotate = true;
                Result result = reader.Decode(b);
 
                TxtScannerCode.Text = result.Text;
            }
            catch (Exception e)
            {
                System.Console.WriteLine(e.Message);
                TxtScannerCode.Text = "";
                return false;
            }
 
            return true;
        }
 
        private bool DecodeByZbar(Bitmap b)
        {
            DateTime now = DateTime.Now;
 
            Bitmap pImg = ZbarMakeGrayscale3(b);
            using (ZBar.ImageScanner scanner = new ZBar.ImageScanner())
            {
                scanner.SetConfiguration(ZBar.SymbolType.None, ZBar.Config.Enable, 0);
                scanner.SetConfiguration(ZBar.SymbolType.CODE39, ZBar.Config.Enable, 1);
                scanner.SetConfiguration(ZBar.SymbolType.CODE128, ZBar.Config.Enable, 1);
 
                List<ZBar.Symbol> symbols = new List<ZBar.Symbol>();
                symbols = scanner.Scan((System.Drawing.Image)pImg);
 
                if (symbols != null && symbols.Count > 0)
                {
                    string result = string.Empty;
                    symbols.ForEach(s => result += "条码内容:" + s.Data + " 条码质量:" + s.Quality + Environment.NewLine);
                    MessageBox.Show(result);
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }
 
        /// <summary>
        /// 处理图片灰度
        /// </summary>
        /// <param name="original"></param>
        /// <returns></returns>
        public static Bitmap ZbarMakeGrayscale3(Bitmap original)
        {
            //create a blank bitmap the same size as original
            Bitmap newBitmap = new Bitmap(original.Width, original.Height);
 
            //get a graphics object from the new image
            Graphics g = Graphics.FromImage(newBitmap);
 
            //create the grayscale ColorMatrix
            System.Drawing.Imaging.ColorMatrix colorMatrix = new System.Drawing.Imaging.ColorMatrix(
               new float[][]
              {
                 new float[] {.3f, .3f, .3f, 0, 0},
                 new float[] {.59f, .59f, .59f, 0, 0},
                 new float[] {.11f, .11f, .11f, 0, 0},
                 new float[] {0, 0, 0, 1, 0},
                 new float[] {0, 0, 0, 0, 1}
              });
 
            //create some image attributes
            ImageAttributes attributes = new ImageAttributes();
 
            //set the color matrix attribute
            attributes.SetColorMatrix(colorMatrix);
 
            //draw the original image on the new image
            //using the grayscale color matrix
            g.DrawImage(original, new Rectangle(0, 0, original.Width, original.Height),
               0, 0, original.Width, original.Height, GraphicsUnit.Pixel, attributes);
 
            //dispose the Graphics object
            g.Dispose();
            return newBitmap;
        }
        #endregion
    }
}

  下载地址我已上传到CSDN,可以访问   https://download.csdn.net/download/fandoc/11180026  下载

 

posted on   范兵  阅读(6494)  评论(2编辑  收藏  举报

努力加载评论中...

导航

点击右上角即可分享
微信分享提示