二維碼又稱二維條碼,常見的二維碼爲QR Code,QR全稱Quick Response,是一個近幾年來移動設備上超流行的一種編碼方式,它比傳統的Bar Code條形碼能存更多的信息,也能表示更多的數據類型。
github 上的官網:
https://github.com/lincolnloop/python-qrcode#advanced-usage
一、qrcode模塊安裝導入
CMD 模式下,安裝 qrcode 模塊
python -m pip install requests
再在 python 中導入 qrcode 模塊。
import qrcode
二、簡單生成二維碼
最簡單的寫法:
import qrcode
data = "https://www.baidu.com" # data 可以是鏈接,也可以是普通字符串。
erweima = qrcode.make( data )
print( erweima ) # <class 'qrcode.image.pil.PilImage'>
erweima.save("1.png") # 保存圖片。其實利用了PIL對象的 save 方法
qrcode 對象可以通過 make 方法生成 data 數據對應的二維碼圖片,是一個 PIL 的圖形對象。
生成的二維碼如下:
微信或者手機瀏覽器掃描該二維碼,會跳轉到百度頁面。
本質而言,掃二維碼就是得到內容,而不會跳轉什麼頁面。微信或者手機瀏覽器器會跳轉,是因爲它們添加了如果掃描二維碼結果是url就自動跳轉的代碼造成的。
也可以這樣:
import os, qrcode
data = "https://www.baidu.com"
erweima = qrcode.make( data )
with open('1.png', 'wb') as f: # 利用 os 模塊的open方法存儲圖片
erweima.save(f)
三、更詳細的生成二維碼配置
一般步驟
-
創建QRCode對象
-
add_data() 添加數據
-
make_image() 創建二維碼(返回im類型的圖片對象。可以在這裏更改二維碼的顏色)
-
自動打開圖片,im.show() ; 或者保存二維碼到指定位置。
簡化版本:
import qrcode,os
data = "https://www.baidu.com" # 二維碼數據
ewm = qrcode.QRCode() # 創建QRCode對象,一切採用默認值
ewm.add_data(data) # 添加數據
ewm_img = ewm.make_image() # 生成二維碼圖像
ewm_img.show() # 直接顯示圖像
with open("test_qr.jpg","wb") as f: # 保存圖像到指定位置
ewm_img.save(f)
擴展版本:
import qrcode,os
# 設置二維碼的數據
data = "https://www.baidu.com"
# 創建QRCode對象
ewm = qrcode.QRCode(
version=1,
error_correction=qrcode.constants.ERROR_CORRECT_L,
box_size=10,
border=4,
)
# 添加數據到二維碼中
ewm.add_data(data=data)
# 更改二維碼的顏色,默認是黑色
ewm.make(fit=True)
ewm_img = ewm.make_image(fill_color="#ff3300", back_color="white")
# 顯示二維碼
ewm_img.show()
with open("test_qr.jpg","wb") as f: # 保存圖像到指定位置
ewm_img.save(f)
參數及方法說明
QRCode 對象參數說明:
-
version: 一個整數,範圍爲1到40,用來控制二維碼的大小(最小值是1,是個21×21的矩陣),如果想讓程序自動生成,將值設置爲 None 並使用 make方法的fit=True 參數即可。
-
error_correction: 二維碼的錯誤容許率,可以選擇4個常量:
-
ERROR_CORRECT_L: 7%以下的錯誤會被糾正
-
ERROR_CORRECT_M :15%以下的錯誤會被糾正【默認值】
-
ERROR_CORRECT_Q :25 %以下的錯誤會被糾正
-
ERROR_CORRECT_H: 30%以下的錯誤會被糾正
-
-
boxsize: 二維碼每個點(方塊)中的像素個數
-
border: 二維碼到圖片邊框的小格子數,默認爲4,而且相關規定最小爲4
方法說明:
-
add_data(data,optimize=20):添加要轉換的數據到
data
參數;如果使用了optimize
優化參數,數據將被拆分爲多個塊來進行優化,以找到一個長度至少爲這個值的足夠簡潔的方式來生成二維碼。設置爲“0”以避免優化。
-
make(fit=True):當
fit
參數爲真或者QRCode 對象沒有給出version
參數時,將會調用best_fit
方法來找到適合數據的最小尺寸。如果QRCode 對象沒有設置mask_pattern
,將會調用best_mask_pattern
方法來找到找到最有效的掩模圖案。最後將這些數據傳遞給makeImpl
方法來生成二維碼。與qrcode
本體的make
方法不一樣的是,這個方法沒有任何返回值。
-
make_image( fill_color=None, back_color=None,image_factory=None ):創建二維碼的圖像並返回,默認爲 PIL 圖像。顏色值可以是單詞,也可以是 #RRGGBB 模式。一般就用前面的兩個參數,後面這個默認吧,不用搞那麼複雜。
其他方法:
-
clear:清空數據
-
get_matrix:返回二維碼數組。
-
print_ascii(out=None, tty=False, invert=False):這個方法用字符畫的形式來輸出二維碼,但是掃的時候一般都掃不出來,很多時候看上去是亂的,也就看看樣子用。
import qrcode,os
# 創建QRCode對象
ewm = qrcode.QRCode()
# 設置二維碼數據, 並添加到二維碼中
data = "https://www.baidu.com"
ewm.add_data(data=data)
ewm.make(fit=True)
# ewm.clear() # 清空數據
ewm_list = ewm.get_matrix() # 獲取二維碼數組
# 更改二維碼的顏色,默認是黑色
ewm_img = ewm.make_image(fill_color="#ff3300", back_color="white")
# 打印字符二維碼
ewm.print_ascii() # 根本掃不出來,也就是看看樣子。
# 打印二維碼數組
print(ewm_list)
# 顯示二維碼
ewm_img.show() # 如果數據被clear了,會有個二維碼,掃它什麼都不會發生
四、二維碼中間帶圖標
簡單來講,就是用小圖標直接貼在二維碼中。雖然二維碼被蓋住了一部分,但是因爲二維碼有一個容錯率,所以依然可以掃出來。因此,不建議圖標太大,太大了二維碼容錯率就不行了。
所以,二維碼中帶圖標,一般要設置高容錯率( ERROR_CORRECT_H )。
經過別人測試,自己丈量,小圖片是二維碼圖片寬高的 六分之一最合適。
一般情況是把圖標放入二維碼中的正中間:
綠色塊的左上角 x 座標是 (二維碼圖片寬 - 圖標寬) /2 ,y 座標同理推得。
所以整體思路是:
-
先獲取二維碼,並得到它的寬高;
-
利用二維碼寬高,計算出圖標寬高;
-
利用PIL 的 Image.open 方法,打開圖標圖片,並進行縮放到適當大小。
-
把圖標“粘貼”進入二維碼:利用 PIL 對象的 paste 粘貼方法
-
把整合的圖片保存下來:利用 PIL對象的save 方法。
舉例代碼:實現準備好一個圖標文件,正方形的。我這裏是 girl.jpg 文件。
# -*- coding:utf-8 -*-
import os , qrcode
from PIL import Image
import qrcode,os
# 創建QRCode對象
ewm = qrcode.QRCode(
version=5,
error_correction=qrcode.constants.ERROR_CORRECT_H,
box_size=10,
border=4,
)
# 設置二維碼數據, 並添加到二維碼中
data = "https://www.baidu.com"
ewm.add_data(data=data)
# 更改二維碼的顏色,默認是黑色。得到的結果是 PIL 圖像對象
ewm.make(fit=True) # 讓二維碼得到一個適合的大小值。
ewm_img = ewm.make_image(fill_color="#ff3300", back_color="white")
# 獲取二維碼大小:寬,高
ewm_size = ewm_img.size
ewm_size_w ,ewm_size_h = ewm_size
# 打開圖標文件,並獲取圖標的大小,重新設定圖標大小
# 這裏設置icon寬高爲二維碼的 6分之一。
s = 6
icon = Image.open("girl.png")
# 設置小圖標的大小,縮放的時候尺寸必須是整數,否則報錯
icon_w,icon_h = int(ewm_size_w/s) ,int(ewm_size_h/s)
icon_small = icon.resize( (icon_w ,icon_h) ,Image.ANTIALIAS) # Image.ANTIALIAS 畫面平滑縮放
# 獲取粘貼小圖標的座標,必須整數,否則粘貼的時候,報錯
icon_x, icon_y = int( (ewm_size_w-icon_w)/2 ), int( (ewm_size_h-icon_h)/2)
# 把圖標“粘貼”到二維碼上正中間。
ewm_img.paste( icon_small,(icon_x,icon_y) )
# 顯示二維碼
ewm_img.show() # 如果數據被clear了,會有個二維碼,掃它什麼都不會發生
ewm_img.save("girl_ewm.jpg")
這裏用到了 PIL 的 Image 對象。用到了它的 open() , resize() , paste() 方法。這裏就不詳細說它們了,具體看註釋,比較簡單。
有機會再寫一篇 PIL 的筆記。最終效果如圖:girl 的原圖奉上~