[Zxing] UnityでQRコードを読み取りしてみる

UnityでQRコードの生成・読み取りをしてみたのでメモ

iOS,Androidで確認。

手順自体は単純なので、下記のサイトを参考に作業を進める。

ライブラリZxingのダウンロード

https://archive.codeplex.com/?p=zxingnet https://github.com/micjahn/ZXing.Net

GitHubからcloneかzipを取得。ZXing.Net-master.zipを解凍し、以下の階層にある「zxing.unity.dll」を取り出す。

ZXing.Net-master / Clients / UnityDemo / Assets / zxing.unity.dll

Unityプロジェクトに放り込む

UnityProjectRoot / Assets / Plugins / zxing.unity.dll ←ここに配置。

※参考サイトでは他にもファイルを使ってましたがこのファイルだけでも問題ありませんでした。

QRコードの生成

Unityのエディタ拡張を使ってQR作成サンプルを動かしてみる。
まずはQRコードを読み書きするクラスを準備。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using ZXing;
using ZXing.QrCode;

public class QRCodeHelper
{
    static public string Read(Texture2D tex)
    {
        BarcodeReader reader = new BarcodeReader();
        int w = tex.width;
        int h = tex.height;
        var pixel32s = tex.GetPixels32();
        var r = reader.Decode(pixel32s, w, h);
        return r.Text;
    }

    public static string Read(WebCamTexture tex)
    {
        BarcodeReader reader = new BarcodeReader();
        int w = tex.width;
        int h = tex.height;
        var pixel32s = tex.GetPixels32();
        var r = reader.Decode(pixel32s, w, h);
        if (r != null)
            return r.Text;
        else
            return "error";
    }

    static public Result Read2(WebCamTexture tex)
    {
        BarcodeReader reader = new BarcodeReader();
        int w = tex.width;
        int h = tex.height;
        var pixel32s = tex.GetPixels32();
        Result r = reader.Decode(pixel32s, w, h);
        return r;
    }

    static public Texture2D CreateQRCode(string str, int w, int h)
    {
        var tex = new Texture2D(w, h, TextureFormat.ARGB32, false);
        var content = Write(str, w, h);
        tex.SetPixels32(content);
        tex.Apply();
        return tex;
    }

    static Color32[] Write(string content, int w, int h)
    {
        Debug.Log(content + " / " + w + " / " + h);

        var writer = new BarcodeWriter
        {
            Format = BarcodeFormat.QR_CODE,
            Options = new QrCodeEncodingOptions
            {
                Width = w,
                Height = h
            }
        };
        return writer.Write(content);
    }
}

続いて、Unityのエディタ上から、QRコードを生成するクラスを準備。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.IO;

public class CreateQREditorWindow : EditorWindow {

    public enum QRImageSize
    {
        SIZE_128 = 7,
        SIZE_256,
        SIZE_512,
        SIZE_1024,
        SIZE_2048,
        SIZE_4096
    }

    [MenuItem("Window/QR")]
    static void Init()
    {
        var w = EditorWindow.GetWindow<CreateQREditorWindow>();
        w.Show();
    }

    QRImageSize _size = QRImageSize.SIZE_256;
    string _content = "";

    void OnGUI()
    {
        string savePath = Application.dataPath + "/qr.png";
        _content = GUILayout.TextArea(_content, GUILayout.Height(30f));
        _size = (QRImageSize)EditorGUILayout.EnumPopup(_size);
        EditorGUI.BeginDisabledGroup(string.IsNullOrEmpty(_content));
        if (GUILayout.Button("Save"))
        {
            int size = (int)Mathf.Pow(2f, (int)_size);
            var tex = QRCodeHelper.CreateQRCode(_content, size, size);
            using (var fs = new FileStream(savePath, FileMode.OpenOrCreate))
            {
                var b = tex.EncodeToPNG();
                fs.Write(b, 0, b.Length);
            }
            AssetDatabase.Refresh();
        }
        EditorGUI.EndDisabledGroup();
    }
}

Assets/EditorディレクトリにEditorWindowを継承したクラスを置くと勝手にUnityでエディタの拡張として読み込んでくれるみたい。正しく動作していれば、メニューに QR が追加されているはず。

image_1_06252018_154531 image_1_06252018_154542

QRコードの読み取り

続いて読み取り。最低限試すだけなので、記述も最小限に。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class SampleQRReader : MonoBehaviour
{
    string _result = null;
    WebCamTexture _webCam;

    IEnumerator Start()
    {
        yield return Application.RequestUserAuthorization(UserAuthorization.WebCam);
        if (Application.HasUserAuthorization(UserAuthorization.WebCam) == false)
        {
            Debug.LogFormat("no camera.");
            yield break;
        }
        Debug.LogFormat("camera ok.");
        WebCamDevice[] devices = WebCamTexture.devices;
        if (devices == null || devices.Length == 0)
            yield break;
        _webCam = new WebCamTexture(devices[0].name, Screen.width, Screen.height, 12);
        _webCam.Play();
    }

    void Update()
    {
        if (_webCam != null)
        {
            _result = QRCodeHelper.Read(_webCam);
            Debug.LogFormat("result : " + _result);
        }
    }

}

このスクリプトを適当なGameObjectにアタッチするだけ。

実行してみる。

カメラの前にQRコードをかざし、読み取りに成功すると内容をコンソールに出力する。カメラプレビューも何にもないので少し見づらいけど動作確認だけならこれだけでOK。

(※0000-0000-0000-0000〜〜〜が読み取ったデータ)

image_1_06252018_160301

ライセンスに関して。

ライセンスに関してはこちらがかなり詳しくまとまっているので下記を参照。