Unity ARCore动态增加识别图
阅读原文时间:2023年07月08日阅读:2

  项目需要,有两点要求说明一下

1.如果你的图片是下载生成的,那没什么问题

2.如果你的识别图是存储在APK包里的话需要调整图片属性:

代码如下:

using QFramework;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Unity.Jobs;
using UnityEditor;
using UnityEngine;

using UnityEngine.XR.ARFoundation;
using UnityEngine.XR.ARSubsystems;

namespace UnityEngine.XR.ARFoundation.Samples
{
///

/// Adds images to the reference library at runtime. ///
[RequireComponent(typeof(ARTrackedImageManager))]
public class DynamicLibrary : MonoSingleton
{
[Serializable]
public class ImageData
{
[SerializeField, Tooltip("The source texture for the image. Must be marked as readable.")]
Texture2D m_Texture;

        public Texture2D texture  
        {  
            get => m\_Texture;  
            set => m\_Texture = value;

        }

        \[SerializeField, Tooltip("The name for this image.")\]  
        string m\_Name;

        public string name  
        {  
            get => m\_Name;  
            set => m\_Name = value;  
        }

        \[SerializeField, Tooltip("The width, in meters, of the image in the real world.")\]  
        float m\_Width;

        public float width  
        {  
            get => m\_Width;  
            set => m\_Width = value;  
        }

        public AddReferenceImageJobState jobState { get; set; }  
    }

    \[SerializeField, Tooltip("The set of images to add to the image library at runtime")\]  
    ImageData\[\] m\_Images;

    /// <summary>  
    /// The set of images to add to the image library at runtime  
    /// </summary>  
    public ImageData\[\] images  
    {  
        get => m\_Images;  
        set => m\_Images = value;  
    }

    enum State  
    {  
        NoImagesAdded,  
        AddImagesRequested,  
        AddingImages,  
        Done,  
        Error  
    }

    State m\_State;

    string m\_ErrorMessage = "";

    StringBuilder m\_StringBuilder = new StringBuilder();

    private void Start()  
    {

        //var pathName = Application.persistentDataPath + "/3.jpg";  
        //Debug.Log(pathName);  
        //var bytes = ReadFile(pathName);  
        //int width = Screen.width;  
        //int height = Screen.height;  
        //Texture2D texture = new Texture2D(width, height, TextureFormat.RGB24, false);  
        //texture.LoadImage(bytes);  
        //texture = SettingTexture(texture);

        //ImageData data = new ImageData();  
        //data.texture = texture;  
        //data.name = "3Test";  
        //data.width = 0.5f;

        //m\_Images\[0\] = data;  
        manager = GetComponent<ARTrackedImageManager>();  
    }  
    public void AddImageTracked(List<string> list\_SavePath)  
    {  
        m\_Images = new ImageData\[list\_SavePath.Count\];

        for (int i = 0; i < list\_SavePath.Count; i++)  
        {  
            int width = Screen.width;  
            int height = Screen.height;  
            var bytes = ReadFile(list\_SavePath\[i\]);  
            Texture2D texture = new Texture2D(width, height, TextureFormat.RGB24, false);  
            texture.LoadImage(bytes);  
            texture = SettingTexture(texture);  
            ImageData data = new ImageData();  
            data.texture = texture;  
            data.name = i.ToString();  
            data.width = 0.5f;  
            m\_Images\[i\] = data;  
        }  
        m\_State = State.AddImagesRequested;  
    }  
    public void AddImageTracked(List<string> list\_SavePath,Dictionary<string,Sprite>dicImageTracked)  
    {  
        m\_Images = new ImageData\[list\_SavePath.Count\];

        Debug.Log(list\_SavePath.Count +"    "+ dicImageTracked.Count);

        for (int i = 0; i < list\_SavePath.Count; i++)  
        {  
            Debug.Log("SavePath   "+list\_SavePath\[i\]);  
        }

        foreach (var item in dicImageTracked)  
        {  
            Debug.Log(item.Key);  
        }

        for (int i = 0; i < list\_SavePath.Count; i++)  
        {  
            if (dicImageTracked.ContainsKey(list\_SavePath\[i\]))  
            {  
                int width = dicImageTracked\[list\_SavePath\[i\]\].texture.width;  
                int height = dicImageTracked\[list\_SavePath\[i\]\].texture.height;  
                var bytes = dicImageTracked\[list\_SavePath\[i\]\].texture.EncodeToPNG();  
                Texture2D texture = new Texture2D(width, height, TextureFormat.RGB24, false);  
                texture.LoadImage(bytes);  
                texture = SettingTexture(texture);  
                ImageData data = new ImageData();  
                data.texture = texture;  
                data.name = i.ToString();  
                data.width = 0.5f;  
                m\_Images\[i\] = data;  
            }  
            else  
                Debug.LogError("Image Not SavePath");

        }  
        m\_State = State.AddImagesRequested;  
    }

    byte\[\] ReadFile(string filePath)  
    {  
        var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);  
        fs.Seek(0, SeekOrigin.Begin);  
        var binary = new byte\[fs.Length\];  
        fs.Read(binary, 0, binary.Length);  
        fs.Close();  
        return binary;  
    }  
    void OnGUI()  
    {

        var fontSize = 50;  
        GUI.skin.button.fontSize = fontSize;  
        GUI.skin.label.fontSize = fontSize;

        float margin = 100;

        GUILayout.BeginArea(new Rect(margin, margin, Screen.width - margin \* 2, Screen.height - margin \* 2));

        switch (m\_State)  
        {  
            case State.NoImagesAdded:  
                {  
                    //if (GUILayout.Button("Add images" + manager.trackables.count))  
                    //{  
                    //    m\_State = State.AddImagesRequested;  
                    //}

                    break;  
                }  
            case State.AddingImages:  
                {  
                    m\_StringBuilder.Clear();  
                    m\_StringBuilder.AppendLine("Add image status:");  
                    foreach (var image in m\_Images)  
                    {  
                        m\_StringBuilder.AppendLine($"\\t{image.name}: {(image.jobState.status.ToString())}");  
                    }  
                  //  GUILayout.Label(m\_StringBuilder.ToString());  
                    break;  
                }  
            case State.Done:  
                {  
                  //  GUILayout.Label("All images added  " + manager.trackables.count);  
                    break;  
                }  
            case State.Error:  
                {  
                    GUILayout.Label(m\_ErrorMessage);  
                    break;  
                }  
        }

        GUILayout.EndArea();  
    }

    void SetError(string errorMessage)  
    {  
        m\_State = State.Error;  
        m\_ErrorMessage = $"Error: {errorMessage}";  
    }  
    ARTrackedImageManager manager;  
    void Update()  
    {  
        switch (m\_State)  
        {  
            case State.AddImagesRequested:  
                {  
                    if (m\_Images == null)  
                    {  
                        SetError("No images to add.");  
                        break;  
                    }

                     manager = GetComponent<ARTrackedImageManager>();  
                    if (manager == null)  
                    {  
                        SetError($"No {nameof(ARTrackedImageManager)} available.");  
                        break;  
                    }

                    // You can either add raw image bytes or use the extension method (used below) which accepts  
                    // a texture. To use a texture, however, its import settings must have enabled read/write  
                    // access to the texture.  
                    for (int i = 0; i < m\_Images.Length; i++)  
                    {  
                        if (!m\_Images\[i\].texture.isReadable)  
                        {  
                            Texture2D tex = SettingTexture(m\_Images\[i\].texture);  
                            m\_Images\[i\].texture = tex;  
                        }  
                    }

                    foreach (var image in m\_Images)  
                    {  
                        if (!image.texture.isReadable)  
                        {

                            SetError($"Image {image.name} must be readable to be added to the image library.");  
                            break;

                        }  
                       // else  
                           // Debug.LogError(" IsReadable = true  "+image.name);  
                    }

                    if (manager.referenceLibrary is MutableRuntimeReferenceImageLibrary mutableLibrary)  
                    {  
                        try  
                        {  
                            foreach (var image in m\_Images)  
                            {  
                                // Note: You do not need to do anything with the returned JobHandle, but it can be  
                                // useful if you want to know when the image has been added to the library since it may  
                                // take several frames.  
                                image.jobState = mutableLibrary.ScheduleAddImageWithValidationJob(image.texture, image.name, image.width);  
                            }

                            m\_State = State.AddingImages;  
                        }  
                        catch (InvalidOperationException e)  
                        {  
                            SetError($"ScheduleAddImageJob threw exception: {e.Message}");  
                        }  
                    }  
                    else  
                    {  
                        SetError($"The reference image library is not mutable.");  
                    }

                    break;  
                }  
            case State.AddingImages:  
                {  
                    // Check for completion  
                    var done = true;  
                    foreach (var image in m\_Images)  
                    {  
                        if (!image.jobState.jobHandle.IsCompleted)  
                        {  
                            done = false;  
                            break;  
                        }  
                    }

                    if (done)  
                    {  
                        m\_State = State.Done;  
                        GameManager.Instance.finish = true;  
                    }

                    break;  
                }  
        }  
    }

    Texture2D SettingTexture( Texture2D texture)  
    {  
        //TextureImporter ti = (TextureImporter)TextureImporter.GetAtPath(AssetDatabase.GetAssetPath(texture));  
        //ti.isReadable = true;  
        //AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(texture));

        Texture2D tex = new Texture2D(texture.width, texture.height, TextureFormat.RGB24,false);  
        byte\[\] data = texture.EncodeToPNG();  
        tex.LoadImage(data);  
        Debug.Log(tex.isReadable);  
        return tex;  
    }  
}

}

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器