QR(Quick Response)码是一种二维条码,可以被快速解码。比普通条码储存更多信息,无需像普通条码在扫描时直线对准扫描器。
图 1:版本3 的 QRCode 图解
QR 不用线性扫描方式,而是使用红外光增强的摄像头工作,可直接识别镜头拍摄图像中的 QR 码,因此降低了对反射角度的要求。二维码扫描器甚至能对液晶屏幕上显示的条码进行识别。
QR 码呈正方形,只有黑白两色。4 个角中的 3 个用于帮助解码软件定位,以任何角度扫描,都可正确读取。
QR 码于 1994 年由日本 Denso-Wave 公司发明,2000 年 6 月,ISO 将其标准化。
QR 码原是为了在汽车制造厂便于追踪零件而设计,现在 QR 码已广泛使用在各行各业的存货管理。使用者可通过设有 RS-232C 界面的个人电脑及解码程式,连接扫描器或摄影机读取 QR 码。
近年,QR 码在日本、韩国的应用越来越普及。手机内置 QR 码解码软件让更多人了解和使用基于 QR 码所提供的服务,中国移动也推出了QR码的离线业务。尤其是日本的居酒屋、美容院,杂志,宣传海报等,用自己的手机对 QR 码进行识别,就可以方便的获取各家店铺的优惠信息。再就是电子票务领域。一般通过短信方式发送一张包含相关信息的二维码图片到用户手机,使用时只需在二维码识别终端上照一下,相关信息被读取出来。2009 年 12 月,广州机场开始使用电子机票,无需登机牌,一条二维码短信就可以登机。铁道部于 2009 年 12 月 10 日,新版车票采用 QR 码作为防伪措施。
本文演示如何利用 Ext.Net.Panel 和 QRCodeLib 项目创建条形码。封装后如下所示:
<cc1:MyQRCode ID="MyQRCode1" Height="100" Width="100" runat="server" Title="名片" CustomData="A:张三;B:经理;C:开发;D:某某软件公司;E:北京;F:86000000;G:15800000000;H:[email protected];I:海淀区;;">
</cc1:MyQRCode>
其中,
如下图所示:
图 2:自定义 MyQRCode 控件
图 3:解决方案结构
图 4:将名片生成 QRCode 码
图 5:将短信生成 QRCode 码
图 6:将电子邮件生成 QRCode 码
图 7:将标签生成 QRCode 码
using System;
using Ext.Net;
using System.ComponentModel;
namespace MyExtNet.Control
{
public partial class MyQRCode
{
[DefaultValue("")]
[Description("数据")]
public string CustomData
{
get
{
return (string)this.ViewState["CustomData"] ?? "";
}
set { this.ViewState["CustomData"] = value; }
}
public MyQRCode()
{
this.AnimCollapse = false;
this.AutoDataBind = false;
}
protected override void OnPreRender(EventArgs e)
{
this.AutoLoad.Url = "~/QRCodeHandler.ashx";
this.AutoLoad.Mode = Ext.Net.LoadMode.IFrame;
this.AutoLoad.Method = Ext.Net.HttpMethod.GET;
this.AutoLoad.Params.Add(new Parameter() { Name = "Data", Value = this.CustomData, Mode = Ext.Net.ParameterMode.Value });
}
}
}
using System;
using Ext.Net;
using System.Web;
namespace MyExtNet.Control
{
public partial class MyQRCode : Ext.Net.Panel
{
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using ThoughtWorks.QRCode.Codec;
using System.Text;
namespace ExtNetQRCode
{
/// <summary>
/// $codebehindclassname$ 的摘要说明
/// </summary>
//[WebService(Namespace = "http://tempuri.org/")]
//[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class QRCodeHandler : IHttpHandler
{
HttpResponse _response;
HttpRequest _request;
public void ProcessRequest(HttpContext context)
{
_response = context.Response;
_request = context.Request;
try
{
QRCodeEncoder qrCodeEncoder = new QRCodeEncoder();
qrCodeEncoder.QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.BYTE;
//qrCodeEncoder.QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.ALPHA_NUMERIC;
//qrCodeEncoder.QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.NUMERIC;
qrCodeEncoder.QRCodeScale = 4;
qrCodeEncoder.QRCodeVersion = 7;
qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.M;
//qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.L;
//qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.Q;
//qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.H;
String data = _request.QueryString["Data"].ToString();
Bitmap bitMap = qrCodeEncoder.Encode(data, Encoding.GetEncoding("UTF-8"));
WriteImageToStream(bitMap);
}
catch (Exception ex)
{
WriteImageToStream(CreateErrorBitmap(ex.Message));
}
}
private Bitmap CreateErrorBitmap(string errMessage)
{
int width = 300;
int height = 150;
Bitmap errBitmap = new Bitmap(width, height);
Graphics g = Graphics.FromImage(errBitmap);
StringFormat strFormat = new StringFormat();
strFormat.Alignment = StringAlignment.Center;
strFormat.LineAlignment = StringAlignment.Center;
g.FillRectangle(Brushes.White, 0, 0, width, height);
g.DrawRectangle(new Pen(Brushes.LightGray, 1), new Rectangle(0, 28, width - 1, height - 33));
strFormat.Alignment = StringAlignment.Center;
strFormat.LineAlignment = StringAlignment.Near;
g.DrawString("QRCode Generator Error", new Font("Arial", 10, FontStyle.Bold), Brushes.Red, new Rectangle(0, 5, width, 15), strFormat);
strFormat.Alignment = StringAlignment.Center;
strFormat.LineAlignment = StringAlignment.Center;
g.DrawString(errMessage, new Font("Arial", 10), Brushes.Red, new Rectangle(8, 28, width - 16, height - 35), strFormat);
return errBitmap;
}
private void WriteImageToStream(Bitmap bitMap)
{
_response.ClearContent();
_response.AddHeader("Content-type", "image/jpeg");
bitMap.Save(_response.OutputStream, ImageFormat.Jpeg);
}
public bool IsReusable
{
get
{
return false;
}
}
}
}
以“短信”为生产 QRCode 码为例,其他情况类似,都是以键和值的方式。
<%@ Page Language="C#" %>
<%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>
<%@ Register Assembly="MyExtNet.Control" Namespace="MyExtNet.Control" TagPrefix="cc1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script runat="server">1:2: protected void EncodeClick(object sender, DirectEventArgs e)3: {4: string value = null;5: for (int i = 0; i < this.FormPanel_Card.Items.Count; i++)6: {7: Ext.Net.TextField txt = (Ext.Net.TextField)this.FormPanel_Card.Items[i];8: value += txt.DataIndex + ":" + txt.Text + ";";9: }10: value += ";";11: this.MyQRCode_Message.CustomData = value;12: this.MyQRCode_Message.Render();13: }14:</script>
</head>
<body>
<form id="form1" runat="server">
<ext:ResourceManager ID="ResourceManager1" runat="server">
</ext:ResourceManager>
<ext:Panel ID="Panel_Card" runat="server" Title="短信" Layout="ColumnLayout" Height="150"
Width="500">
<Items>
<ext:FormPanel ID="FormPanel_Card" runat="server" ColumnWidth="0.6" Padding="5">
<Items>
<ext:TextField ID="txt_sm" runat="server" FieldLabel="手机号码" Text="158000000" DataIndex="SM">
</ext:TextField>
<ext:TextField ID="txt_txt" runat="server" FieldLabel="内容" Text="cnblog" DataIndex="TXT">
</ext:TextField>
</Items>
<Buttons>
<ext:Button ID="btn_cardqrcode" runat="server" Text="生成二维码">
<DirectEvents>
<Click OnEvent="EncodeClick">
</Click>
</DirectEvents>
</ext:Button>
</Buttons>
</ext:FormPanel>
<cc1:MyQRCode ID="MyQRCode_Message" Width="100" Height="150" runat="server">
</cc1:MyQRCode>
</Items>
</ext:Panel>
</form>
</body>
</html>