使用 Google 的 Web API 創建二維碼

jopen 9年前發布 | 20K 次閱讀 二維碼 條形碼/二維碼開發包

介紹

在這篇文章里我將會介紹一個簡單的方法(使用內部的標準空間)用來創建二維碼(QR Code), 記錄關于UserControl的一切用以備查。有許多的庫幫助我們做類似的操作,但是這次我要使用谷歌圖表( Google Charts) (https://developers.google.com/chart/),同時還有System.Net和 System.IO命名空間。

背景

谷歌圖表(Google Charts)可以通過POST被查詢請求(細節看這里: https://developers.google.com/chart/image/docs/post_requests?csw=1),因此,我們必須: a)查詢遠程服務器,尤其是POST的參數(稍后敘述), b)獲取服務器的應答 (一張PNG圖片), c) 使用它對我們而言,就是把它(圖片)繪成我們想要的樣子。

因此, 在 Visual Studio中打開一個工程, 之后添加一個新的用戶控件(User Control)。 把 BorderStyle屬性設置成Fixed3D, 把 DoubleBuffered 設成 True (當控件自己刷新時,避免閃爍)。

使用 Google 的 Web API 創建二維碼

使用代碼

我們將要查詢的標準URL如下:http://chart.googleapis.com/chart?chs={WIDTH}x{HEIGHT}&cht=qr&chl={DATA}  (大括號里的參數將由實際的參數代替)。chs 由特定的二維碼決定 (width x height)chl 包含條形碼所表示的數據。與條形碼大小相關的參數很容易從我們的控制屬性上得出(標準的控制自然是有寬和高的),但是我們還要新建一個變量來存儲一個定長的文本,即表示我們的二維碼所展示的數據。

在UserControl中,我們將標準URI定義為一個常量,定義Data Property以及一個用來存儲本地上下文數據的內部變量:

Const _GOOGLE_URL As String = "http://chart.googleapis.com/chart?chs= [This link is external to TechNet Wiki. It will open in a new window.] {WIDTH}x{HEIGHT}&cht=qr&chl={DATA}"
Dim _DATA As String = String.Empty
 
Property Data As String
  Get
    Return _DATA
  End Get
  Set(value As String)
    _DATA = value
  End Set
End Property

當我們使用Control時,Data Property在代碼視圖和設計視圖里都是可用的:

使用 Google 的 Web API 創建二維碼

現在可以用請求參數來構造一個網址URI,這需要在頁面請求之前通過編碼的方式將數據組裝。要確保沒有特別的字符來干擾我們的查詢。我編寫了一個私有方法來完成這個任務。調用它可以得到一個參數編碼的URI(多虧有WebUtility.UrlEncode函數)。

Private Function getQRURI() As String
    Dim _qrAddr As String = _GOOGLE_URL.Replace("{WIDTH}", Me.Width.ToString).Replace("{HEIGHT}", Me.Height.ToString)
    _qrAddr = _qrAddr.Replace("{DATA}", WebUtility.UrlEncode(_DATA))
 
    Return _qrAddr
End Function

一旦有數據參數需要被包含,將用我們的尺寸替換掉代碼中的兩個參數{WIDTH}和{HEIGHT}(有關WebUtility.UrlEncode,請看 這里

現在可以從遠程服務器獲取二維碼圖片了,因為我們已經在服務器上利用QRCode控件產生好二維碼圖片緩存等待您的請求。由于想直接用標準OnPaint繪制方法(可以更好使用PaintEventArgs),我將進行重載,添加我自己的代碼:

Protected Overrides Sub OnPaint(e As PaintEventArgs)
    MyBase.OnPaint(e)
    If _DATA Is Nothing Then Exit Sub
 
    Dim client As New WebClient()
    Dim bytes() As Byte = client.DownloadData(getQRURI())
    client.Dispose()
 
    Dim memStream As New IO.MemoryStream(bytes)
    Dim bmp As Bitmap = Bitmap.FromStream(memStream)
    memStream.Dispose()
 
    e.Graphics.DrawImage(bmp, 0, 0)
End Sub

OnPaints調用標準的繪制操作。下一步,如果有數據請求,我們會進行檢查(另外存在方法),我們用一個新的WebClient實例來處理遠程請求。通過格式化URI方法處理過的下載數據的調用,我們填充一個bytes數組,進而構建一個諸如PNG格式的QR Code二維碼圖片


圖片類型的變量可以通過讀取流的方式進行初始化(就像我們打開本地的一張圖片,會有一份本地流的副本)。既然在內存中我們有自己的字節,我們可以聲明一個基于數組的MemoryStream,并且使用它作為位圖的源。在這一點上,為了實現完美的工作位圖,我們可以利用變量 e,其中的OnPaint事件可以訪問自己,以此在我們控制的位置[0;0]繪制圖像。

編譯我們的項目后,QRBox將出現在工具箱里,準備在Form上使用。

使用 Google 的 Web API 創建二維碼
 

使用它非常簡單,只需要設置它的數據和屬性,還有控制刷新的回調。

接下來的簡單Form例子會展示它是如何工作的。我已經向我的Form中添加了QrBox,一個標準的TextBox和Button。

使用 Google 的 Web API 創建二維碼

當用戶按下“制作”按鈕時,我們將會讀到一段TextBox文本,并將其傳送到QrBox Data Property中,并且觸發刷新方法。為了開始針對谷歌Charts的遠程查詢,按按鈕產生的代碼將會簡單如下:

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    QrBox1.Data = TextBox1.Text
    QrBox1.Refresh()
End Sub

UserControl的完整代碼

QrBox UserControl的完整代碼如下:

Imports System.Net
 
Public Class QRBox
    Const _GOOGLE_URL As String = "http://chart.googleapis.com/chart?chs={WIDTH}x{HEIGHT}&cht=qr&chl={DATA}"
    Dim _DATA As String = String.Empty
 
    Property Data As String
        Get
            Return _DATA
        End Get
        Set(value As String)
            _DATA = value
        End Set
    End Property
 
    Private Function getQRURI() As String
        Dim _qrAddr As String = _GOOGLE_URL.Replace("{WIDTH}", Me.Width.ToString).Replace("{HEIGHT}", Me.Height.ToString)
        _qrAddr = _qrAddr.Replace("{DATA}", WebUtility.UrlEncode(_DATA))
 
        Return _qrAddr
    End Function
 
    Protected Overrides Sub OnPaint(e As PaintEventArgs)
        MyBase.OnPaint(e)
        If _DATA Is Nothing Then Exit Sub
 
        Dim client As New WebClient()
        Dim bytes() As Byte = client.DownloadData(getQRURI())
        client.Dispose()
 
        Dim memStream As New IO.MemoryStream(bytes)
        Dim bmp As Bitmap = Bitmap.FromStream(memStream)
        memStream.Dispose()
 
        e.Graphics.DrawImage(bmp, 0, 0)
    End Sub
 
    Public Sub New()
        InitializeComponent()
    End Sub
End Class

我希望本文對你的項目有用。

祝你編碼愉快,工作愉快!

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!