C#でQRコードを作成するにはZXing.Netを使うと良いらしい。ただ、軽くググった感じではバージョン0.16.6以前のサンプルが多く、0.16.7以降(最新の0.16.9を含む)ではコンパイルができなかったので、新しい書き方のサンプルのメモ。
新しいバージョンではBitmap以外にSVGの出力がサポートされ、それによって互換性が破壊されている。
SVG
BarcodeWriter<SvgRenderer.SvgImage> qr = new()
{
Format = BarcodeFormat.QR_CODE,
Options = new QrCodeEncodingOptions
{
ErrorCorrection = ErrorCorrectionLevel.H,
CharacterSet = "UTF-8",
Width = 512,
Height = 512,
},
Renderer = new SvgRenderer(),
};
File.WriteAllText("log.svg", qr.Write("hello world").Content);
レンダリングの結果はstringで得られるので、File.WriteAllTextでファイルに書き出している。適当なSVGビューア(Webブラウザとか)で開けばQRコードを確認できる。
Bitmap
BarcodeWriter<PixelData> qr = new()
{
Format = BarcodeFormat.QR_CODE,
Options = new QrCodeEncodingOptions
{
ErrorCorrection = ErrorCorrectionLevel.H,
CharacterSet = "UTF-8",
Width = 512,
Height = 512,
},
Renderer = new PixelDataRenderer()
};
var pixelData = qr.Write("hello world");
using var bmp = ConvertToBitmapFrom32bppArgb(
pixelData.Width, pixelData.Height, pixelData.Pixels);
bmp.Save("log.png");
static Bitmap ConvertToBitmapFrom32bppArgb(int width, int height, byte[] data)
{
if (width * height * 4 != data.Length) { throw new ArgumentException(); }
var gcHandle = GCHandle.Alloc(data, GCHandleType.Pinned);
try
{
return new(
width, height, width * 4,
PixelFormat.Format32bppArgb,
gcHandle.AddrOfPinnedObject());
}
finally
{
gcHandle.Free();
}
}
ピクセルデータで出力する場合、ARGBの生データで出力されるので、Bitmapのインスタンスを作成して画像ファイルとして保存している。
その他
色
コードの色を変えたい場合はRendererのオプションで指定する。
Renderer = new PixelDataRenderer
{
Foreground = new(Color.Black.ToArgb()),
Background = new(Color.White.ToArgb()),
},
色は独自の構造体(A, R, G, Bをbyteで保持)で管理しているので、コンストラクタでSystem.Drawing.Color.ToArgb()を渡すと楽。
自分でレンダーを作る
0.16.7以降はレンダーをオプションに与える形式になったので、この部分を自作すれば色々加工できる。
例えば
class MyRender : IBarcodeRenderer<string>
{
public string Render(BitMatrix matrix, BarcodeFormat format, string content)
=> throw new NotImplementedException();
public string Render(BitMatrix matrix, BarcodeFormat format, string content, EncodingOptions options)
{
StringBuilder sb = new();
for (int y = 0; y < matrix.Height; y++)
{
for (int x = 0; x < matrix.Width; x++)
{
sb.Append(matrix[x, y] ? "●" : "□");
}
sb.AppendLine();
}
return sb.ToString();
}
}
のようなレンダーを作り
BarcodeWriter<string> qr = new()
{
Format = BarcodeFormat.QR_CODE,
Options = new QrCodeEncodingOptions
{
ErrorCorrection = ErrorCorrectionLevel.H,
CharacterSet = "UTF-8",
},
Renderer = new MyRender(),
};
File.WriteAllText("log.txt", qr.Write("hello world"));
のように使えば
というような結果が得られる。
BitMatrixはある点の色をboolで得られるから、好きに加工すれば自由にQRコードを作成できる(正しく読めるQRコードかは各自の責任)。