当前位置: 首页 > 科技观察

使用Google的WebAPI创建二维码

时间:2023-03-15 20:58:48 科技观察

GoogleCharts(谷歌图表)可以通过POST方式进行查询和请求(详见这里:https://developers.google.com/chart/image/docs/post_requests?csw=1),因此,我们必须:a)查询远程服务器,特别是POST的参数(后面介绍),b)得到服务器的响应(一个PNG图片),c)为我们使用,就把它(图片)来绘制我们想要的。因此,在VisualStudio中打开一个项目,然后添加一个新的用户控件(UserControl)。将BorderStyle属性设置为Fixed3D并将DoubleBuffered设置为True(以避免在控件自行刷新时闪烁)。我们将使用代码查询的标准URL如下:http://chart.googleapis.com/chart?chs={WIDTH}x{HEIGHT}&cht=qr&chl={DATA}(大括号中的参数将替换为实际参数)。chs由一个特定的二维码(宽x高)决定,chl包含条形码代表的数据。条形码大小相关的参数很容易从我们的控件属性中获取(标准控件自然是有宽高的),但是我们还需要新建一个变量来存储一个固定长度的文本,也就是说我们的二维数据由代码显示。在UserControl中,我们将标准URI定义为常量,定义Data属性和一个用于存储本地上下文数据的内部变量:}x{HEIGHT}&cht=qr&chl={DATA}"Dim_DATAAsString=String.EmptyPropertyDataAsStringGetReturn_DATAEndGetSet(valueAsString)_DATA=valueEndSetEndProperty当我们使用Control时,DataProperty在代码视图和设计视图中都可用:现在您可以使用Request参数构造一个URLURI,需要在页面请求之前将数据通过编码组装起来。确保没有特殊字符干扰我们的查询。我写了一个私有方法来做到这一点。调用它以获取参数编码的URI(感谢WebUtility.UrlEncode函数)。PrivateFunctiongetQRURI()AsStringDim_qrAddrAsString=_GOOGLE_URL.Replace("{WIDTH}",Me.Width.ToString).Replace("{HEIGHT}",Me.Height.ToString)_qrAddr=_qrAddr.Replace("{DATA}",WebUtility.UrlEncode(_DATA))return_qrAddrEndFunction会把代码中的{WIDTH}和{HEIGHT}这两个参数替换成我们的大小一旦有数据参数需要包含得到二维码图片,因为我们已经使用了服务端的QRCode控件来生成一个二维码图片缓存,等待您的请求。由于我想直接使用标准的OnPaint绘图方法(最好使用PaintEventArgs),我将重载并添加我自己的代码:(getQRURI())client.Dispose()DimmeStreamAsNewIO.MemoryStream(bytes)DimbmpAsBitmap=Bitmap.FromStream(memStream)memStream.Dispose()e.Graphics.DrawImage(bmp,0,0)EndSub调用标准绘图操作。接下来,我们检查是否有数据请求(还有另一种方法),我们使用一个新的WebClient实例来处理远程请求。通过调用格式URI方法处理的下载数据,填充一个bytes数组,然后构造一个QRCode图片类型变量,比如PNG格式。图片类型的变量可以通过读取流来初始化(就像我们打开一张本地图片,本地流会有一份拷贝)。现在我们在内存中有了自己的字节,我们可以声明一个基于数组的MemoryStream并将其用作位图的源。此时,为了实现最终的工作位图,我们可以使用OnPaint事件本身可以访问的变量e,在我们控制的[0;0]位置绘制图像。编译我们的项目后,QRBox将出现在工具箱中,准备在Form上使用。使用起来非常简单,只需要设置它的数据和属性,以及一个控制刷新的回调即可。下面的简单表单示例将展示它是如何工作的。我在我的表单中添加了一个QrBox、一个标准的文本框和按钮。当用户按下“制作”按钮时,我们将读取一个TextBox文本,将其传输到QrBox数据属性,并触发刷新方法。要启动对GoogleCharts的远程查询,按下按钮生成的代码将非常简单:PrivateSubButton1_Click(senderAsObject,eAsEventArgs)HandlesButton1.ClickQrBox1.Data=TextBox1.TextQrBox1.Refresh()EndSubUserControlQrBoxUserControl的完整代码如下:ImportsSystem.NetPublicClassQRBoxConst_GOOGLE_URLAsString="http://chart.googleapis.com/chart?chs={WIDTH}x{HEIGHT}&cht=qr&chl={DATA}"Dim_DATAAsString=String.EmptyPropertyDataAsStringGetReturn_DATAEndGetSet(valueAsString)_DATA=valueEndSetEndPropertyPrivateFunctiongetQRURI()AsStringDim_qrAddrAsString=_GOOGLE_URL。替换("{WIDTH}",Me.Width.ToString).替换("{HEIGHT}",Me.Height.ToString)_qrAddr=_qrAddr.Replace("{DATA}",WebUtility.UrlEncode(_DATA))Return_qrAddrEndFunctionProtectedOverridesSubOnPaint(eAsPaintEventArgs)MyBase.OnPaint(e)If_DATAIsNothingThenExitSubDimclientAsNewWebClient()Dimbytes()AsByte=client.DownloadData(getQRURI())client.Dispose()DimmeStreaAsNewIO.MemoryStream(字节)DimbmpAsBitmap=Bitmap.FromStream(memStream)memStream.Dispose()e.Graphics.DrawImage(bmp,0,0)EndSubPublicSubNew()InitializeComponent()EndSubEndClass