基于Asp.Net Core,利用ZXing来生成二维码的一般流程
程序员文章站
2022-06-22 08:30:04
在.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第一个既是。选中安装即可。
可通过项目中依赖性查看相应包的引用。如图:
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(); //} } }
运行生成结果:
遗留问题:
当barcode包含中文时,生成二维码扫码得出结果是乱码。网上找了一些解决方案均不行。有时间在研究吧。在此记录作个记录。