在WPF中开启摄像头扫描二维码(Media+Zxing)
程序员文章站
2023-11-14 21:34:52
近两天项目中需要添加一个功能,是根据摄像头来读取二维码信息,然后根据读出来的信息来和数据库中进行对比显示数据。 选择技术Zxing、WPFMediaKit。基本的原理就是让WPFmediaKit来对摄像头进行操作,然后Zxing这个库对图片进行分析大致就是这样。 在后台中定义了定时器,用于解析当前摄 ......
近两天项目中需要添加一个功能,是根据摄像头来读取二维码信息,然后根据读出来的信息来和数据库中进行对比显示数据。
选择技术zxing、wpfmediakit。基本的原理就是让wpfmediakit来对摄像头进行操作,然后zxing这个库对图片进行分析大致就是这样。
在后台中定义了定时器,用于解析当前摄像头的图像,然后直接读数据。
需要注意的是一定要引入 using wpfmediakit.directshow.controls; using zxing;
public partial class yidong : page { public yidong() { initializecomponent(); cb.itemssource = multimediautil.videoinputnames;//获得所有摄像头 if (multimediautil.videoinputnames.length > 0) { cb.selectedindex = 0;//第0个摄像头为默认摄像头 } else { messagebox.show("电脑没有安装任何可用摄像头"); } cameratimer.isenabled = false; cameratimer.interval = new timespan(200); //执行间隔0.2秒 cameratimer.tick += cameratimer_tick; ; } /// <summary> /// zxing 二维码扫描类 /// </summary> barcodereader codereader = new barcodereader(); /// <summary> /// 定时器 /// </summary> dispatchertimer cameratimer = new dispatchertimer(); private void cameratimer_tick(object sender, eventargs e) { rendertargetbitmap bmp = new rendertargetbitmap((int)vce.actualwidth, (int)vce.actualheight, 96, 96, pixelformats.default); vce.measure(vce.rendersize); vce.arrange(new rect(vce.rendersize)); bmp.render(vce); bitmapencoder encoder = new jpegbitmapencoder(); encoder.frames.add(bitmapframe.create(bmp)); using (memorystream ms = new memorystream()) { encoder.save(ms); bitmap btimap = new bitmap(ms); var result = codereader.decode(btimap);//解析条码 if (result != null) { string shelve_index = result.tostring(); observablecollection<xmodel.store_detailvm> list = xdal.store_goods_detail.getgoodsbyshelve_index(shelve_index); dialog.openwindow open = lib.pubmethod.getopenwindow(this); if (open != null) { application.current.properties["sweeplist"] = list; open.closeastrue(); } } } } private void btncapture_click(object sender, routedeventargs e) { cameratimer.start(); } private void restart_click(object sender, routedeventargs e) { cameratimer.stop(); vce.play(); } private void cb_selectionchanged(object sender, selectionchangedeventargs e) { //控件制定摄像头 vce.videocapturesource = (string)cb.selecteditem; }
前台布局很简单,
<grid> <grid.columndefinitions> <columndefinition width="86*"/> <columndefinition width="237*"/> </grid.columndefinitions> <grid.rowdefinitions> <rowdefinition height="5*"/> <rowdefinition height="*"/> <rowdefinition height="*"/> </grid.rowdefinitions> <stackpanel background="lightblue" grid.row="0" grid.columnspan="2"> <wpfmedia:videocaptureelement x:name="vce" stretch="fill" width="auto" height="auto" margin="0" grid.row="0" rendertransformorigin="0.5,0.5"> <wpfmedia:videocaptureelement.rendertransform> <transformgroup> <scaletransform/> <skewtransform/> <translatetransform/> </transformgroup> </wpfmedia:videocaptureelement.rendertransform> </wpfmedia:videocaptureelement> </stackpanel> <label x:name="label" content="摄像头:" grid.row="1" grid.column="0" width="49" horizontalalignment="right" margin="0,14,0,4" /> <combobox x:name="cb" style="{staticresource query_combo}" grid.row="1" width="204" horizontalalignment="left" margin="2,13,0,8" selectionchanged="cb_selectionchanged" grid.column="1" /> <button content="开始" x:name="btncapture" style="{staticresource query_button}" click="btncapture_click" width="50" grid.row="2" grid.column="1" height="20" horizontalalignment="left" margin="9,10,0,14"/> <button content="暂停" x:name="btnrestart" style="{staticresource query_button}" click="restart_click" width="50" grid.row="2" grid.column="1" height="20" horizontalalignment="left" margin="67,11,0,15"/> </grid>
需要注意的是xaml一定要引入 xmlns:wpfmedia="clr-namespace:wpfmediakit.directshow.controls;assembly=wpfmediakit" 。
效果如下。
上一篇: php 正则 过滤html 的超链接
下一篇: C# Lambda表达式