XAMLを使用して帳票を作成する際に、QRコードを表示したいが
ZXingだとImageの変換が必要となるらしいので、この際ZXingで新しく実装された
SVG出力の機能でQRコードを表示してみました。解像度的にもSVGの方が良い為。
1次元バーコードの表示も併用可能です。
ソースコード
NuGetパッケージマネージャー より ZXing.NET (Ver.0.16.6以上)をインストールしてください。
今回は Ver.0.16.9 を使用しています。
デザイン (UserControl1.xaml)
<!--QRCode--> <Path Margin="4.1cm, 1.7cm, 0, 0" Width="1.5cm" Height="1.5cm" x:Name="QRCodeImage" Data="" Fill="Black" Stretch="Uniform" /> <!--Code128--> <StackPanel Margin="0.6cm, 3.1cm, 0, 0"> <Path Width="3cm" Height="0.4cm" x:Name="Code128Image" Data="" Fill="Black" Stretch="Uniform" /> <TextBlock Height="0.25cm" x:Name="Code128Text" FontSize="0.15cm" TextAlignment="Center" Text="" /> </StackPanel>
データバインディング (UserControl1.xaml.cs)
private string? _QRCode; private string? _Code128; public string QRCode { get => this._QRCode ?? ""; set { this._QRCode = value; CreateBarcode(QRCodeImage, this._QRCode, BarcodeFormat.QR_CODE); } } public string Code128 { get => this._Code128 ?? ""; set { this._Code128 = value; CreateBarcode(Code128Image, this._Code128, BarcodeFormat.CODE_128); } } private void CreateBarcode(Path path, string text, BarcodeFormat barcodeFormat) { string data = "F1 "; foreach ( XElement el in XElement.Parse( new BarcodeWriter<SvgRenderer.SvgImage> { Format = barcodeFormat, Options = new QrCodeEncodingOptions { ErrorCorrection = ErrorCorrectionLevel.M, CharacterSet = "UTF-8", NoPadding = true, }, Renderer = new SvgRenderer(), }.Write(text).Content ).Elements()) { if (el.Name.LocalName == "rect") { string x = el.Attribute("x").Value; string y = el.Attribute("y").Value; string width = el.Attribute("width").Value; string height = el.Attribute("height").Value; //data += $"M{x},{y} v{height} h{width} v-{height} Z"; data += $"M{x},{y} h{width} v{height} h-{width} Z"; path.Data = (Geometry?)new GeometryConverter().ConvertFromInvariantString(data); } else if (el.Name.LocalName == "text") { if (path == Code128Image) Code128Text.Text = el.Value; } } }
解説
デザイン (UserControl1.xaml)
<Path Margin="4.1cm, 1.7cm, 0, 0" Width="1.5cm" Height="1.5cm" x:Name="QRCodeImage" Data="" Fill="Black" Stretch="Uniform" />
Margin は表示位置を指定しています。
Width、Height はQRコードのサイズです。親要素のサイズに合わせたい場合は削除してください。
x:Name はデータバインディングで使用する名前です。
CODE128は StackPanel でまとめて Path の下に TextBlock を追加しています。文字列を Path に変換出来ない為です。
データバインディング (UserControl1.xaml.cs)
private string? _QRCode; public string QRCode { get => this._QRCode ?? ""; set { this._QRCode = value; CreateBarcode(QRCodeImage, this._QRCode, BarcodeFormat.QR_CODE); } }
プロパティを使用し set でバーコード作成メソッドを呼び出し、Path に反映させています。
private void CreateBarcode(Path path, string text, BarcodeFormat barcodeFormat) { string data = "F1 "; foreach ( XElement el in XElement.Parse( new BarcodeWriter<SvgRenderer.SvgImage> { Format = barcodeFormat, Options = new QrCodeEncodingOptions { ErrorCorrection = ErrorCorrectionLevel.M, CharacterSet = "UTF-8", NoPadding = true, }, Renderer = new SvgRenderer(), }.Write(text).Content ).Elements()) { if (el.Name.LocalName == "rect") { string x = el.Attribute("x").Value; string y = el.Attribute("y").Value; string width = el.Attribute("width").Value; string height = el.Attribute("height").Value; //data += $"M{x},{y} v{height} h{width} v-{height} Z"; data += $"M{x},{y} h{width} v{height} h-{width} Z"; path.Data = (Geometry?)new GeometryConverter().ConvertFromInvariantString(data); } else if (el.Name.LocalName == "text") { if (path == Code128Image) Code128Text.Text = el.Value; } } }
バーコード作成メソッドです。
変数 data に Path 表示に使用する文字列を入れていきます。
先頭の F1 は塗潰しオプションなので必須です。
ZXing からの戻り値が XML で返ってくるため、SVGタグ のみを取り出します。
new BarcodeWriter<SvgRenderer.SvgImage> で 戻り値を SVG に指定しています。
あとは、SVG⇒Path変換の処理なので説明は省略します。詳しく知りたい場合は、Pathの使用を見てください。
あとがき
ZXing最新バージョンを使用した際に、今までのソースコードが使えなくて戸惑ってましたが
まさか出力フォーマットが指定できるようになっていたとは、目から鱗です。
SVGが使用出来て解像度の事を考えなくてよくなるので、幅が広がりそうです。
今後、バーコードを使用した帳票の作成方法も記事にしたいと思います。