栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

EasyAR+ZXing实现UnityAR二维码扫描

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

EasyAR+ZXing实现UnityAR二维码扫描

本来打算使用高通的AR插件来实现,但是高通的官网老是登录不上去,没有办法只有使用EasyAR来实现(手动滑稽)

EasyAR注册以及下载

首先,我们现在EasyAR的官网进行注册;

注册完成后,申请授权

不做商业开发用,我们选择个人版就好

应用名称和PaceageName需要和在unity中一致(本文我们只做Android开发,故不用申请IOS的BundleID)

 授权密钥复制保存下来,等会儿要用;

 申请API KEY

 

 API KEY和API Seret复制下来,等会也要用;

接下来,下载SDK;

传送门:

下载-EasyAR官网https://www.easyar.cn/view/download.html

 这里我们找到UnityPlugin 下载就好;

EasyAR导入Unity

EasyAR4.4.0的版本导入Unity的方式和往常的import的不太一样,需要在Unity的packageManager中进行操作

 

 载入你刚才下好的包;

Zxing插件下载以及导入

插件已上传百度网盘,如有需要,自行提取

链接:https://pan.baidu.com/s/16CuwPVNxO4tSu2IOVEYCQg 
提取码:xjza 
在unity的Assets文件夹下新建一个 Plugins文件夹,将ZXing插件导入;

Unity打包设置

选择Android

点击PlayerSetting -> player

进行配置;

 

 JDK以及AndroidSDK的接入配置

 

 JDK不要下载过高版本,我下载的是JDK8

AndroidSDK使用的是7.0的版本

具体的SDK和JDK下载以及配置,这里不做详细介绍,如有需要的朋友,可以参考这篇博客

(31条消息) 2018年Unity结合Android SDK下载安装及配置教程_Sinkiang的博客-CSDN博客_unity 安卓sdkhttps://blog.csdn.net/dxj467822057/article/details/80198165?ops_request_misc=&request_id=&biz_id=102&utm_term=unity%E6%8E%A5%E5%85%A5androidsdk&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-6-80198165.first_rank_v2_pc_rank_v29&spm=1018.2226.3001.4187

场景配置

找到Resources文件夹下的EasyAR文件夹中的Setting

 填入,我们当时申请的密钥、APIKEY 、APISecret(PS:如果需要使用云识别,就填入ServerAddress和CloudRecognizerAppID,不需要就不用填)

为了实现图片追踪的效果,我们需要在场景中新建如下的Object

 以及一个ImageTarget

 场景中的Camera 需要设置成单色模式,背景色选择成黑色;

设定需要追踪的图像

在Assets文件夹下新建一个StreamingAssets文件夹,将需要追踪的图片放进来;并在ImageTarget的Inspector面板设置好参数;

 在场景中新建一个Cube,并将它作为ImageTarget的子物体;

至此,打包成APK包,在手机上测试,已经能够完成,识别图片显示模型,并追踪图片位置;

下面开始添加二维码扫描的功能;

二维码扫描脚本

在场景中的ImageTarget下在新建一个Sphere,用来测试根据不同的二维码识别信息显示不同的模型;

 新建一个Canvas,在Canvas下新建一个Panel,然后在panel下新建几个Text,用来显示我们的Debug信息;

具体的UI层级可以参考我的,也可以自行组织;

首先,我们需要获取到相机的Texture。在查阅了EasyAR的API文档后,我们知道了,官方为我们封装了方法,可以直接调用;

首先我们获取到场景中的“CameraDevice”,找到他的CameraImageRenderer组件,直接调用官方的方法;

CameraImageRenderer cameraRenderer = GameObject.Find("AR Session (EasyAR)/Camera Device").GetComponent();
cameraRenderer.RequestTargetTexture(targetTextureEventHandler); 

使用这个方法要注意,在用完后一定要调用释放资源的方法;

  //释放资源!!!
  cameraRenderer.DropTargetTexture(targetTextureEventHandler);

因为二维码扫描的是Texture2D所以我们在获取了相机的Texture之后,需要对Texture进行处理,需要将Texture转换为Texture2D;这里可以使用RenderTexture作为媒介来进行转换;具体代码请看示例代码;

在获取二维码信息是,因为需要读取的是Color32的信息,所以,还需要对Texture进行处理;

因为,EasyAR的组件对需要显示的模型是自动控制的,而在这里,我们希望,在没有扫描出二维码信息的时候不显示,并且能够根据不同的二维码显示不同的信息;

所以,我们需要关闭EasyAR的Target的自动显示功能;

   GetComponent().ActiveControl = TargetController.ActiveControlStrategy.None;     
示例代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using easyar;
using ZXing;
using UnityEngine.UI;
using System;

//读取摄像头图像 
//扫描二维码
//如果和预设信息一致就显示模型
public class ScanQRCode : MonoBehaviour
{
    public Text isScanBool;
    public Text scanMessage;
    public GameObject cube;
    public GameObject spare;
    public GameObject trucker;
    /// 
    /// 扫描时间间隔
    /// 
    float interval = 0.5f;
    /// 
    /// 32位颜色信息
    /// 
    Color32[] data;
    /// 
    /// 用来存储相机贴图信息
    /// 
    Texture camTexture;
    /// 
    /// 识别结果
    /// 
    Result result;
    /// 
    /// 二维码识别
    /// 
    BarcodeReader barcodeReader;//库文件对象 二维码信息保存的地方
    /// 
    /// 是否显示模型
    /// 
    public bool isShow ;

    private Action targetTextureEventHandler;
    /// 
    /// 是否开始扫描
    /// 
    private bool isScan = false;

    private void Awake()
    {
        targetTextureEventHandler = (camera, texture) =>
        {
            if (texture)
            {
                //获取相机纹理贴图
                camTexture = texture;
            }
            
        };
    }
    private void Start()
    {
        isShow = false;
        //ImageTrackerframeFilter m_imageTrackerframeFilter = trucker.GetComponent();
        //因为我们要让GameObject在扫描识别到二维码之后显示对应的GameObject
        //所以让显示GameObject不接受EasyAR的自动控制
        GetComponent().ActiveControl = TargetController.ActiveControlStrategy.None;     
    }
    private void FixedUpdate()
    {
        StartScan();
        ScanInterval(3);
    }

    /// 
    /// 扫描间隔
    /// 
    /// 间隔时间
    void ScanInterval(float s_interval)
    {
        if (isScan)//开始扫描
        {
            interval += Time.deltaTime;
            if (interval >= s_interval)
            {
                interval = 0;//重置计时器
                Scan();//扫描
            }
        }
    }
    /// 
    /// 开启扫描
    /// 
    void StartScan()
    {
        //如果扫描到了目标就开启扫描
        if (GetComponent().IsTracked)
        {
            barcodeReader = new BarcodeReader();
            //开始扫描
            isScan = true;
            isScanBool.text = "true";
        }
        else
        {
            isScan = false;
            isScanBool.text = "false";
            isShow = false;
            spare.SetActive(false);
            cube.SetActive(false);
        }
    }
    

    /// 
    /// 扫描二维码
    /// 
    void Scan()
    {
        scanMessage.text = "StartScan";
        CameraImageRenderer cameraRenderer = GameObject.Find("AR Session (EasyAR)/Camera Device").GetComponent();
        cameraRenderer.RequestTargetTexture(targetTextureEventHandler); 
        scanMessage.text = "GetCamera";
        //转换成TEXTURE2D并获取color32数据信息
        data = TextureToTexture2D(camTexture).GetPixels32();
        //获取二维码信息
        result = barcodeReader.Decode(data, camTexture.width, camTexture.height);
        scanMessage.text = "ScanQRCode";
        if (result != null)
        {
            isScan = false;
            isScanBool.text = "false";
            isShow = true;

            scanMessage.text = result.Text;
            if (result.Text == "cube0" || result.Text == "Cube0")
            {
                cube.SetActive(true);
            }
            if (result.Text == "spare0" || result.Text == "Spare0")
            {
                spare.SetActive(true);
            }
            //释放资源!!!
            cameraRenderer.DropTargetTexture(targetTextureEventHandler);
        }
        else
        {
            isShow = false;
            spare.SetActive(false);
            cube.SetActive(false);
        }
    }
    /// 
    /// 转换成2D纹理
    /// 
    /// 需要转换的纹理
    /// 
    private Texture2D TextureToTexture2D(Texture texture)
    {
        Texture2D texture2D = new Texture2D(texture.width, texture.height, TextureFormat.RGBA32, false);
        RenderTexture currentRT = RenderTexture.active;
        RenderTexture renderTexture = RenderTexture.GetTemporary(texture.width, texture.height, 32);
        Graphics.Blit(texture, renderTexture);

        RenderTexture.active = renderTexture;
        texture2D.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0);
        texture2D.Apply();

        RenderTexture.active = currentRT;
        RenderTexture.ReleaseTemporary(renderTexture);

        return texture2D;
    }
}

 将脚本挂载在Image Target下就可以了,并将对应的参数设置好;

 将ImageTarget下的Cube和Sphere隐藏掉

直接打包成APK,在手机上进行运行测试;

测试效果

参考文章

(31条消息) Unity技术分享之Unity中Texture和Texture2D格式互相转换_月儿圆-CSDN博客_unity的texture2dhttps://blog.csdn.net/s15100007883/article/details/80411638?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164188209416780255241008%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=164188209416780255241008&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-1-80411638.first_rank_v2_pc_rank_v29&utm_term=unity+texture%E8%BD%ACtexture2d&spm=1018.2226.3001.4187

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/704186.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号