HoloLens开发手记 - Unity之Locatable camera 使用相机
Enabling the capability for Photo Video Camera 启用相机能力
为了使用摄像头,我们必须启用WebCam能力。
- 在Unity中打开Player settings
- 展开Windows Store标签页
- 在"Publishing Settings > Capabilities"部分勾选WebCam能力
同一时刻只能执行一次相机操作。为了识别当前相机处在哪种模式下(拍照还是视频),你可以通过UnityEngine.VR.WSA.WebCam.Mode API检查。
Photo Capture 捕获照片
命名空间: UnityEngine.VR.WSA.WebCam
类型: PhotoCapture
PhotoCapture类允许我们使用相机拍摄静态照片。正常的使用模式如下:
- 创建PhotoCapture对象
- 使用我们想要的设置来创建一个CameraParameters对象
- 调用StartPhotoModeAsync()方法开始拍照模式
- 拍摄想要的照片
- (可选项)进一步处理捕获的图像
- 关闭拍照模式并释放资源
Common Set Up for PhotoCapture 使用PhotoCapture的通用做法
对于任何拍照方式,开始步骤都是像下面这样:
创建PhotoCapture对象
PhotoCapture photoCaptureObject = null;
void Start()
{
PhotoCapture.CreateAsync(false, OnPhotoCaptureCreated);
}
存储对象,配置拍摄参数并开始拍照模式
void OnPhotoCaptureCreated(PhotoCapture captureObject)
{
photoCaptureObject = captureObject; Resolution cameraResolution = PhotoCapture.SupportedResolutions.OrderByDescending((res) => res.width * res.height).First(); CameraParameters c = new CameraParameters();
c.hologramOpacity = 0.0f;
c.cameraResolutionWidth = cameraResolution.width;
c.cameraResolutionHeight = cameraResolution.height;
c.pixelFormat = CapturePixelFormat.BGRA32; captureObject.StartPhotoModeAsync(c, false, OnPhotoModeStarted);
}
最后关闭相机时需要使用同样的清理代码
void OnStoppedPhotoMode(PhotoCapture.PhotoCaptureResult result)
{
photoCaptureObject.Dispose();
photoCaptureObject = null;
}
完成这些步骤后,你可以挑选使用哪种方式捕获照片。
Capture a Photo to a File 捕获照片到文件
最简单的做法是直接将照片捕获到文件。照片可以被存储为PNG或JPG文件。
如果我们成功开始了拍照模式,需要拍照并将照片存储到磁盘上,做法如下:
private void OnPhotoModeStarted(PhotoCapture.PhotoCaptureResult result)
{
if (result.success)
{
string filename = string.Format(@"CapturedImage{0}_n.jpg", Time.time);
string filePath = System.IO.Path.Combine(Application.persistentDataPath, filename); photoCaptureObject.TakePhotoAsync(filePath, PhotoCaptureFileOutputFormat.JPG, OnCapturedPhotoToDisk);
}
else
{
Debug.LogError("Unable to start photo mode!");
}
}
完成捕获照片到文件的操作后,需要退出拍照模式并清理资源
void OnCapturedPhotoToDisk(PhotoCapture.PhotoCaptureResult result)
{
if (result.success)
{
Debug.Log("Saved Photo to disk!");
photoCaptureObject.StopPhotoModeAsync(OnStoppedPhotoMode);
}
else
{
Debug.Log("Failed to save Photo to disk");
}
Capture a Photo to a Texture2D 捕获文件到Texture2D对象
我们可以把捕获的照片保存为Texture2D对象,做法和保存到文件类似。步骤如下:
在OnPhotoModeStarted()方法中,捕获一帧图像到内存中。
private void OnPhotoModeStarted(PhotoCapture.PhotoCaptureResult result)
{
if (result.success)
{
photoCaptureObject.TakePhotoAsync(OnCapturedPhotoToMemory);
}
else
{
Debug.LogError("Unable to start photo mode!");
}
}
我们需要把得到的结果赋给Texture2D对象,然后清理相机资源
void OnCapturedPhotoToMemory(PhotoCapture.PhotoCaptureResult result, PhotoCaptureFrame photoCaptureFrame)
{
if (result.success)
{
// 使用正确分辨率创建Texture2D对象
Resolution cameraResolution = PhotoCapture.SupportedResolutions.OrderByDescending((res) => res.width * res.height).First();
Texture2D targetTexture = new Texture2D(cameraResolution.width, cameraResolution.height);
// 将图像数据拷贝到Texture2D对象中
photoCaptureFrame.UploadImageDataToTexture(targetTexture);
// 进一步使用Texture2D对象,比如赋给材质神马的
}
// 清理相机
photoCaptureObject.StopPhotoModeAsync(OnStoppedPhotoMode);
}
Capture a Photo and Interact with the Raw bytes 捕获照片并和原始数据交互
为了在内存中操作图像原始数据,需要的步骤和捕获图片到Texture2D类似,不同之处在于,OnCapturedPhotoToMemory()方法里可以获得图像原始数据并操作它们。
在本示例中,我们会创建一个List<Color>用来进一步处理或者直接通过SetPixels()方法来应用于Texture2D对象。
void OnCapturedPhotoToMemory(PhotoCapture.PhotoCaptureResult result, PhotoCaptureFrame photoCaptureFrame)
{
if (result.success)
{
List<byte> imageBufferList = new List<byte>();
// 复制原始 IMFMediaBuffer 数据到空的list
photoCaptureFrame.CopyRawImageDataIntoBuffer(imageBufferList); //本例使用 BGRA32 格式捕获照片.
int stride = ;
float denominator = 1.0f / 255.0f;
List<Color> colorArray = new List<Color>();
for (int i = imageBufferList.Count - ; i >= ; i -= stride)
{
float a = (int)(imageBufferList[i - ]) * denominator;
float r = (int)(imageBufferList[i - ]) * denominator;
float g = (int)(imageBufferList[i - ]) * denominator;
float b = (int)(imageBufferList[i - ]) * denominator; colorArray.Add(new Color(r, g, b, a));
}
// 接下来可以把list用做进一步的处理 }
photoCaptureObject.StopPhotoModeAsync(OnStoppedPhotoMode);
}
Video Capture 捕获视频
命名空间: UnityEngine.VR.WSA.WebCam
类型: VideoCapture
捕获视频的用法和捕获照片类似,不同的地方在于你必须指定一个帧率(FPS)并且你只能以MP4格式把视频直接存储到磁盘上。步骤如下:
- 创建VideoCapture对象
- 使用我们想要的设置来创建一个CameraParameters对象
- 调用 StartVideoModeAsync()方法开始视频捕获模式
- 开始录制视频
- 停止录制视频
- 停止视频捕获模式并释放相机资源
创建并配置VideoCapture对象
void Start ()
{
VideoCapture.CreateAsync(false, OnVideoCaptureCreated);
} void OnVideoCaptureCreated (VideoCapture videoCapture)
{
if (videoCapture != null)
{
m_VideoCapture = videoCapture; Resolution cameraResolution = VideoCapture.SupportedResolutions.OrderByDescending((res) => res.width * res.height).First();
float cameraFramerate = VideoCapture.GetSupportedFrameRatesForResolution(cameraResolution).OrderByDescending((fps) => fps).First(); CameraParameters cameraParameters = new CameraParameters();
cameraParameters.hologramOpacity = 0.0f;
cameraParameters.frameRate = cameraFramerate;
cameraParameters.cameraResolutionWidth = cameraResolution.width;
cameraParameters.cameraResolutionHeight = cameraResolution.height;
cameraParameters.pixelFormat = CapturePixelFormat.BGRA32; m_VideoCapture.StartVideoModeAsync(cameraParameters,
VideoCapture.AudioState.None,
OnStartedVideoCaptureMode);
}
else
{
Debug.LogError("Failed to create VideoCapture Instance!");
}
}
一旦配置完成VideoCapture对象,我们就开始录制视频
void OnStartedVideoCaptureMode(VideoCapture.VideoCaptureResult result)
{
if (result.success)
{
string filename = string.Format("MyVideo_{0}.mp4", Time.time);
string filepath = System.IO.Path.Combine(Application.persistentDataPath, filename); m_VideoCapture.StartRecordingAsync(filepath, OnStartedRecordingVideo);
}
}
在开始录制后,我们需要更新UI或者行为来确保可以停止视频捕获。在这里我们只输出log。
void OnStartedRecordingVideo(VideoCapture.VideoCaptureResult result)
{
Debug.Log("Started Recording Video!");
// 我们将会通过一些方式来停止视频捕获,比如计时器或者点击手势等等
}
最后我们需要停止视频捕获,可以中国定时器或者其他输入方式来实现。
void StopRecordingVideo()
{
m_VideoCapture.StopRecordingAsync(OnStoppedRecordingVideo);
}
一旦视频捕获停止后,需要及时退出视频捕获模式并释放相机资源。
void OnStoppedRecordingVideo(VideoCapture.VideoCaptureResult result)
{
Debug.Log("Stopped Recording Video!");
m_VideoCapture.StopVideoModeAsync(OnStoppedVideoCaptureMode);
} void OnStoppedVideoCaptureMode(VideoCapture.VideoCaptureResult result)
{
m_VideoCapture.Dispose();
m_VideoCapture = null;
}
Troubleshooting 问题诊断
获取不到分辨率
- 确保你在项目中启用了WebCam能力
- 全息图像不能捕获到图片或者视频中
- 未来的更新会支持捕获全息图像
HoloLens开发手记 - Unity之Locatable camera 使用相机的更多相关文章
- HoloLens开发手记 - Unity development overview 使用Unity开发概述
Unity Technical Preview for HoloLens最新发行版为:Beta 24,发布于 09/07/2016 开始使用Unity开发HoloLens应用之前,确保你已经安装好了必 ...
- HoloLens开发手记 - Unity之摄像头篇
当你穿戴好HoloLens后,你就会处在全息应用世界的中心.当你的项目开启了"Virtual Reality Support"选项并选中了"Windows Hologra ...
- HoloLens开发手记 - Unity之Gaze凝视射线
凝视是HoloLens首要输入方式,形式功能类似于桌面系统的光标,用于选择操作全息对象.然而在Unity中并没有明确的Gaze API或者组件. 实现Gaze Implementing Gaze 概念 ...
- HoloLens开发手记 - Unity之Spatial mapping 空间映射
本文主要讨论如何在Unity项目中集成空间映射功能.Unity内置了对空间映射功能的支持,通过以下两种方式提供给开发者: HoloToolkit项目中你可以找到空间映射组件,这可以让你便捷快速地开始使 ...
- HoloLens开发手记 - Unity之Tracking loss
当HoloLens设备不能识别到自己在世界中的位置时,应用就会发生tracking loss.默认情况下,Unity会暂停Update更新循环并显示一张闪屏图片给用户.当设备重新能追踪到位置时,闪屏图 ...
- HoloLens开发手记 - Unity之Recommended settings 推荐设置
Unity提供了大量的设置选项来满足全平台的配置,对于HoloLens,Unity可以通过切换一些特定的设置来启用HoloLens特定的行为. Holographic splash screen 闪屏 ...
- HoloLens开发手记 - Unity之语音输入
对于HoloLens,语音输入是三大基本输入方式之一,广泛地运用在各种交互中.HoloLens上语音输入有三种形式,分别是: 语音命令 Voice Command 听写 Diction 语法识别 Gr ...
- HoloLens开发手记 - Unity之Persistence 场景保持
Persistence 场景保持是HoloLens全息体验的一个关键特性,当用户离开原场景中时,原场景中全息对象会保持在特定位置,当用户回到原场景时,能够准确还原原场景的全息内容.WorldAncho ...
- HoloLens开发手记 - Unity之Spatial Sounds 空间声音
本文主要讲述如何在项目中使用空间声音特性.我们主要讲述必须的插件组件和Unity声音组件和属性的设置来确保空间声音的实现. Enabling Spatial Sound in Unity 在Unity ...
随机推荐
- MySQL 5.6 中的 TIMESTAMP 和 explicit_defaults_for_timestamp 参数
安装MySQL时,有warning: [root@localhost mysql]# scripts/mysql_install_db --user=mysql Installing MySQL sy ...
- c# 反射简单使用
类库dll,将生成ExampleLib.dll文件 namespace ExampleLib { public class Example { public static string FuncA() ...
- Windows Server 2008 R2安装WAMPSERVER无法启动的解决方法
其实根本不算什么解决方法,会者不难的事.Windows Server 2008 R2(也包括其他版本的Windows)默认状态下安装WAMPSERVER经常是无法顺利启动WAMPSERVER的,尤其是 ...
- 烂泥:kickstart无人值守安装CentOS6.5
本文由秀依林枫提供友情赞助,首发于烂泥行天下. 在本次实验进行之前,首先我们要把公司的网络环境进行介绍. 注意这个网络拓扑图,也是生产环境的一个实例.同时服务器192.168.1.214已关闭ipta ...
- 面向对象and类
类和对象: 1.什么叫类:类是一种数据结构,就好比一个模型,该模型用来表述一类事物(事物即数据和动作的结合体),用它来生产真实的物体(实例). 2.什么叫对象:睁开眼,你看到的一切的事物都是一个个的对 ...
- WDK编程的一些特殊点
函数的多线程安全性在内核编程中比用户态应用程序的编程更常见. 调用源 运行环境 原因 driverEntry,DriverUnload 单线程 这两个函数由系统进程的单一线程调用,不会出现多线程同时调 ...
- ext3,ext4,xfs和btrfs文件系统性能对比
应为原文:http://www.ilsistemista.net/index.php/linux-a-unix/6-linux-filesystems-benchmarked-ext3-vs-ext4 ...
- 基于go-ceph创建CEPH块设备及快照
一.代码执行前准备 1.系统中安装了CEPH集群 2.GOPATH目录下存在src/github.com/noahdesu/go-ceph代码库 3.在ubuntu 14.04下还需apt-get l ...
- codeforces 484B B. Maximum Value(二分)
题目链接: B. Maximum Value time limit per test 1 second memory limit per test 256 megabytes input standa ...
- C语言异或运算在程序设计中的妙用
异或运算符∧也称XOR运算符.它的规则是若参加运算的两个二进位同号,则结果为0(假):异号则为1(真).即0∧0=0,0∧1=1,1∧1=0. 性质: (1).与1异或会翻转 (2).与0异或保持不变 ...