広告

ZXingをUnityで使えるようにしてみる(その2)

今回は実際にCamearaからQRコードが読み取れるかやってみる

カメラ画像の表示

前回使ったプロジェクトをそのまま使います
とりあえずUIを使ってカメラの画像を表示させます。
RawImageとButtonを追加させます。

RawImageは全画面
ButtonはStartCameraとしていい感じの大きさと位置に調整します。


カメラ起動していないとき→ボタン押下でカメラ起動
カメラ起動しているとき→ボタン押下でカメラ終了としたいのでスクリプトを作成します。
名前をただのCameraにすると紛らわしいので、WebCameraとします。

Webカメラのテクスチャ情報からQRコードを読む処理を「QRCodeReder」に追加します。

    /// <summary>
    /// WebCamTextureからのQRコード読み込み
    /// </summary>
    /// <param name="tex">テクスチャ</param>
    /// <returns>読み込んだテクスチャの文字列</returns>
    public string ReadQRCodeWebCamTexture(WebCamTexture tex)
    {
        BarcodeReader reader = new BarcodeReader();
        // 読み込み
        ZXing.Result r = reader.Decode(tex.GetPixels32(), tex.width, tex.height);

        return r != null ? r.Text : string.Empty;
    }

「WebCamera」側にはカメラ画像の読み込みとQRの読み込みを記載します。

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

public class WebCamera : MonoBehaviour
{
    /// <summary>
    /// カメラ情報表示用
    /// </summary>
    [SerializeField]
    private RawImage m_CameraView;

    /// <summary>
    /// カメラ開始停止
    /// </summary>
    [SerializeField]
    private Button m_Button;

    /// <summary>
    /// ボタンテキスト
    /// </summary>
    [SerializeField]
    private TextMeshProUGUI m_ButtonText;

    /// <summary>
    /// 結果表示用
    /// </summary>
    [SerializeField]
    private TextMeshProUGUI m_ResultText;

    /// <summary>
    /// WEBカメラ
    /// </summary>
    private WebCamTexture m_webCamTexture = null;

    /// <summary>
    /// カメラ動いているフラグ
    /// </summary>
    private bool m_StartCamera = false;

    /// <summary>
    /// カメラ許可フラグ
    /// </summary>
    private bool m_CameraCheck = false;

    /// <summary>
    /// カメラ許可コールバック
    /// </summary>
    private PermissionCallbacks m_CallBack = new PermissionCallbacks();

    /// <summary>
    /// QRコード読み込み用
    /// </summary>
    private QRCodeReder m_QRCodeReder;

    // Start is called before the first frame update
    void Start()
    {
        // 許可時コールバック
        m_CallBack.PermissionGranted += CameraPermissionGranted;
        // 拒否時コールバック
        m_CallBack.PermissionDenied += CameraPermissionDenied;

        m_QRCodeReder = QRCodeReder.Instance;
    }

    // Update is called once per frame
    void Update()
    {
        if(m_StartCamera)
        {
            m_ResultText.text = m_QRCodeReder.ReadQRCodeWebCamTexture(m_webCamTexture);
        }
    }

    /// <summary>
    /// ボタン押下時の処理
    /// </summary>
    public void OnButton()
    {
        if (!m_StartCamera)
        {
            // チェック
            if (CheckCamera())
            {
                StartCamera();
            }
        }
        else
        {
            m_ResultText.text = string.Empty;
            m_webCamTexture.Stop();
            // カメラ停止用
            m_ButtonText.text = "StartCamera";
            m_StartCamera = false;
        }
    }

    /// <summary>
    /// カメラ開始
    /// </summary>
    private void StartCamera()
    {
        if (m_webCamTexture == null)
        {
            // RawImageのサイズに合わせる
            var width = m_CameraView.rectTransform.rect.width;
            var height = m_CameraView.rectTransform.rect.height;
            // サイズ設定
            m_webCamTexture = new WebCamTexture((int)width, (int)height, 30);
            // オートフォーカスの位置設定
            m_webCamTexture.autoFocusPoint = new Vector2(width * 0.5f, height * 0.5f);
            // カメラが写している画像をゲーム画面に表示
            m_CameraView.texture = m_webCamTexture;
        }
        // カメラの使用を開始
        m_webCamTexture.Play();

        // カメラ停止用
        m_ButtonText.text = "StopCamera";
        m_StartCamera = true;
    }

    /// <summary>
    /// 使用できるかどうかチェックチェック
    /// </summary>
    /// <returns></returns>
    private bool CheckCamera()
    {
        try
        {
            // カメラの使用が許可チェック
            if (!Permission.HasUserAuthorizedPermission(Permission.Camera))
            {
                // カメラの使用許可リクエスト
                Permission.RequestUserPermission(Permission.Camera, m_CallBack);
                // カメラ使用チェック
                m_CameraCheck = true;
                // ボンタン使えなくする
                m_Button.gameObject.SetActive(false);
                // まだカメラ使用OKされていない状態へ
                return false;
            }
            else
            {
                // カメラ使用OK
                return true;
            }
        }
        catch(Exception e)
        {   
            m_ResultText.text = e.Message;
            return false;
        }
    }

    /// <summary>
    /// カメラパーミッションおK
    /// </summary>
    /// <param name="type"></param>
    private void CameraPermissionGranted(string type)
    {
        if(type == Permission.Camera)
        {
            m_CameraCheck = false;
            // ボンタン使えなくする
            m_Button.gameObject.SetActive(true);
            // カメラ起動
            StartCamera();
        }
    }

    /// <summary>
    /// カメラパーミッション失敗
    /// </summary>
    /// <param name="type"></param>
    private void CameraPermissionDenied(string type)
    {
        if (type == Permission.Camera)
        {
            // カメラ使用不可
            m_CameraCheck = false;
            // ボンタン有効
            m_Button.gameObject.SetActive(true);
        }
    }
}

あとはCanvasにWebCameraスクリプトを貼り付けます。

で、ボタンにWebCameraのボタンクリック時の処理を設定して

Androidで実行すると・・・・

例外が出て、何もできません。
例外が出るタイミングが
Permission.HasUserAuthorizedPermission(Permission.Camera)
この部分なのでだいぶ意味が分からないです・・・・
なんでや・・・・

コメント

タイトルとURLをコピーしました