「Qtの応用 - QRコード」の版間の差分

提供:MochiuWiki - SUSE, Electronic Circuit, PCB
ナビゲーションに移動 検索に移動
197行目: 197行目:
==== QRコードの生成 ====
==== QRコードの生成 ====
  <syntaxhighlight lang="c++">
  <syntaxhighlight lang="c++">
#include <ZXing/MultiFormatWriter.h>
#include <ZXing/BitMatrix.h>
#include <ZXing/BarcodeFormat.h>
#include <ZXing/ReadResult.h>
  // ZXingライブラリのフォワード宣言
  // ZXingライブラリのフォワード宣言
  namespace ZXing {
  namespace ZXing {
206行目: 211行目:
  </syntaxhighlight>
  </syntaxhighlight>
<br>
<br>
 
まず、QRコード生成のオプションを設定する。<br>
<br>
対応するバーコードフォーマット<br>
* ZXing::BarcodeFormat::QR_CODE      // QRコード
* ZXing::BarcodeFormat::DATA_MATRIX  // データマトリックス
* ZXing::BarcodeFormat::AZTEC        // Aztecコード
* ZXing::BarcodeFormat::PDF_417      // PDF417
* ZXing::BarcodeFormat::CODE_128      // CODE 128
* ZXing::BarcodeFormat::CODE_39      // CODE 39
* ZXing::BarcodeFormat::EAN_13        // EAN-13
* ZXing::BarcodeFormat::EAN_8        // EAN-8
* ZXing::BarcodeFormat::UPC_A        // UPC-A
* ZXing::BarcodeFormat::UPC_E        // UPC-E
<br>
エラー訂正レベル<br>
* ZXing::ErrorCorrectionLevel::Low      // 約7%のエラー訂正
* ZXing::ErrorCorrectionLevel::Medium  // 約15%のエラー訂正
* ZXing::ErrorCorrectionLevel::Quality  // 約25%のエラー訂正
* ZXing::ErrorCorrectionLevel::High    // 約30%のエラー訂正
<br>
その他の主要なオプション<br>
* options.characterSet    // 文字エンコーディング ("UTF-8", "Shift_JIS"等)
* options.quietZone        // 余白サイズ (-1で自動)
* options.autoColor        // 自動色設定 (true / false)
* options.foregroundColor  // 前景色 (QRコードの色)
* options.backgroundColor  // 背景色
<br>
QRコード特有のオプション<br>
* options.qrVersion      // QRコードのバージョン (1〜40)
* options.qrMaskPattern  // マスクパターン (0〜7)
* options.minVersion    // 最小バージョン
* options.maxVersion    // 最大バージョン
<br>
<syntaxhighlight lang="c++">
ZXing::MultiFormatWriter::Option options;
// バーコードのフォーマットを指定
// QR_CODE以外にも複数のフォーマットが指定可能 (後述)
options.format = ZXing::BarcodeFormat::QR_CODE;
// QRコードの余白 (Quiet Zone) のサイズを指定
// 単位はモジュール (QRコードの最小単位となる点)
// 一般的な値は1〜4, 小さすぎると読み取りが困難になる
options.margin = 2;
// QRコードの出力サイズを指定 (ピクセル単位)
// width : 横幅,  height : 高さ
// 大きすぎると処理時間が増加, 小さすぎると読み取りが困難
// 一般的な最小サイズは、21x21ピクセル
// 推奨サイズは、200x200〜1000x1000ピクセル
options.width  = width;
options.height = height;
// エンコードオプション (追加可能なオプション)
// options.eccLevel    = ZXing::ErrorCorrectionLevel::Medium;  // エラー訂正レベル
                                                                // 高いレベルほどQRコードの損傷に強い
                                                                // ただし、データ容量は減少
                                                                // 一般用途ではMediumが推奨
// options.characterSet = "UTF-8";                              // 文字エンコーディング
                                                                // 日本語を含む場合はUTF-8またはShift_JISを指定
                                                                // 英数字のみの場合は指定不要
// options.quietZone    = -1;                                  // 余白サイズ (-1で自動)
                                                                // 最低でも4モジュール分必要
                                                                // 読み取り環境が悪い場合は多めに設定
</syntaxhighlight>
<br>
次に、任意の文字列データをQRコードにエンコードする。<br>
<syntaxhighlight lang="c++">
// 戻り値のmatrixはビット行列 (BitMatrix) 形式
// 各ビットが黒 (true) か 白 (false) を表す
auto matrix = writer->encode(text.toStdString(), options);
// QRコードを描画するためのQImage作成
// Format_RGB32 : 32ビットRGBフォーマット (8bitずつR, G, B, 予約)
QImage image(width, height, QImage::Format_RGB32);
// 背景を白で塗りつぶし
image.fill(Qt::white);
// BitMatrixをQImageに変換
for (int y = 0; y < matrix.height(); y++) {
    for (int x = 0; x < matrix.width(); x++) {
      // matrix.get(x, y)がtrueの場合、その点は黒
      if (matrix.get(x, y)) {
          // 黒色のピクセルを設定(R=0, G=0, B=0)
          image.setPixel(x, y, qRgb(0, 0, 0));
      }
      // falseの場合は白のまま
    }
}
</syntaxhighlight>
<br>
最後に、QRコード画像をファイルに保存する。<br>
対応している画像形式は、PNG、JPEG、BMP等がある。<br>
<syntaxhighlight lang="c++">
// 戻り値 : 保存成功でtrue, 失敗でfalse
image.save(filePath);
</syntaxhighlight>
<br><br>
<br><br>



2024年11月23日 (土) 23:42時点における版

概要



ZXing-C++ライブラリ

ZXing-C++ライブラリとは

ZXing-C++は、C++で実装されたオープンソースのマルチフォーマットリニア / マトリックスバーコード画像処理ライブラリである。
元々、JavaのZXingライブラリから移植されが、さらに開発されて、現在ではランタイムと検出性能の面で多くの改善が含まれている。

多くのフォーマットのバーコードの読み取りおよび書き込みが可能である。

対応しているフォーマットを以下に示す。

ZXing-C++ライブラリの対応フォーマット
1D product 1D industrial 2D
UPC-A Code 39 QRコード
UPC-E Code 93 Data Matrix
EAN-8 Code 128 Aztec
EAN-13 Codebar PDF 417
UPC/EAN Extension 2/5 ITF MaxiCode
RSS-14
RSS-Expanded


なお、ZXing-C++ライブラリのライセンスは、Apache-2.0となっている。

ZXing-C++ライブラリのインストール

パッケージ管理システムからインストール
# RHEL
sudo dnf install zxing-cpp-devel

# SUSE
sudo zypper install zxing-cpp-devel


ソースコードからインストール

ZXing-C++ライブラリのビルドに必要なライブラリをインストールする。

# RHEL
sudo dnf install make cmake gcc gcc-c++ stb-devel \
                 opencv-devel                             # ZXing向けOpenCVのサンプルコードもインストールする場合
                 qt6-qtbase-devel qt6-qtmultimedia-devel  # Qt向けのサンプルコードもインストールする場合

# SUSE
sudo zypper install make cmake gcc gcc-c++ stb-devel \
                    opencv-devel                                        # ZXing向けOpenCVのサンプルコードもインストールする場合
                    qt6-gui-devel qt6-quick-devel qt6-multimedia-devel  # Qt向けのサンプルコードもインストールする場合

br> ZXing-C++のGithubにアクセスして、ソースコードをダウンロードする。
ダウンロードしたファイルを解凍する。

tar xf zxing-cpp-<バージョン>.tar.gz
cd zxing-cpp-<バージョン>


または、git cloneコマンドを使用してソースコードをダウンロードする。

git clone https://github.com/zxing-cpp/zxing-cpp.git


ZXing-C++ライブラリをビルドおよびインストールする。

mkdir build && cd build

cmake -DCMAKE_BUILD_TYPE=Release \
      -DCMAKE_INSTALL_PREFIX=<ZXing-C++のインストールディレクトリ> \
      ..
make -j $(nproc)
make install


CMakeLists.txtファイルの設定

 find_package(ZXing REQUIRED)
 
 target_link_libraries(<プロジェクト名> PRIVATE
    ZXing::ZXing
 )


QRコードの読み込み

まず、QImageクラスを使用して画像ファイルを読み込む。
QImageクラスでは、PNG、JPEG、BMP、GIF等の一般的な画像形式に対応している。

 #include <ZXing/MultiFormatReader.h>
 #include <ZXing/BitMatrix.h>
 #include <ZXing/BarcodeFormat.h>
 #include <ZXing/ReadResult.h>
 
 // ZXingライブラリのフォワード宣言
 namespace ZXing {
    class MultiFormatReader;
 }
 
 // ZXingライブラリのインスタンス
 std::unique_ptr<ZXing::MultiFormatReader> reader;


 QImage image(filePath);
 
 // 画像の読み込みに失敗した場合
 // ファイルが存在しない場合や破損している場合等
 if (image.isNull()) {
    qDebug() << "画像の読み込みに失敗 : " << filePath;
    return QString();
 }


次に、読み込んだ画像の幅と高さを取得する。
これらの値は、ピクセル単位で表される。

 int width = image.width();
 int height = image.height();


ZXingライブラリで処理するためのピクセルバッファを作成する。
そして、画像の各ピクセルをグレースケールに変換する。

 // uint8_tは8ビット(0-255)のグレースケール値を格納するために使用
 // 配列サイズは width * height (総ピクセル数)
 std::vector<uint8_t> pixels(width * height);
 
 // 画像の各ピクセルをグレースケールに変換
 for (int y = 0; y < height; y++) {
    for (int x = 0; x < width; x++) {
       // QRgbはQtのRGB値を表す型(32ビット整数)
       QRgb pixel = image.pixel(x, y);
 
       // qGray関数でRGB値をグレースケール(0-255)に変換
       // 変換式: Gray = (R * 11 + G * 16 + B * 5) / 32
       // 1次元配列のインデックスに変換: y * width + x
       pixels[y * width + x] = qGray(pixel);
    }
 }


ZXingのImageViewオブジェクトを生成する。

ZXing::ImageViewの第4引数 (ImageFormat) で指定可能な値

  • ZXing::ImageFormat::Lum
    輝度 (Luminance) のみの画像フォーマット
    8ビットグレースケールであり、最も一般的で処理が高速である。
    そのため、QRコード読み取りに最適である。
  • ZXing::ImageFormat::RGB
    RGBカラー形式で、各ピクセルは24ビット (R:8bit、G:8bit、B:8bit)
    ただし、メモリ使用量が多い。
  • ZXing::ImageFormat::BGR
    BGRカラー形式
    RGBと同様だが、バイト順が逆となる。
    Windowsのビットマップ等で使用されている。
  • ZXing::ImageFormat::RGBX
    RGBにアルファチャンネルを加えた32ビット形式
    アルファ値は無視される。
  • ZXing::ImageFormat::BGRX
    BGRにアルファチャンネルを加えた32ビット形式
    アルファ値は無視される。
  • ZXing::ImageFormat::XRGB
    パディングバイトの後にRGBが続く形式
  • ZXing::ImageFormat::XBGR
    パディングバイトの後にBGRが続く形式


画像フォーマットの指定において、QRコード読み取りの場合は、Lumが最適 (処理が高速で十分な情報量) である。
メモリ使用量を考慮する場合は、Lumが推奨される。

カラー情報が必要な場合は、RGBまたはBGRを使用する。

元画像のフォーマットに合わせて選択することにより、変換のオーバーヘッドを削減できる。

 // 第1引数 : ピクセルデータへのポインタ
 // 第2引数 : 画像の幅 (ピクセル)
 // 第3引数 : 画像の高さ (ピクセル)
 // 第4引数 : 画像フォーマット (下記参照)
 ZXing::ImageView imageView(pixels.data(), width, height, ZXing::ImageFormat::Lum);


最後に、QRコードの読み取りを行う。

 // ZXing::MultiFormatReader::readメソッドは、ZXing::ReadResult型を返す
 auto result = reader->read(imageView);
 
 // 読み取り結果が有効な場合、テキストを返す
 // 無効な場合は空のQStringを返す
 if (result.isValid()) {
    return QString::fromStdString(result.text());
 }


QRコードの生成

 #include <ZXing/MultiFormatWriter.h>
 #include <ZXing/BitMatrix.h>
 #include <ZXing/BarcodeFormat.h>
 #include <ZXing/ReadResult.h>
 
 // ZXingライブラリのフォワード宣言
 namespace ZXing {
    class MultiFormatWriter;
 }
 
 // ZXingライブラリのインスタンス
 std::unique_ptr<ZXing::MultiFormatWriter> writer;


まず、QRコード生成のオプションを設定する。

対応するバーコードフォーマット

  • ZXing::BarcodeFormat::QR_CODE // QRコード
  • ZXing::BarcodeFormat::DATA_MATRIX // データマトリックス
  • ZXing::BarcodeFormat::AZTEC // Aztecコード
  • ZXing::BarcodeFormat::PDF_417 // PDF417
  • ZXing::BarcodeFormat::CODE_128 // CODE 128
  • ZXing::BarcodeFormat::CODE_39 // CODE 39
  • ZXing::BarcodeFormat::EAN_13 // EAN-13
  • ZXing::BarcodeFormat::EAN_8 // EAN-8
  • ZXing::BarcodeFormat::UPC_A // UPC-A
  • ZXing::BarcodeFormat::UPC_E // UPC-E


エラー訂正レベル

  • ZXing::ErrorCorrectionLevel::Low // 約7%のエラー訂正
  • ZXing::ErrorCorrectionLevel::Medium // 約15%のエラー訂正
  • ZXing::ErrorCorrectionLevel::Quality // 約25%のエラー訂正
  • ZXing::ErrorCorrectionLevel::High // 約30%のエラー訂正


その他の主要なオプション

  • options.characterSet // 文字エンコーディング ("UTF-8", "Shift_JIS"等)
  • options.quietZone // 余白サイズ (-1で自動)
  • options.autoColor // 自動色設定 (true / false)
  • options.foregroundColor // 前景色 (QRコードの色)
  • options.backgroundColor // 背景色


QRコード特有のオプション

  • options.qrVersion // QRコードのバージョン (1〜40)
  • options.qrMaskPattern // マスクパターン (0〜7)
  • options.minVersion // 最小バージョン
  • options.maxVersion // 最大バージョン


 ZXing::MultiFormatWriter::Option options;
 
 // バーコードのフォーマットを指定
 // QR_CODE以外にも複数のフォーマットが指定可能 (後述)
 options.format = ZXing::BarcodeFormat::QR_CODE;
 
 // QRコードの余白 (Quiet Zone) のサイズを指定
 // 単位はモジュール (QRコードの最小単位となる点)
 // 一般的な値は1〜4, 小さすぎると読み取りが困難になる
 options.margin = 2;
 
 // QRコードの出力サイズを指定 (ピクセル単位)
 // width : 横幅,  height : 高さ
 // 大きすぎると処理時間が増加, 小さすぎると読み取りが困難
 // 一般的な最小サイズは、21x21ピクセル
 // 推奨サイズは、200x200〜1000x1000ピクセル
 options.width  = width;
 options.height = height;
 
 // エンコードオプション (追加可能なオプション)
 // options.eccLevel     = ZXing::ErrorCorrectionLevel::Medium;  // エラー訂正レベル
                                                                 // 高いレベルほどQRコードの損傷に強い
                                                                 // ただし、データ容量は減少
                                                                 // 一般用途ではMediumが推奨
 // options.characterSet = "UTF-8";                              // 文字エンコーディング
                                                                 // 日本語を含む場合はUTF-8またはShift_JISを指定
                                                                 // 英数字のみの場合は指定不要
 // options.quietZone    = -1;                                   // 余白サイズ (-1で自動)
                                                                 // 最低でも4モジュール分必要
                                                                 // 読み取り環境が悪い場合は多めに設定


次に、任意の文字列データをQRコードにエンコードする。

 // 戻り値のmatrixはビット行列 (BitMatrix) 形式
 // 各ビットが黒 (true) か 白 (false) を表す
 auto matrix = writer->encode(text.toStdString(), options);
 
 // QRコードを描画するためのQImage作成
 // Format_RGB32 : 32ビットRGBフォーマット (8bitずつR, G, B, 予約)
 QImage image(width, height, QImage::Format_RGB32);
 
 // 背景を白で塗りつぶし
 image.fill(Qt::white);
 
 // BitMatrixをQImageに変換
 for (int y = 0; y < matrix.height(); y++) {
    for (int x = 0; x < matrix.width(); x++) {
       // matrix.get(x, y)がtrueの場合、その点は黒
       if (matrix.get(x, y)) {
          // 黒色のピクセルを設定(R=0, G=0, B=0)
          image.setPixel(x, y, qRgb(0, 0, 0));
       }
       // falseの場合は白のまま
    }
 }


最後に、QRコード画像をファイルに保存する。
対応している画像形式は、PNG、JPEG、BMP等がある。

 // 戻り値 : 保存成功でtrue, 失敗でfalse
 image.save(filePath);