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

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. Codeforces Gym 104059B - Breeding Bugs

    简要题意 Virtual Judge 传送门 | Codeforces Gym 传送门 给出一个长度为 \(n\) 的序列 \(a\),你需要从中选出一些数,使其两两相加不为质数.输出最大可以选择多少 ...

  2. SpringBoot源码学习3——SpringBoot启动流程

    系列文章目录和关于我 一丶前言 在 <SpringBoot源码学习1--SpringBoot自动装配源码解析+Spring如何处理配置类的>中我们学习了SpringBoot自动装配如何实现 ...

  3. 深入Typescript--02-Typescript数据类型

    基本类型 一.最最基础的类型 布尔.数字.字符串类型 let bool:boolean = true; let num:number = 10; let str:string = 'hello wor ...

  4. absolute定位后居中的方法

    要求 : 子级需要加动画上下动起来,并且需要在全屏居中 html代码如下: <div class="row m-0 w-100 mybanner"> <!-- 左 ...

  5. flutter学习第一天笔记-----学习资源总结

  6. Zabbix“专家坐诊”第180期问答汇总

    问题一 Q:老师,请教个问题,zabbix通过自动发现扫描网段,然后添加主机,有没有什么办法区分路由器或者交换机类型的方法,这样才能把交换机模板或者路由器模板挂给对应的主机A:不多的话, 批量加2次模 ...

  7. Vue过滤案例、按键修饰符、数据双向绑定

    目录 Vue过滤案例.按键修饰符.数据双向绑定 一.v-for能循环的类型 二.js的几种循环方式 三.key值的解释 四.数组.对象的检测与更新 五.input的几个事件 六.事件修饰符 七.按键修 ...

  8. ICSharpCode.SharpZipLib.Zip 解析时报错System.NotSupportedException: No data is available for encoding 936

    分析原因 利用ICSharpCode.SharpZipLib.Zip进行APK解析时,因为APK内编译的名称为中文,查询微软开发文档936为gb2312中文编码 微软开发文档地址https://doc ...

  9. P4349 [CERC2015]Digit Division

    题目传送门 思路 以下纯考场思路. 今天模拟赛考到了这题的加强版,然后预处理写炸了,\(100\) 变成 \(70\),当是给 CSP 攒 rp 了. 首先一眼看到题目可能会没有思路,没什么关系,手推 ...

  10. 理解JS函数之call,apply,bind

    前言 在 JavaScript 中,apply.bind 和 call 是三个重要的函数,它们都是 Function.prototype 的方法.这些函数可以让我们动态地改变函数的 this 值,或者 ...