編譯構建
需要使用到 CMake、Git、GCC 或 MSVC。
github 鏈接:https://github.com/zxing-cpp/zxing-cpp
編譯之前請確保:
-
確保安裝了 CMake 版本 3.15 或更高版本。
-
確保安裝了與 C++17 兼容的編譯器(最低VS 2019 16.8 / gcc 7 / clang 5)。
編譯構建很簡單,如同官網:
git clone https://github.com/zxing-cpp/zxing-cpp.git --recursive --single-branch --depth 1
cmake -S zxing-cpp -B zxing-cpp.release -DCMAKE_BUILD_TYPE=Release
cmake --build zxing-cpp.release -j8 --config Release
如果出錯那就只能自行解決,不過不用擔心,我們已經提供了編譯完成的靜態庫。
此庫不支持動態庫,我們提供了 debug 和 release 兩種 .lib
。
之后就是正常的引入靜態庫的環境配置了,不再介紹。
OpenCV
ZXing 理論上不依賴 OpenCV 等其它庫,不過涉及圖形操作,我們的第一選擇基本也就是 OpenCV 了。實測 OpenCV3 與 OpenCV4 都可使用。
OpenCV + Zxing 根據字符串生成 PDF417 條形碼
#include <opencv2/opencv.hpp>
#include <BarcodeFormat.h>
#include <BitMatrix.h>
#include <TextUtfEncoding.h>
#include <MultiFormatWriter.h>using namespace cv;
using namespace ZXing;int main() {std::string input = "Hello, ZXing! This is a PDF417 barcode.";MultiFormatWriter writer(BarcodeFormat::PDF417);auto bitMatrix = writer.encode(input, 200, 100);int width = bitMatrix.width();int height = bitMatrix.height();Mat barcodeImage(height, width, CV_8UC1);for (int y = 0; y < height; ++y) {for (int x = 0; x < width; ++x) {barcodeImage.at<uint8_t>(y, x) = bitMatrix.get(x, y) ? 0 : 255;}}namedWindow("PDF417 Barcode", WINDOW_NORMAL);imshow("PDF417 Barcode", barcodeImage);waitKey(0);imwrite("pdf417_barcode.png", barcodeImage);
}
實測掃碼槍可以識別。如果當前環境編碼存在問題,可以考慮進行編碼轉換,轉換到 UTF-8。
我們稍微詳細的來解釋一下上面的代碼。
- 包含頭文件:
- 包含 OpenCV 和 ZXing 庫的頭文件。以及引入對應的命名空間
#include <opencv2/opencv.hpp>
#include <BarcodeFormat.h>
#include <BitMatrix.h>
#include <TextUtfEncoding.h>
#include <MultiFormatWriter.h>using namespace cv;
using namespace ZXing;
-
輸入字符串并生成 PDF417 條形碼
-
定義一個要編碼為 PDF417 條形碼的字符串:
std::string input = "Hello, ZXing! This is a PDF417 barcode.";
-
生成 PDF417 條形碼:
創建一個
MultiFormatWriter
對象,指定條形碼格式為PDF417。使用
encode
方法將輸入字符串編碼為一個位矩陣(bit matrix),并指定圖像的寬度和高度(200x100)。MultiFormatWriter writer(BarcodeFormat::PDF417); auto bitMatrix = writer.encode(input, 200, 100); // 寬度和高度可以根據需要調整
-
-
將條形碼數據轉換為 OpenCV Mat 對象:
-
獲取位矩陣的寬度和高度。
-
創建一個 OpenCV 的灰度圖像矩陣。
-
遍歷位矩陣的每個像素點,如果為真則設為黑色(0),否則設為白色(255)
int width = bitMatrix.width(); int height = bitMatrix.height(); Mat barcodeImage(height, width, CV_8UC1);for (int y = 0; y < height; ++y) {for (int x = 0; x < width; ++x) {barcodeImage.at<uint8_t>(y, x) = bitMatrix.get(x, y) ? 0 : 255;} }
-
-
顯示條形碼圖像:
創建窗口并顯示,等待用戶按下任意鍵關閉窗口:
namedWindow("PDF417 Barcode", WINDOW_NORMAL); imshow("PDF417 Barcode", barcodeImage); waitKey(0);
-
保存條形碼為本地圖像:
imwrite("pdf417_barcode.png", barcodeImage);
總結
最大的問題不在于代碼的理解,而是在于環境的構建。
代碼本身是簡單的,根據這個小例子足以修改、增加,完成許多的需求。