Unity ARCore动态增加识别图

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

       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
{
    /// <summary>
    /// Adds images to the reference library at runtime.
    /// </summary>
    [RequireComponent(typeof(ARTrackedImageManager))]
    public class DynamicLibrary : MonoSingleton<DynamicLibrary>
    {
        [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;
        }
    }
    
}

 

posted @ 2022-07-21 16:09  D个人笔记  阅读(260)  评论(0编辑  收藏  举报