其實現在二維碼越來越流行,網上也有很多生成二維碼的類庫。寫一下WEB生成二維碼注意事項吧!
目前C#生成二維碼大部分都是使用ThoughtWorks.QRCode或者ZXing類庫生成,主要說一下ThoughtWorks,因為第一個找到的是這個類庫的代碼。
第一步:下載ThoughtWorks類庫
搜一下“QRCode.net源碼”會有很多,下載完后可以看到“QRCodeSample_DLL”文件,喜歡的話先運行看一下效果,了解一下二維碼的生成需要哪些基本參數。
參數說明:
Data:需要進行二維碼顯示的文字
Encoding:編碼方式,主要還得看二維碼要顯示的文字,中文就選擇BYTE吧。
Correction Level:設置編碼錯誤糾正級別
Version:版本驗證
Size:畫二維碼時使用,值越大生成的二維碼圖片像素越高
運行效果:
第二步:查看源碼文件
源碼文件夾中主要的就在“QRCodeLib”中了,有興趣可以研究一下每一個類的寫法。
這里只說一下用法:
將“QRCodeLib”程序集生成dll放入項目或者直接將程序集放入項目,新建一個Web頁面“CreatQRCode.aspx”
頁面代碼:
<body style="background:#fff; width:690px; margin-left:auto; margin-right:auto;"> <form id="form1" runat="server"> <h2> QRCODE二維碼生成DEMO</h2> <h3> 生成二維碼顯示區:</h3> <div style="width: 600px; height: 200px; border: 1px solid #ccc"> <asp:Image ID="picEncode" runat="server" Style="margin-left: auto; margin-right: auto;" /> </div> <h3> 二維碼參數配置區:</h3> <dl> <dt>明文數據</dt><dd style="width: 400px; height: 25px;"><input type="text" runat="server" id="txtEncodeData" style="width: 400px; height: 25px;" /></dd></dl> <dl> <dt>編碼類型</dt> <dd> <asp:DropDownList ID="Encoding" runat="server"> <asp:ListItem Text="字母數字" Value="AlphaNumeric"></asp:ListItem> <asp:ListItem Text="數字" Value="Numeric"></asp:ListItem> <asp:ListItem Selected="True" Text="字節" Value="Byte"></asp:ListItem> </asp:DropDownList> </dd> <dt>校正水平</dt> <dd> <asp:DropDownList ID="Correction_Level" runat="server"> <asp:ListItem Text="L" Value="L"></asp:ListItem> <asp:ListItem Selected="True" Text="M" Value="M"></asp:ListItem> <asp:ListItem Text="Q" Value="Q"></asp:ListItem> <asp:ListItem Text="H" Value="H"></asp:ListItem> </asp:DropDownList> </dd> </dl> <dl> <dt>版本0~40</dt> <dd> <asp:TextBox ID="cboVersion" runat="server" Text="5"></asp:TextBox> </dd> <dt>圖片大小</dt> <dd> <asp:TextBox ID="size" runat="server" Text="4"></asp:TextBox></dd> </dl> <dl> <dd style="text-align: center;"> <asp:Button ID="Encode" runat="server" Text="生成" CssClass="btn_style" OnClick="Encode_Click" /></dd> <dd style="text-align: center;"> <asp:Button ID="save" runat="server" Text="保存" CssClass="btn_style" /></dd></dl> </form> </body>
生成二維碼事件:
/// <summary> /// 生成二維碼 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void Encode_Click(object sender, EventArgs e) { string message = ""; //驗證加密數據不能為空 if (txtEncodeData.Value.Trim() == String.Empty) { message += "明文數據不能為空;"; return; } QRCodeEncoder qrCodeEncoder = new QRCodeEncoder(); //獲取編碼方式 String encoding = Encoding.SelectedItem.Value; if (encoding == "Byte") { qrCodeEncoder.QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.BYTE; } else if (encoding == "AlphaNumeric") { qrCodeEncoder.QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.ALPHA_NUMERIC; } else if (encoding == "Numeric") { qrCodeEncoder.QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.NUMERIC; } //驗證圖片大小參數(值越大生成的二維碼圖片像素越高) try { int scale = Convert.ToInt16(size.Text); qrCodeEncoder.QRCodeScale = scale; } catch (Exception ex) { message += "圖片大小非法輸入"; return; } //版本驗證 try { int version = Convert.ToInt16(cboVersion.Text); //設置為0主要是防止編碼的字符串太長時發生錯誤 qrCodeEncoder.QRCodeVersion = version; } catch (Exception ex) { message += "版本大小非法輸入"; } //設置編碼錯誤糾正級別 string errorCorrect = Correction_Level.SelectedItem.Value; if (errorCorrect == "L") qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.L; else if (errorCorrect == "M") qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.M; else if (errorCorrect == "Q") qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.Q; else if (errorCorrect == "H") qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.H; if (message == "") { //驗證文件路徑是否存在 if (!File.Exists(Server.MapPath("~/Upload/QRCode/QRCode.jpg"))) { File.Create(Server.MapPath("~/Upload/QRCode/QRCode.jpg")); } Bitmap image; String data = txtEncodeData.Value; image = qrCodeEncoder.Encode(data); image.Dispose(); image.Save(Server.MapPath("~/Upload/QRCode/QRCode.jpg"), System.Drawing.Imaging.ImageFormat.Jpeg); picEncode.ImageUrl = "~/Upload/QRCode/QRCode.jpg"; } else { Master.Page.ClientScript.RegisterStartupScript(Page.GetType(), "aa", "alert('" + message + "')", true); } }
第三步:此時編譯應該會出現“索引超出了數組界限”
錯位位置:rsTemp[rsBlockNumber][j] = codewords[i2];
這個地方剛開始比較難搞,調試發現缺少“qrcode_data”文件夾下資源。
調試中當前環境運行路徑為:C:\Program Files\Common Files\Microsoft Shared\DevServer\10.0\qrcode_data
那么把讀取的資源放到指定位置即可。
1.找到“QRCodeLib”下“Resources”
2.在讀取文件的指定目錄下創建文件夾“qrcode_data”
3.將"Resources"文件內容拷貝到新建的“qrcode_data”
以上三個操作即可排除“索引超出了數組界限”的錯誤
在Web中或者通過修改一下修改“QRCodeEncoder.cs”文件,在構造函數中對“QRCODE_DATA_PATH”進行初始化。
1.修改構造函數
//修改構造函數 public QRCodeEncoder(string qrcode_data) { qrcodeErrorCorrect = ERROR_CORRECTION.M; qrcodeEncodeMode = ENCODE_MODE.BYTE; qrcodeVersion = 7; qrcodeStructureappendN = 0; qrcodeStructureappendM = 0; qrcodeStructureappendParity = 0; qrcodeStructureappendOriginaldata = ""; qrCodeScale = 4; qrCodeBackgroundColor = Color.White; qrCodeForegroundColor = Color.Black; QRCODE_DATA_PATH = qrcode_data; //QRCODE_DATA_PATH = Environment.CurrentDirectory + @"\qrcode_data"; }
2.將“qrcode_data”放在站點根目錄
3.實例化QRCodeEncoder類時進行“qrcode”路徑參數傳遞
QRCodeEncoder qrCodeEncoder = new QRCodeEncoder(Server.MapPath("~/qrcode_data"));
第四步:這時會發現如果要生成中文二維碼會出現亂碼,那么請在“QRCodeLib”程序集中,修改編碼方式未UTF-8即可。
public virtual Bitmap Encode(String content) { if (QRCodeUtility.IsUniCode(content)) { //return Encode(content, Encoding.Unicode); //支持中文 return Encode(content, Encoding.UTF8); } else { return Encode(content, Encoding.ASCII); } }
運行查看效果:
如果需要在二維碼中心加上自己的小圖標,可以把兩個圖層合並在一起。
判斷如果傳入Image對象,則疊加繪制。
//繪制中心圖標 if (CenterImage != null) { if (CenterImage.Height != 65 || CenterImage.Width != 65) { CenterImage = KiResizeImage(CenterImage, 65, 65, 0); } Graphics gr = Graphics.FromImage(image); gr.DrawImage(image, 0, 0, image.Width, image.Height); int s_x = (image.Width / 2 - (CenterImage.Width / 2)); int s_y = (image.Width / 2 - (CenterImage.Width / 2)); int size_width = CenterImage.Width; int size_height = CenterImage.Height;
//繪制邊框
//gr.FillRectangle(System.Drawing.Brushes.White, s_x-1, s_y-1, size_width+2, size_height+2);
gr.DrawImage(CenterImage, s_x, s_y, size_width, size_height);
GC.Collect();
}
處理中心圖標大小
/// <summary> /// Resize圖片 /// </summary> /// <param name="bmp">原始Bitmap</param> /// <param name="newW">新的寬度</param> /// <param name="newH">新的高度</param> /// <param name="Mode">保留着,暫時未用</param> /// <returns>處理以后的圖片</returns> public static Image KiResizeImage(Image bmp, int newW, int newH, int Mode) { try { Image b = new Bitmap(newW, newH); Graphics g = Graphics.FromImage(b); // 插值算法的質量 g.InterpolationMode = InterpolationMode.HighQualityBicubic; g.DrawImage(bmp, new Rectangle(0, 0, newW, newH), new Rectangle(0, 0, bmp.Width, bmp.Height), GraphicsUnit.Pixel); g.Dispose(); return b; } catch { return null; } }
效果:
實現過程中也非常感謝這些博友的奉獻
果子:http://www.cnblogs.com/tianguook/p/3513497.html
毅無涯:http://www.cnblogs.com/yiwuya/archive/2012/08/13/3018795.html