欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

在WPF中开启摄像头扫描二维码(Media+Zxing)

程序员文章站 2022-07-20 09:59:58
近两天项目中需要添加一个功能,是根据摄像头来读取二维码信息,然后根据读出来的信息来和数据库中进行对比显示数据。 选择技术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" 。

效果如下。

 在WPF中开启摄像头扫描二维码(Media+Zxing)