有趣的二維條碼:使用MyQR和qrcode來製作二維條碼

2020-10-03 12:01:19

前言

  今天下午無聊,突發奇想想玩玩二維條碼,於是就結合著上學期學的標識技術,用Python製作了一下二維條碼。

1. 二維條碼

  二維條碼 ( 2 − D i m e n s i o n a l (2-Dimensional (2Dimensional B a r c o d e ) Barcode) Barcode),又稱二維條形碼。它是用某種特定的幾何圖形按一定規律在平面(二維方向上)分佈的黑白相間的圖形來記錄資料符號資訊的;在程式碼編制上巧妙地利用構成計算機內部邏輯基礎的「0」、「1」位元流的概念,使用若干個與二進位制相對應的幾何形體來表示文字數值資訊,通過圖象輸入裝置或光電掃描裝置自動識讀以實現資訊自動處理。

  一維條形碼,就是我們日常所說的條形碼 ( B a r c o d ) (Barcod) (Barcod),常見於食品包裝上。它是將寬度不等的多個黑條和空白,按一定的編碼規則排列,用以表達一組資訊的圖形識別符號。常見的一維條形碼是由黑條(簡稱條)和白條(簡稱空)排成平行線圖案。條形碼可以標出物品的生產國、製造廠家、商品名稱、生產日期以及圖書分類號、郵件起止地點、類別、日期等資訊。
  通常一維條形碼所能表示的字元集不過10個數位、26個英文字母及一些特殊字元,條碼字元集最大所能表示的字元個數為128個ASCII字元,資訊量非常有限。

  二維條碼有其特定的字元集,每個字元佔有一定的寬度,每種碼具有一定的校驗功能,同時還具有對不同行的資訊自動識別功能、及處理圖形旋轉變化等特點。
  二維條形碼是在二維空間水平和豎直方向儲存資訊的條形碼。它的優點是資訊容量大,譯碼可靠性高,糾錯能力強,製作成本低,保密與防偽效能好。
  目前,世界上應用最多的二維條碼符號有 A z t e c Aztec Aztec C o d e Code Code P D F 147 PDF147 PDF147 D a t a M a t r i x DataMatrix DataMatrix Q R QR QR C o d e Code Code C o d e 16 K Code16K Code16K等。
在這裡插入圖片描述
  常見的二維條碼為 Q R QR QR C o d e Code Code Q R QR QR全稱是 Q u i c k Quick Quick R e s p o n s e Response Response,是一個近幾年來移動裝置上超流行的一種編碼方式。它的結構如下:

在這裡插入圖片描述
  QR Code屬於矩陣式二維條碼,又稱棋盤式二維條碼。它是在一個矩形空間通過黑、白畫素在矩陣中的不同分佈進行編碼。在矩陣相應元素位置上,用點(方點、圓點或其他形狀)的出現表示二進位制「1」,點的不出現表示二進位制的「0」,點的排列組合確定了矩陣式二維條碼所代表的意義。
  主要有以下特點:
  1. 符號規格從版本1(21×21)到版本40(177×177),每提高一個版本,每邊增加4個碼元(即指構成QR碼的方形黑白點);
  2. 資訊容量大:能儲存7089個數位字元或4296個字母字元或2953個8位元位元組字元或1817漢字字元;
  3. 糾錯能力強:即使部分編碼變髒或破損,也可以恢復資料。L級約可糾錯7%的資料碼字,M級約可糾錯15%的資料碼字,Q級約可糾錯25%的資料碼字,H級約可糾錯30%的資料碼字;
  4. 可以從任意方向讀取:QR碼可以從360°任一方向均可快速讀取。通過QR碼中的三處定點陣圖案,可以幫助QR碼不受背景樣式的影響,實現快速穩定的讀取。


上述材料來源於《物聯網技術基礎教學》/李聯寧編著.清華大學出版社,2012.6

2. MyQR

  有關更詳細MyQR的操作,可以參閱官方檔案

  MyQR可以生成常見的二維條碼、藝術二維條碼(黑白或彩色), 動態二維條碼(黑白或彩色),安裝命令如下:

	pip install MyQR
引數型別說明
w o r d s words words s t r str str二維條碼的內容
v e r s i o n version version i n t int int 1 − 40 1-40 140,控制二維條碼的大小,預設是 1 1 1,即 21 × 21 21\times21 21×21
l e v e l level level s t r str str ′ L ′ , ′ M ′ , ′ Q ′ , ′ H ′ 'L','M','Q','H' L,M,Q,H,選一個,預設是 L L L
p i c u t r e picutre picutre s t r str str圖片的檔名,預設為空,即生成的二維條碼是普通的二維條碼
c o l o r i z e d colorized colorized b o o l bool bool預設是 F a l s e False False,即生成的二維條碼是黑白的
c o n s t r a s t constrast constrast f l o a t float float對比度,預設是 1.0 1.0 1.0
b r i g h t n e s s brightness brightness f l o a t float float亮度,預設是 1.0 1.0 1.0
s a v e _ n a m e save\_name save_name s t r str str輸出的檔名,比如 ′ e x a m p l e . p n g ′ 'example.png' example.png
s a v e _ d i r save\_dir save_dir s t r str str輸出的檔案路徑,預設為當前路徑

  程式碼如下:

if __name__ == '__main__':
    version, level, qr_name = myqr.run(
        words='https://blog.csdn.net/qq_42730750',
        version=1,
        level='H',
        picture='./XKD.gif',
        colorized=True,
        contrast=1.0,
        brightness=1.0,
        save_name='test4.gif',
        save_dir=os.getcwd()
    )
    print(version)
    print(level)
    print(qr_name)

  這是我生成的幾個二維條碼:
在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述
  MyQR確實是挺好用的,唯一的缺點就是,不支援中文!!!沒錯,是不是有點遺憾,它只支援以下字元:

  • 數位 0 到 9
  • 大小寫的英文字母
  • 常用英文標點符號和空格
· , . : ; + - * / \ ~ ! @ # $ % ^ & ` ' = < > [ ] ( ) ? _ { } | and  (space)

3. qrcode

  有關更詳細qrcode的操作,可以參閱官方檔案

  qrcode的功能雖稍遜於MyQR,但是它支援中文字元,且能生成向量圖,安裝命令如下:

	pip install qrcode
引數型別說明
v e r s i o n version version i n t int int 1 − 40 1-40 140,控制二維條碼的大小,預設是 1 1 1,即 21 × 21 21\times21 21×21
e r r o r _ c o r r e c t i o n error\_correction error_correction c o n s t a n t s constants constants用於QR碼的錯誤校正,預設 q r c o d e . c o n s t a n t s . E R R O R _ C O R R E C T _ L qrcode.constants.ERROR\_CORRECT\_L qrcode.constants.ERROR_CORRECT_L,即 L L L
b o x _ s i z e box\_size box_size i n t int int控制QR碼的每個格子有多少畫素,預設為10
b o r d e r border border i n t int int控制邊框(空白區)的格子寬度,預設為4
f i l l _ c o l o r fill\_color fill_color s t r str str二維條碼的繪製色,預設為 ′ b l a c k ′ 'black' black
b a c k _ c o l o r back\_color back_color s t r str str二維條碼的背景色,預設為 ′ w h i t e ′ 'white' white

  程式碼如下:

def mergeImg(img1, img2, flag=True):
    """
    合併影象
    :param img1:
    :param img2:
    :param flag: True 表示將logo居中, False 表示將logo作為背景圖
    :return:
    """
    img1_w, img1_h = img1.size
    if flag:
        img2_w = int(img2.size[0] / 3)
        img2_h = int(img2.size[1] / 3)
        # 縮放logo
        img2 = img2.resize(size=(img2_w, img2_h), resample=Image.ANTIALIAS)
        # 將logo居中顯示
        img1.paste(im=img2, box=(int((img1_w - img2_w) / 2), int((img1_h - img2_h) / 2)))
        img1.save('./test8.png')
    else:
        img2 = img2.resize(size=(img1_w, img1_h), resample=Image.ANTIALIAS)
        # 兩張圖片的size和mode要一致
        # 計算公式為out = image1 * (1.0 - alpha) + image2 * alpha
        # 這裡的背景色就是一種干擾了, 如果將二維條碼的透明度設定過高會識別不出來
        out_img = Image.blend(img1, img2, alpha=0.3)
        out_img.save('./test9.png')


if __name__ == '__main__':
    qr = qrcode.QRCode(
        version=1,
        error_correction=qrcode.constants.ERROR_CORRECT_H,
        box_size=10,
        border=4,
    )
    qr.add_data('這是我的部落格地址: https://blog.csdn.net/qq_42730750')
    qr.make(fit=True)

    # black green purple orange pink white blue
    # make_image() 返回的是一個PilImage物件
    # 可以使用pillow對它進行影象處理相關的操作
    # img1 = qr.make_image(fill_color="#8A2BE2", back_color="white")
    img1 = qr.make_image(fill_color="orange", back_color="white").convert('RGB')
    # img1.show()
    # img1.save('./test6.png')

    img2 = Image.open('./cutcamera.png').convert('RGB')
    mergeImg(img1, img2, flag=True)

  這是我生成的幾個二維條碼:
在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述

  有關更多 P I L . I m a g e PIL.Image PIL.Image的操作,請參考官方檔案