詳解免費(fèi)開(kāi)源的DotNet二維碼操作組件ThoughtWorks.QRCode(.NET組件介紹之四)
在生活中有一種東西幾乎已經(jīng)快要成為我們的另一個(gè)電子”身份證“,那就是二維碼。無(wú)論是在軟件開(kāi)發(fā)的過(guò)程中,還是在普通用戶的日常中,幾乎都離不開(kāi)二維碼。二維碼 (dimensional barcode) ,又稱二維條碼,是在一維條碼的基礎(chǔ)上擴(kuò)展出的一種具有可讀性的條碼。設(shè)備掃描二維條碼,通過(guò)識(shí)別條碼的長(zhǎng)度和寬度中所記載的二進(jìn)制數(shù)據(jù),可獲取其中所包含的信息。相比一維條碼,二維碼記載更復(fù)雜的數(shù)據(jù),比如圖片、網(wǎng)絡(luò)鏈接等。
今天介紹一種免費(fèi)開(kāi)源的二維碼操作組件,ThoughtWorks.QRCode組件可以高效而穩(wěn)定的生成我們需要的二維碼,接下來(lái)我們?cè)敿?xì)的了解一下這個(gè)組件。
一.ThoughtWorks.QRCode組件概述:
QRCode庫(kù)是一個(gè).NET組件,可用于編碼和解碼QRCode。 QRCode是源自日本的二維條形碼。 現(xiàn)在,它廣泛應(yīng)用于廣泛的工業(yè)領(lǐng)域。 用于車輛部件跟蹤和庫(kù)存管理。QR代表“快速反應(yīng)”。 它是日本公司Denso-Wave在1994年創(chuàng)建的,目的是高速解碼內(nèi)容。 如今,QR碼被用于手機(jī)中以緩解數(shù)據(jù)輸入。QRCode還可以打印在名片上或顯示在任何顯示器上,然后可以由移動(dòng)電話捕獲,只要移動(dòng)電話具有讀取QRCode的軟件。QRCode庫(kù)提供的功能包括:將內(nèi)容編碼為QR碼圖像,可以保存為JPEG,GIF,PNG或位圖格式;解碼QR碼圖像。
該庫(kù)可用于任何.NET 2.0 Windows應(yīng)用程序,ASP.NET Web應(yīng)用程序或Windows Mobile設(shè)備應(yīng)用程序。以下是該組件的聲明”本文以及任何相關(guān)的源代碼和文件均已獲得代碼項(xiàng)目開(kāi)放許可證(CPOL)許可“。
二.ThoughtWorks.QRCode相關(guān)核心對(duì)象和方法解析:
有關(guān)ThoughtWorks.QRCode的主要類如下:
以上是采用.NET Reflector對(duì)DLL文件進(jìn)行反編譯,以此查看源代碼。由于我只是下載了DLL文件,沒(méi)有下載源碼,所以直接利用.NET Reflector查看源碼,接下來(lái)具體介紹一下組件的一些類和方法:
1.QRCodeEncoder:二維碼編碼類。
public enum ENCODE_MODE { ALPHA_NUMERIC, NUMERIC, BYTE } public enum ERROR_CORRECTION { L, M, Q, H } public virtual Bitmap Encode(string content, Encoding encoding) { bool[][] flagArray = this.calQrcode(encoding.GetBytes(content)); SolidBrush brush = new SolidBrush(this.qrCodeBackgroundColor); Bitmap image = new Bitmap((flagArray.Length * this.qrCodeScale) + 1, (flagArray.Length * this.qrCodeScale) + 1); Graphics graphics = Graphics.FromImage(image); graphics.FillRectangle(brush, new Rectangle(0, 0, image.Width, image.Height)); brush.Color = this.qrCodeForegroundColor; for (int i = 0; i < flagArray.Length; i++) { for (int j = 0; j < flagArray.Length; j++) { if (flagArray[j][i]) { graphics.FillRectangle(brush, j * this.qrCodeScale, i * this.qrCodeScale, this.qrCodeScale, this.qrCodeScale); } } } return image; }
2.QRCodeDecoder:二維碼解碼類。
public virtual string decode(QRCodeImage qrCodeImage, Encoding encoding) { sbyte[] src = this.decodeBytes(qrCodeImage); byte[] dst = new byte[src.Length]; Buffer.BlockCopy(src, 0, dst, 0, dst.Length); return encoding.GetString(dst); } public virtual sbyte[] decodeBytes(QRCodeImage qrCodeImage) { DecodeResult result; Point[] adjustPoints = this.AdjustPoints; ArrayList list = ArrayList.Synchronized(new ArrayList(10)); while (this.numTryDecode < adjustPoints.Length) { try { result = this.decode(qrCodeImage, adjustPoints[this.numTryDecode]); if (result.CorrectionSucceeded) { return result.DecodedBytes; } list.Add(result); canvas.println("Decoding succeeded but could not correct"); canvas.println("all errors. Retrying.."); } catch (DecodingFailedException exception) { if (exception.Message.IndexOf("Finder Pattern") >= 0) { throw exception; } } finally { this.numTryDecode++; } } if (list.Count == 0) { throw new DecodingFailedException("Give up decoding"); } int num = -1; int numErrors = 0x7fffffff; for (int i = 0; i < list.Count; i++) { result = (DecodeResult) list[i]; if (result.NumErrors < numErrors) { numErrors = result.NumErrors; num = i; } } canvas.println("All trials need for correct error"); canvas.println("Reporting #" + num + " that,"); canvas.println("corrected minimum errors (" + numErrors + ")"); canvas.println("Decoding finished."); return ((DecodeResult) list[num]).DecodedBytes; }
3.QRCodeBitmapImage:位圖圖像。
public class QRCodeBitmapImage : QRCodeImage { // Fields private Bitmap image; // Methods public QRCodeBitmapImage(Bitmap image); public virtual int getPixel(int x, int y); // Properties public virtual int Height { get; } public virtual int Width { get; } }
public interface QRCodeImage { // Methods int getPixel(int x, int y); // Properties int Height { get; } int Width { get; } }
以上是對(duì)ThoughtWorks.QRCode組件的一些方法的介紹,如果需要了解更多的方法,可以查看對(duì)應(yīng)的源碼。
三.ThoughtWorks.QRCode二維碼操作實(shí)例:
1.生成二維碼(對(duì)二維碼沒(méi)有進(jìn)行設(shè)置)。
/// <summary> /// 生成二維碼 /// </summary> /// <param name="content">帶生成二維碼的字符串</param> /// <param name="path">路徑</param> /// <returns></returns> public static string CreatehoughtWorksQrCode(string content, string path) { if (string.IsNullOrEmpty(content)) { throw new ArgumentNullException(content); } if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException(path); } var qrCodeEncoder = new QRCodeEncoder { QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.BYTE, QRCodeScale = 4, QRCodeVersion = 8, QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.M }; Image image = qrCodeEncoder.Encode(content); var filename = DateTime.Now.ToString("yyyymmddhhmmssfff") + ".jpg"; var filepath = string.Format("{0}{1}", path, filename); FileStream fs = null; try { fs = new FileStream(filepath, FileMode.OpenOrCreate, FileAccess.Write); image.Save(fs, System.Drawing.Imaging.ImageFormat.Jpeg); } catch (IOException ex) { throw new IOException(ex.Message); } finally { if (fs != null) fs.Close(); image.Dispose(); } return CodeDecoder(filepath); }
2.選擇生成二維碼的相關(guān)類型。
/// <summary> /// 選擇生成二維碼的相關(guān)類型 /// <param name="strData">要生成的文字或者數(shù)字,支持中文。如: "4408810820 深圳-廣州" 或者:4444444444</param> /// <param name="qrEncoding">三種尺寸:BYTE ,ALPHA_NUMERIC,NUMERIC</param> /// <param name="level">大?。篖 M Q H</param> /// <param name="version">版本:如 8</param> /// <param name="scale">比例:如 4</param> /// <returns></returns> /// </summary> public void CreateCode_Choose(string strData, string qrEncoding, string level, int version, int scale) { if (string.IsNullOrEmpty(strData)) { throw new ArgumentNullException(strData); } if (string.IsNullOrEmpty(qrEncoding)) { throw new ArgumentNullException(qrEncoding); } if (string.IsNullOrEmpty(level)) { throw new ArgumentNullException(level); } var qrCodeEncoder = new QRCodeEncoder(); var encoding = qrEncoding; switch (encoding) { case "Byte": qrCodeEncoder.QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.BYTE; break; case "AlphaNumeric": qrCodeEncoder.QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.ALPHA_NUMERIC; break; case "Numeric": qrCodeEncoder.QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.NUMERIC; break; default: qrCodeEncoder.QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.BYTE; break; } qrCodeEncoder.QRCodeScale = scale; qrCodeEncoder.QRCodeVersion = version; switch (level) { case "L": qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.L; break; case "M": qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.M; break; case "Q": qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.Q; break; default: qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.H; break; } Image image = null; FileStream fs = null; try { //文字生成圖片 image = qrCodeEncoder.Encode(strData); var filename = DateTime.Now.ToString("yyyymmddhhmmssfff") + ".jpg"; var filepath = HttpContext.Current.Server.MapPath(@"~\Upload") + "\\" + filename; fs = new FileStream(filepath, FileMode.OpenOrCreate, FileAccess.Write); image.Save(fs, System.Drawing.Imaging.ImageFormat.Jpeg); } catch (IOException ioex) { throw new IOException(ioex.Message); } catch (Exception ex) { throw new Exception(ex.Message); } finally { if (fs != null) fs.Close(); if (image != null) image.Dispose(); } }
3.二維碼解碼。
/// <summary> /// 二維碼解碼 /// </summary> /// <param name="filePath">圖片路徑</param> /// <returns></returns> public static string CodeDecoder(string filePath) { if (string.IsNullOrEmpty(filePath)) { throw new ArgumentNullException(filePath); } try { if (!File.Exists(filePath)) return null; var myBitmap = new Bitmap(Image.FromFile(filePath)); var decoder = new QRCodeDecoder(); var decodedString = decoder.decode(new QRCodeBitmapImage(myBitmap)); return decodedString; } catch (Exception ex) { throw new Exception(ex.Message); } }
四.總結(jié):
跟以前介紹組件一樣,首先是組件的概述,組件的核心類,組件的使用方法,這些在這個(gè)組件時(shí),找改組件的相關(guān)概述時(shí),花了不少時(shí)間,也不知道為何,這個(gè)組件沒(méi)有找到相關(guān)的資料,甚至連作者都是以某某某代替,但是互聯(lián)網(wǎng)就是如此,我們不需要知道是誰(shuí)制造的,只要用起來(lái)方便就可以。在生成二維碼的組件和js插件中,我個(gè)人還是喜歡這個(gè)組件的,感覺(jué)很不錯(cuò),任何組件和方法都是有個(gè)人偏好和使用環(huán)境,讀者可以自行根據(jù)情況選擇。
由于開(kāi)發(fā)者提供了一個(gè)demo,可以直接進(jìn)入上面的鏈接中查看下載,在這里就不做一個(gè)示例介紹。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- .NET 開(kāi)源配置組件 AgileConfig的使用簡(jiǎn)介
- ASP.NET開(kāi)源導(dǎo)入導(dǎo)出庫(kù)Magicodes.IE完成Csv導(dǎo)入導(dǎo)出的方法
- 詳解開(kāi)源免費(fèi)且穩(wěn)定實(shí)用的.NET PDF打印組件itextSharp(.NET組件介紹之八)
- 詳解一款開(kāi)源免費(fèi)的.NET文檔操作組件DocX(.NET組件介紹之一)
- 詳解免費(fèi)開(kāi)源的.NET多類型文件解壓縮組件SharpZipLib(.NET組件介紹之七)
- 詳解最好的.NET開(kāi)源免費(fèi)ZIP庫(kù)DotNetZip(.NET組件介紹之三)
- 詳解免費(fèi)開(kāi)源的DotNet任務(wù)調(diào)度組件Quartz.NET(.NET組件介紹之五)
- .NET中開(kāi)源文檔操作組件DocX的介紹與使用
- 基于.NET平臺(tái)常用的框架和開(kāi)源程序整理
- .NET 開(kāi)源項(xiàng)目Polly的簡(jiǎn)單介紹
相關(guān)文章
linq to sql 中,如何解決多條件查詢問(wèn)題,答案,用表達(dá)式樹(shù)! (下)
在上一篇中,我們做了基于linq to sql 的多條件組合查詢,但通過(guò)監(jiān)視數(shù)據(jù)庫(kù)發(fā)現(xiàn),這樣做的成本比較高,每次都要取出全部的數(shù)據(jù)到內(nèi)存進(jìn)行篩選.2011-08-08Asp.Net MVC4通過(guò)id更新表單內(nèi)容的思路詳解
一個(gè)表單一旦創(chuàng)建完,其中大部分的字段便不可再編輯。只能編輯其中部分字段。下面通過(guò)本文給大家分享Asp.Net MVC4通過(guò)id更新表單內(nèi)容的思路詳解,需要的朋友參考下吧2017-07-07ASP.NET創(chuàng)建動(dòng)態(tài)縮略圖的方法
這篇文章主要介紹了ASP.NET創(chuàng)建動(dòng)態(tài)縮略圖的方法,實(shí)例分析了asp.net動(dòng)態(tài)操作圖片的相關(guān)技巧,需要的朋友可以參考下2015-06-06在ASP.NET Core Mvc集成MarkDown的方法
這篇文章主要介紹了在ASP.NET Core Mvc集成MarkDown的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03完美解決Could not load file or assembly AjaxPro.2 or one of its
Could not load file or assembly AjaxPro.2,經(jīng)排查原來(lái)是mcafee限制了2007-08-08如何將asp.net core程序部署到Linux服務(wù)器
這篇文章主要介紹了將asp.net core程序部署到Linux服務(wù)器上的詳細(xì)過(guò)程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-09-09ASP.NET Core 奇技淫巧之接口代理轉(zhuǎn)發(fā)的實(shí)現(xiàn)
這篇文章主要介紹了ASP.NET Core 奇技淫巧之接口代理轉(zhuǎn)發(fā)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08詳解VS2017 Linux 上.NET Core調(diào)試
這篇文章主要介紹了詳解VS2017 Linux 上.NET Core調(diào)試,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-04-04