在生活中常常可以看到條碼(Barcode)的存在,無論是商品結帳時在收銀台使用的EAN條碼、書籍使用的ISBN條碼,還是在最近因行動裝置的流行也跟著帶動起來的QR Code,這些條碼都可以讓我們的生活更便利,傳遞資訊的速度更快,省下許多使用鍵盤打字的時間。zBar是一個使用C語言開發的函式庫,效率極佳,支援多種一維條碼和二維條碼的掃描,要如何在Rust上使用zBar函式庫進行條碼掃描呢?



ZBar Rust

「ZBar Rust」是筆者開發的套件,可以讓Rust程式綁定zBar的函式庫,使Rust程式能夠直接使用zBar函式庫的功能。

Crates.io

https://crates.io/crates/zbar-rust

Cargo.toml

zbar-rust = "*"

編譯

zBar是使用C語言開發的,因此無法直接被引用至Rust程式中使用,必須要使用這篇文章介紹的做法來引用才行。為了簡化問題,「ZBar Rust」套件可以自動綁定作業系統中安裝的zBar函式庫。如果想要手動設定zBar函式庫的位置也是可以的,尤其是想要讓Rust程式可以在無zBar函式庫的執行環境中使用,要先設定好以下的幾個環境變數:

  • ZBAR_LIB_DIRS:函式庫檔案所在的目錄位置。這個變數類似C/C++編譯器中-L參數的用途。路徑如果有多個的話,必須使用:隔開。
  • ZBAR_LIBS:函式庫的名稱。這個變數類似C/C++編譯器中-l參數的用途。路徑如果有多個的話,必須使用:隔開。通常這個變數的值是iconv:zbar
  • ZBAR_INCLUDE_DIRS:函式庫標頭檔的路徑。這個變數類似C/C++編譯器中-i參數的用途。路徑如果有多個的話,必須使用:隔開。

使用方法

zbar_rust這個crate底下有ZBarImageScanner結構體,這個結構體的實體提供了new關聯函數,可以用來產生ZBarImageScanner的結構實體。ZBarImageScanner結構實體提供了scan_y800方法,可以用來掃描一張灰階圖片。如果掃描成功,scan_y800方法會回傳Vec<ZBarImageScanResult>結構實體,每個ZBarImageScanResult結構實體分別代表著一個條碼圖案的掃描結果。可以利用ZBarImageScanResult結構實體的symbol_type欄位來查看條碼的類型,用data欄位來讀取解碼後的資料。

如果要讀取任意格式的圖片,建議搭配image等影像處理的crate來將讀取到的圖片轉為灰階格式。

例如:

extern crate zbar_rust;
extern crate image;

use zbar_rust::ZBarImageScanner;

use image::GenericImageView;

let img = image::open(INPUT_IMAGE_PATH).unwrap();

let (width, height) = img.dimensions();

let luma_img = img.to_luma();

let luma_img_data: Vec<u8> = luma_img.to_vec();

let mut scanner = ZBarImageScanner::new();

let results = scanner.scan_y800(&luma_img_data, width, height).unwrap();

for result in results {
    println!("{}", String::from_utf8(result.data).unwrap())
}