如何製作 QR Code #6:生成圖片的前置作業

帶你實現屬於自己的 QR Code 產生器和解碼器

Yeecy
4 min readAug 22, 2020

為了能讓接下來的文章專注於如何產生 QR Code ,Yeecy 會在這篇文章中描述一些讀者能做的事,雖然本文跟 QR Code 本身的關聯性較弱,但是相信對想寫程式來產生圖片的人是有幫助的。

點此閱讀《如何製作 QR Code》其他文章

影像處理函式庫

想產生圖片,免不了要用到影像處理的函式庫,總不可能連圖片的編解碼器都自己寫吧 ⋯⋯?

請讀者安裝自己語言能用的函式庫,例如 OpenCV 之類的,主要用來幫助我們儲存圖片。

如果讀者使用 Python,我推薦 Matplotlib 加上 Jupyter notebook,在 Jupyter notebook 上用 Matplotlib 繪圖是個相當舒服的體驗,相信使用過的讀者會理解我在說什麼的。

數位影像

所謂的數位影像,事實上就是陣列,如果它是個灰階圖片,在我們眼裡就是二維陣列,如果是彩色圖片,那就是三維陣列。

因為 QR Code 只有黑色和白色的碼元,使用個二維陣列就能表示我們的 QR Code 了,不過如果讀者的動手能力很強,想要在 QR Code 的中央放個自己的圖片,或是要幫碼元上色之類的,那就要用三維陣列來處理了。

[[0, 255],
[255, 0]]

懂點程式的讀者應該看得出來上面想表達的是一個 2×2 的陣列,我們可以把它當成一張灰階圖片。二維陣列中的值是重要的,正常來說,255 在八位深度的灰階圖中代表白色,而 0 是黑色,不過保險起見,讀者要確定一下輸入怎樣的值會是黑色,輸入怎樣的值會出現白色。

範例陣列在灰階下的樣子

或許有些讀者會問,既然只要表達黑和白,為什麼不用二值圖片(黑白圖片)就好了呢?這是因為我們會需要用到灰色來除錯,只有黑色和白色,很難看出來有沒有把碼元放在正確的位置上,如果有了灰色,那除錯就簡單多了。

透過灰色背景,可以發現混入了奇怪的碼元

寫一個用來塡色的類別(class)

對,這個類別指的就是程式的類別。先寫好一個用來填色的類別,可以讓我們方便許多,畢竟 arr[row][column] = 0 相比 canvas.set_black(row, column) 的可讀性來的低,而且一不小心腦袋就會混亂。

舉例來說,QR Code 的白色是 0,所以當我們在二進位字串中遇到 0 時,要在二維陣列中的某個位置填上 255,因為灰階圖片中的 255 才代表白色。

我們先假設類別名稱叫做 Canvas ,以下以我自創的虛擬碼(pseudocode)列出它至少要有的方法(method),有點程式基礎的讀者應該不難看懂。

class Canvas:
private:
var array
public:
func constructor(v)
func set_black(r, c)
func set_white(r, c)
func show()
func save(p)
  • array:用來存值的二維陣列
  • constructor(v):建構子,v 表 version,我們需要知道版本,才能知道 array 的大小,別忘了把 array 初始化成灰色
  • set_black(r, c):r 表 row,c 表 column,利用 r 和 c 來把 array[r][c] 設成黑色
  • set_white(r, c):同上,把 array[r][c] 設成白色
  • show():用來顯示圖片,我指的不是單純把 array 印在螢幕上,而是用函式庫把它顯示出來
  • save(p):p 表 path,用來把 array 變成圖片,並儲存到指定的位置

以上只是個簡單範例而已,讀者還可以根據自己的需要,加上更多方法,另外別忘了好好測試 Canvas 裡頭的所有方法,你不會希望除錯除半天,最後發現居然是 Canvas 的某個方法出了錯。

結語

這篇文章感覺起來有點像是教程式語言的教授在出作業,不過至少我們寫的 Canvas 是有用的,跟教授出的作業不一樣。

下一篇文章就要開始教讀者怎麼填色囉!

感謝你的閱讀,我是 Yeecy,我們下一篇文章見。

--

--

Yeecy
Yeecy

Written by Yeecy

A Ph.D. student at NYCU CS and a compiler engineer at ICEshell Co., Ltd. You can find more information about me on my GitHub page github.com/ADNRs.

No responses yet