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

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;
}
} }

Unity ARCore动态增加识别图的更多相关文章

  1. Unity3D 动态地创建识别图

    前面介绍了EasyAR的单图识别,它是提前在Unity设置好图片路径的,那么如果我们的图片是存储在服务器上的,那么我们肯定不能直接把服务的图片地址填上去了.这个时候我们可以动态地创建识别图.步骤如下: ...

  2. 可以动态增加系统的U盘启动器(基于grub)

    前言:最近面试无果,就在宿舍看那本<30天自制操作系统>,里面使用的系统文件格式是img,要在真机上运行,就需要使用U盘进行启动,因为现在都没有软盘.而网上很多都是用软件写入U盘的.反正我 ...

  3. 使用Unity创造动态的2D水体效果

    者:Alex Rose 在本篇教程中,我们将使用简单的物理机制模拟一个动态的2D水体.我们将使用一个线性渲染器.网格渲染器,触发器以及粒子的混合体来创造这一水体效果,最终得到可运用于你下款游戏的水纹和 ...

  4. Unity3D 创建动态的立方体图系统

    Unity3D 创建动态的立方体图系统 这一篇主要是利用上一篇的Shader,通过脚本来完成一个动态的立方体图变化系统. 准备工作如下: 创建一个新的场景.一个球体.提供给场景一个平行光,准备2个立方 ...

  5. C++基础知识:动态类型识别

    1.动态类型指的是基类指针所指向的对象的实际类型 2.C++中的多态根据实际的对象类型调用对应的虚函数(1)可以在基类中定义虚函数返回具体的类型信息(2)所有的派生类都必须实现类型相关的虚函数(3)每 ...

  6. 3D动态人脸识别技术分析——世纪晟人脸识别实现三维人脸建模

    - 目录 - 国内3D动态人脸识别现状概况 - 新形势下人脸识别技术发展潜力 - 基于深度学习的3D动态人脸识别技术分析 1. 非线性数据建模方法 2. 基于3D变形模型的人脸建模 - 案例结合——世 ...

  7. Hyperledger fablic 1.0 在centos7环境下的安装与部署和动态增加节点

    Hyperledger fablic 1.0 在centos7环境下的安装与部署和动态增加节点 一.安装docker 执行代码如下: curl -sSL https://get.daocloud.io ...

  8. iOS-------- Objective-C多态:动态类型识别+动态绑定+动态加载

    一.Objective-C多态 1.概念:相同接口,不同的实现 来自不同类可以定义共享相同名称的方法. 动态类型能使程序直到执行时才确定对象所属类型 动态类型绑定能使程序直到执行时才确定要对对象调用的 ...

  9. Objective-C多态:动态类型识别+动态绑定+动态加载

    http://blog.csdn.net/tskyfree/article/details/7984887 一.Objective-C多态 1.概念:相同接口,不同的实现 来自不同类可以定义共享相同名 ...

  10. vue项目中,无需打包而动态更改背景图以及标题

    1.背景 今天,项目经理对已完成的项目提出了一个需求,即项目的基础功能目前针对于各个基层法院都适用,而对于不同的法院,我们每次都需要前端研发来更改所属法院的法院名称以及背景图,这样对于演示者来说是非常 ...

随机推荐

  1. VUE Angular通用动态列表组件-亦可为自动轮播组件-01-根据数据量自动纵向滚动,鼠标划入停止滚动

    本文为纵向轮播,横向轮播/动态列表组件请戳---- 代码是angular的,稍微改改就可以放入Vue项目里,差别不大哟 以下代码可以根据实际情况自行调整 父组件html <app-scroll- ...

  2. FAQ selenium无法click的一个案例分享(1)

    案例描述 http://sahitest.com/demo/php/fileUpload.htm 来自助教咨询 点击网页的第一个选择文件,如图 示例代码  from selenium import w ...

  3. Flex布局专题

    Flex布局专题 参照 https://www.runoob.com/w3cnote/flex-grammar.html 下面是自己看代码的一下 小结,和认识,加笔记,加原文 认识容器 flex布局需 ...

  4. 如何使用 ArrayPool

    如果不停的 new 数组,可能会造成 GC 的压力,因此在 aspnetcore 中推荐使用 ArrayPool 来重用数组,本文将介绍如何使用 ArrayPool. 使用 ArrayPool Arr ...

  5. 安卓逆向 创建自己一个SO库

    要求 1.能调用java中的方法 2.有返回值 如何完成一个SO ? public native String getText(); //第一肯定是得创建一个方法 cmd指令自动生成对应接口 生成完后 ...

  6. 【python自动化测试】1- python基础和pycharm使用

    python基础和pycharm使用 1.pycharm 1.1 为特定格式文件添加头信息 File--Settings--Editor--File and Code Templates--Pytho ...

  7. JZOJ 1038. 【SCOI2009】游戏

    题目 自己找 思路 大致过程见 JZOJ 3232. [佛山市选2013]排列 而本题改成种类数 那么我们不需要 \(ln\) 这个东东 直接转移 \(f\) 改成种类数 对于可能转移过来的状态,直接 ...

  8. BI工具术语表大全:从字母A-Z全面收录

    谈到商业智能行业,变革是不可避免的.为了跟上步伐,各种各样的BI 解决方案正在快速迭代更新,以满足企业的数字化需求,那么市场上BI 工具种类繁杂,到底如何选择适合功能全面.满足自己企业运转情况的.合适 ...

  9. rin和快速迭代

    链接:https://ac.nowcoder.com/acm/contest/3002/E rin最近喜欢上了数论. 然而数论实在太复杂了,她只能研究一些简单的问题. 这天,她在研究正整数因子个数的时 ...

  10. Postgresql清理WAL日志

    WAL是Write Ahead Log的简写,和oracle的redo日志类似,存放在$PGDATA/pg_xlog中,10版本以后在$PGDATA/pg_wal目录. 1.如果开启了归档,在目录ar ...