ZXing.NETでQRコードやバーコードを解析するには?[C#/VB]:.NET TIPS
オープンソースで提供されているZXing.NETを使用して、QRコードやバーコードを含む画像を解析し、テキストやその他の情報を抽出する方法を解説する。
バーコードやQRコードなどを扱う機能は.NET Frameworkに標準では備わっていない。たいていのコードは解読するアルゴリズムが公表されているので、自前で実装することも可能ではある。実際には、優れたサードパーティー製のライブラリやツールが幾つもあるので、その中から利用することが多い。本稿では、オープンソースのZXing.NET(ゼブラクロッシングドットネット)を使ってバーコードやQRコードが写っている画像を解析する方法を紹介する。
バーコードやQRコードなどを読み取るアプリは、一般的にはカメラから画像を取り込む機能とその画像を解析する機能を持つ。本稿では後半部分のみ、つまり、バーコードやQRコードなどが写った画像が得られたものとして、その画像からコードを読み取る機能だけを扱う。
ZXing.NETはバーコードやQRコードなどの解析だけでなく生成もできるが、そちらは本稿では扱わない。ZXing.NETとは別のものになるが、「Open Source QRCode Library」を使ってQRコードを生成する方法を次の記事で紹介している。
また、本稿で特定のトピックをすぐに知りたいという方は以下のリンクを活用してほしい。
なお、本稿に掲載したサンプルコードの全体はGitHubで別途公開している。サンプルコードをそのまま試すにはVisual Studio 2017(Update 5)以降が必要である。
ZXing.NETについて
ZXing.NETは、JavaベースのZXingを.NET Framework用に移植したものであり、パッケージはNuGetで公開されている。ZXing.NETのライセンスはApache License Version 2.0である。利用に際してはライセンスに合致するよう注意してほしい。
利用するには、Visual Studioの[NuGet パッケージの管理]ウィンドウで、ZXing.NETパッケージをプロジェクトにインストールする。
ちなみに、別の開発者の手によってZXing.NETを組み込んで作られたZXing.Net.Mobileというライブラリもある。こちらは、カメラから画像を取り込んで解析するまでの機能を備えた画面を提供する。ZXing.NETより対応環境は少ないが(Xamarin.iOS/Xamarin.Android/UWPなど)、QRコード対応のモバイルアプリを簡単に作成できる。
解析の基本【Windowsフォーム】
ZXing.NETでバーコードやQRコードを解析するには、BarcodeReaderクラス(ZXing名前空間)のDecodeメソッドを使えばよい。Windowsフォームの場合は、画像データをBitmapオブジェクト(System.Drawing名前空間)としてDecodeメソッドに渡す。
例えば、画像ファイルから作ったBitmapオブジェクトを、画面上のPictureBoxコントロールに表示するとともにZXing.NETで解析するには次のコードのようにする。
// 指定された画像ファイルをPictureBoxコントロール「Image1」に表示
var source = new Bitmap("……省略(画像ファイルのパス)……");
this.Image1.Image = source;
// コードの解析
ZXing.BarcodeReader reader = new ZXing.BarcodeReader();
ZXing.Result result = reader.Decode(Image1.Image as Bitmap);
if (result != null)
{
// 結果をTextBoxコントロール「BarcodeFormatText」/「TextText」に表示
this.BarcodeFormatText.Text = result.BarcodeFormat.ToString();
this.TextText.Text = result.Text;
}
' 指定された画像ファイルをPictureBoxコントロール「Image1」に表示
Dim source = New Bitmap("……省略(画像ファイルのパス)……")
Me.Image1.Image = source
' コードの解析
Dim reader As ZXing.BarcodeReader = New ZXing.BarcodeReader()
Dim result As ZXing.Result = reader.Decode(TryCast(Image1.Image, Bitmap))
If (result IsNot Nothing) Then
' 結果をTextBoxコントロール「BarcodeFormatText」/「TextText」に表示
Me.BarcodeFormatText.Text = result.BarcodeFormat.ToString()
Me.TextText.Text = result.Text
End If
ここでは概要だけを示している。完全なコードの全体は以下をご覧いただきたい。
C#:Form1.cs
VB:Form1.vb
別途公開しているサンプルコードの実行例を示す(次の画像)。
Windowsフォーム版の実行例(上:QRコード/下:JANコード)
ウィンドウの右側に、読み取ったコードのフォーマットとその内容が表示されている。JANコードは、そのベースとなったEANコードとして認識されている。
解析の基本【WPF】
ZXing.NETでバーコードやQRコードを解析するには、WPFではBarcodeReaderクラス(ZXing.Presentation名前空間)のDecodeメソッドを使う。WPFの場合は、画像データをBitmapImageオブジェクト(System.Windows.Media.Imaging名前空間)としてDecodeメソッドに渡す。
例えば、画像ファイルから作ったBitmapImageオブジェクトを、画面上のImageコントロールに表示するとともにZXing.NETで解析するには次のコードのようにする。
// 指定された画像ファイルをImageコントロール「Image1」に表示
var source = new BitmapImage(new Uri("……省略(画像ファイルのパス)……"));
this.Image1.Source = source;
// コードの解析
ZXing.Presentation.BarcodeReader reader = new ZXing.Presentation.BarcodeReader();
ZXing.Result result = reader.Decode(Image1.Source as BitmapImage);
if (result != null)
{
// 結果をTextBoxコントロール「BarcodeFormatText」/「TextText」に表示
this.BarcodeFormatText.Text = result.BarcodeFormat.ToString();
this.TextText.Text = result.Text;
}
' 指定された画像ファイルをImageコントロール「Image1」に表示
Dim source = New BitmapImage(New Uri("……省略(画像ファイルのパス)……"))
Me.Image1.Source = source
' コードの解析
Dim reader As ZXing.Presentation.BarcodeReader _
= New ZXing.Presentation.BarcodeReader()
Dim result As ZXing.Result = reader.Decode(TryCast(Image1.Source, BitmapImage))
If (result IsNot Nothing) Then
' 結果をTextBoxコントロール「BarcodeFormatText」/「TextText」に表示
Me.BarcodeFormatText.Text = result.BarcodeFormat.ToString()
Me.TextText.Text = result.Text
End If
ここでは概要だけを示している。完全なコードの全体は以下をご覧いただきたい。
別途公開しているサンプルコードの実行例を示す(次の画像)。
解析機能の詳細
上で述べたように解析の基本は、BarcodeReaderオブジェクトのDecodeメソッドに画像データを渡すだけだ。ここでは実際の開発に役立つと思われるオプション設定などの詳細を紹介しよう。
BarcodeReaderクラスには、次のようなオプションを設定できる。
- AutoRotateプロパティ:trueにすると、画像を90度ずつ回転させて読み取りを試す
- TryInvertedプロパティ:trueにすると、読み取れなかったときに白黒反転させてもう一度試す
- Optionsプロパティ:その他のオプションを設定する(下記)
OptionsプロパティはDecodingOptions型で、たくさんのオプションを設定できる。その中から2つだけ紹介しておこう。
- TryHarderプロパティ:trueにすると、画像をより丁寧に解析する。認識率が上がる代わりに、時間もかかる
- PossibleFormatsプロパティ:読み取るコードのフォーマットのリストを与える。読み取るべきコードの種類を限定することで、読み取り精度が上がる
BarcodeReaderをインスタンス化するときにAutoRotateプロパティとOptionsプロパティのTryHarderプロパティを設定する例を示す(次のコードと画像)。
var reader = new BarcodeReader()
{
AutoRotate = true,
Options = { TryHarder = true },
};
Dim reader = New BarcodeReader() With
{
.AutoRotate = True,
.Options = New ZXing.Common.DecodingOptions With {.TryHarder = True}
}
AutoRotateプロパティの効果
AutoRotateプロパティをtrueにすると、横倒しに写っている1次元バーコードでもこのように読み取れる。なお、QRコードは回転していても読み取れるように設計されているので、AutoRotateプロパティは関係ない。
「解析の基本」ではDecodeメソッドだけを紹介したが、BarcodeReaderクラスにはDecodeMultipleメソッドもある。複数のコードが写っている1枚の画像を与えた場合に、DecodeMultipleメソッドは全てのコードを読み取ってResultオブジェクト(ZXing名前空間)の配列として返す。
Decodeメソッド/DecodeMultipleメソッドは解析に成功するとResultオブジェクト(またはその配列)を返してくる(読み取れなかったときはnull)。Resultオブジェクトには次のような情報が入っている(一部だけを示す)。
- Textプロパティ:解読したコードの内容
- BarcodeFormatプロパティ:解読したコードのフォーマット
- ResultPointsプロパティ:コードとして認識できた画像内の領域(座標のコレクション)
- ResultMetadataプロパティ:その他の情報が入っている。ORIENTATIONタイプのデータ(AutoRotateプロパティがtrueのときに読み取ったときの回転角度)は常に入っているようである
別途公開のサンプルコードでは、TextプロパティとBarcodeFormatプロパティを表示している。さらに、WPF版(C#)では、ResultPointsプロパティとResultMetadataプロパティのORIENTATIONタイプデータを使って、コードを認識した画像内の領域をオーバーレイ表示するようにしている(次の画像)。参考にしていただきたい。
コードを認識した領域を赤くオーバーレイ表示する例(上:QRコード/下:JANコード)
QRコードでは、3個のファインダパターンと1個のアライメントパターンの中心を結ぶ四角形の領域が報告される。1次元バーコードでは、画像の辺と平行にコードを横断する線分が報告される。
この実装は本稿では解説しないので、興味のある方はWPF版(C#)のソースコードをご覧いただきたい。
その他のプラットフォーム(UWP/Xamarin.Formsなど)
ZXing.NETは、実に多くのプラットフォームに対応している。System.Drawing名前空間が使えるプラットフォームなら、Windowsフォームの場合と同様にして解析できる。コンソールアプリやASP.NETでも使えるということだ。
Windows Runtime(Windows 8.xのストアアプリ)やUWPにも対応している(次の画像)。この場合に画像を渡すには、SoftwareBitmapクラス(Windows.Graphics.Imaging名前空間)かWriteableBitmapクラス(Windows.UI.Xaml.Media.Imaging名前空間)を使う。実際のコードは別途公開のサンプルコードをご覧いただきたい。
Xamarin.Formsにも対応している(次の画像)。Xamarin.FormsではプラットフォームごとにZXing.NETを利用する方法もあるし、PCLから使う方法もある。PCLから使うにしても画像を渡す方法は幾つか考えられるが、SkiaSharpのSKBitmapクラスを使うとよいだろう。実際のコードは別途公開のサンプルコードをご覧いただきたい。SKBitmapクラスを受け付けるDecodeメソッドは拡張メソッドとして実装されていることに注意が必要かもしれない。
Xamarin.Formsの実施例(UWPアプリ)
これはXamarin.FormsのPCLプロジェクトで、読み取りの実装は.NET Standard 2.0のPCL内だけで完結している。
SkiaSharpのSKBitmapクラスをDecodeメソッドに渡すために、ZXing.Net.Bindings.SkiaSharpパッケージの導入も必要だ。ちなみにSkiaSharpは、Xamarinだけでなく、Windowsフォーム/WPF/UWP/.NET Coreにも対応している。
まとめ
ZXing.NETは多くのプラットフォームでQRコード/バーコードの解析ができる。そのBarcodeReaderインスタンスを作る方法とDecodeメソッドに渡せる画像フォーマットには注意が必要だが、あとはとても簡単に実装できる。
利用可能バージョン:.NET Framework 2.0以降(WPFは.NET Framework 3.5以降)
カテゴリ:オープンソースライブラリ 処理対象:Windowsフォーム
カテゴリ:オープンソースライブラリ 処理対象:WPF
カテゴリ:オープンソースライブラリ 処理対象:Xamarin.Forms
カテゴリ:クラス・ライブラリ 処理対象:画像
カテゴリ:クラス・ライブラリ 処理対象:ビットマップ
カテゴリ:Windowsフォーム 処理対象:画像
カテゴリ:WPF 処理対象:画像
カテゴリ:Xamarin 処理対象:画像
使用ライブラリ:BarcodeReaderクラス(ZXing名前空間)
使用ライブラリ:BarcodeReaderクラス(ZXing.Presentation名前空間)
使用ライブラリ:Bitmapクラス(System.Drawing名前空間)
使用ライブラリ:BitmapImageクラス(System.Windows.Media.Imaging名前空間)
使用ライブラリ:SKBitmapクラス(SkiaSharp名前空間)
関連TIPS:QRコードをアプリケーションで作成するには?[C#、VB]
関連TIPS:画像を読み込むには?
関連TIPS:Windowsフォームで簡単に画像を表示するには?
関連TIPS:構文:インスタンス化と同時にプロパティを設定するには?[C#/VB]
Copyright© Digital Advantage Corp. All Rights Reserved.