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

基于Asp.Net Core,利用ZXing来生成二维码的一般流程

程序员文章站 2022-03-25 18:06:26
在.net环境下,基于Asp.Net Core,利用ZXing来生成二维码的一般操作。 ......

  本文主要介绍如何在.net环境下,基于asp.net core,利用zxing来生成二维码的一般操作。对二维码工作原理了解,详情见:文章介绍。

1、前期准备

  .net core preview8,vs2019(用于支持core3.0),二维码生成插件:开源库zxing。相关插件可以在github上找到。安装vs2019后新建.net core web解决方案,也可以右键该解决方案,通过管理解决方案nuget包功能来找到。如下图:浏览中搜索zxing第一个既是。选中安装即可。

基于Asp.Net Core,利用ZXing来生成二维码的一般流程

 

 

   可通过项目中依赖性查看相应包的引用。如图: 

基于Asp.Net Core,利用ZXing来生成二维码的一般流程

 2.二维码生成

2.1前端页面

 在login.cshtml页面中添加前端元素,主要是一个图片控件。

1 <div style="text-align:center">
2     <div style="margin-top:20px">
3         <span>扫码获取</span><br/>
4         <img id="barcode" width="400" height="400" alt="扫码获取" src="dynpass/getbarcode"/>
5     </div>
6 </div>
src="dynpass/getbarcode"表示image数据从dynpasscontroller的getbarcode方法获取。

 2.1后端代码

 初始化界面以及二维码资源生成方法:

 1  public class dynpasscontroller : controller
 2     {
 3         private readonly barcodevue  _barcodecontent;//
 4         public dynpasscontroller(ioptions<barcodevue> content)
 5         {
 6             this._barcodecontent = content.value;
 7         }
 8 
 9         /// <summary>
10         /// 初始化显示页面
11         /// </summary>
12         /// <returns></returns>
13         [httpget]
14         public iactionresult login()
15         {
16             return view();
17         }
18 
19         /// <summary>
20         /// svn显示==请求获取二维码资源
21         /// </summary>
22         /// <returns></returns>
23         [httpget]
24         public actionresult getbarcode()
25         {
26             var bar= _barcodecontent != null ? _barcodecontent.barcode : "扫码获取";
27             bitmap bitmap = myzxingbarcode.generatebitmapcode(bar);//扫码获取
28             system.io.memorystream ms = new system.io.memorystream();
29             bitmap.save(ms, imageformat.bmp);
30             return file(ms.getbuffer(), "image/png");//
31         }
32     }
dynpasscontroller生成二维码的内容即_barcodecontent值由core框架依赖注入(构造该对象时通过构造函数传入)。所以需在configureservices中进行注册。
barcode类结构

1  public class barcodevue
2     {
3         public string barcode { get; set; }
4     }

二维码内容注册

具体步骤:

1.在appsettings.json中添加节点。

 1 {
 2   "logging": {
 3     "loglevel": {
 4       "default": "information",
 5       "microsoft": "warning",
 6       "microsoft.hosting.lifetime": "information"
 7     }
 8   },
 9   "barcodevue": {
10     "barcode":"mybarcode"
11   },
12 
13   "allowedhosts": "*"
14 }

2.barcodevue注册

在program类中configureservices方法中通过configure注册。

 1  // this method gets called by the runtime. use this method to add services to the container.
 2         public void configureservices(iservicecollection services)
 3         {
 4             services.configure<cookiepolicyoptions>(options =>
 5             {
 6                 // this lambda determines whether user consent for non-essential cookies is needed for a given request.
 7                 options.checkconsentneeded = context => true;
 8             });
 9             services.configure<barcodevue>(configuration.getsection("barcodevue"));//注册barcodevue键值
10             //services.addmvc().addviewoptions(options => options.htmlhelperoptions.clientvalidationenabled = true);
11             services.addcontrollerswithviews()
12                 .addnewtonsoftjson();
13             services.addrazorpages();
14         }

3.生成二维码方法myzxingbarcode类

  public class myzxingbarcode
    {
        /// <summary>
        /// 生成二维码,保存成图片
        /// </summary>
        public static bitmap generatebitmapcode(string content)
        {
            var writer = new barcodewriterpixeldata();
            writer.format = barcodeformat.qr_code;
            qrcodeencodingoptions options = new qrcodeencodingoptions();
            options.disableeci = true;
            //设置内容编码
            options.characterset = "utf-8";
            //设置二维码的宽度和高度
            options.width = 300;
            options.height = 300;
            //设置二维码的边距,单位不是固定像素
            options.margin = 1;
            writer.options = options;
            //
            var pixdata = writer.write(content);
            var map = pixtobitmap(pixdata.pixels, pixdata.width, pixdata.height);
            //string filename = @"d:\generate1.png";
            //map.save(filename, imageformat.bmp);
            return map;
        }

        /// <summary>  
        /// 将一个字节数组转换为位图  
        /// </summary>  
        /// <param name="pixvalue">显示字节数组</param>  
        /// <param name="width">图像宽度</param>  
        /// <param name="height">图像高度</param>  
        /// <returns>位图</returns>  
        private static bitmap pixtobitmap(byte[] pixvalue, int width, int height)
        {
            //// 申请目标位图的变量,并将其内存区域锁定
            var m_currbitmap = new bitmap(width, height, pixelformat.format32bppargb);
            var m_rect = new rectangle(0, 0, width, height);
            var m_bitmapdata = m_currbitmap.lockbits(m_rect, imagelockmode.writeonly, pixelformat.format32bpprgb);

            intptr iptr = m_bitmapdata.scan0;  // 获取bmpdata的内存起始位置  

            //// 用marshal的copy方法,将刚才得到的内存字节数组复制到bitmapdata中  
            system.runtime.interopservices.marshal.copy(pixvalue, 0, iptr, pixvalue.length);
            m_currbitmap.unlockbits(m_bitmapdata);
            //// 算法到此结束,返回结果  

            return m_currbitmap;


            ////初始化条形码格式,宽高,以及purebarcode=true则不会留白框
            //var writer = new barcodewriterpixeldata
            //{
            //    format = barcodeformat.qr_code,
            //    options = new zxing.common.encodingoptions { height = 31, width = 167, purebarcode = true, margin = 1 }
            //};
            //var pixeldata = writer.write("123236699555555555559989966");
            //using (var bitmap = new bitmap(pixeldata.width, pixeldata.height, pixelformat.format32bpprgb))
            //using (var ms = new memorystream())
            //{
            //    var bitmapdata = bitmap.lockbits(new rectangle(0, 0, pixeldata.width, pixeldata.height),
            //       system.drawing.imaging.imagelockmode.writeonly, pixelformat.format32bpprgb);
            //    try
            //    {
            //        // we assume that the row stride of the bitmap is aligned to 4 byte multiplied by the width of the image
            //        system.runtime.interopservices.marshal.copy(pixeldata.pixels, 0, bitmapdata.scan0, pixeldata.pixels.length);
            //    }
            //    finally
            //    {
            //        bitmap.unlockbits(bitmapdata);
            //    }
            //    // save to stream as png
            //    bitmap.save(ms, imageformat.png);
            //    image image = bitmap.fromstream(ms, true);
            //    image.save(@"d:\content.png");
            //    byte[] bytes = ms.getbuffer();
            //}
        }
    }

 

运行生成结果:

 基于Asp.Net Core,利用ZXing来生成二维码的一般流程

 

 

 遗留问题:

当barcode包含中文时,生成二维码扫码得出结果是乱码。网上找了一些解决方案均不行。有时间在研究吧。在此记录作个记录。