在.net環境下,基於Asp.Net Core,利用ZXing來生成二維碼的一般操作。 ...
本文主要介紹如何在.net環境下,基於Asp.Net Core,利用ZXing來生成二維碼的一般操作。對二維碼工作原理瞭解,詳情見:https://blog.csdn.net/weixin_36191602/article/details/82466148文章介紹。
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包含中文時,生成二維碼掃碼得出結果是亂碼。網上找了一些解決方案均不行。有時間在研究吧。在此記錄作個記錄。