LoginSignup
3
2

ZXing.Netを使用してC#でQRコードを作成する

Posted at

 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コードを確認できる。

image.png

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のインスタンスを作成して画像ファイルとして保存している。

image.png

その他

 コードの色を変えたい場合は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"));

 のように使えば

image.png

 というような結果が得られる。

 BitMatrixはある点の色をboolで得られるから、好きに加工すれば自由にQRコードを作成できる(正しく読めるQRコードかは各自の責任)。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2