Enabling the capability for Photo Video Camera 启用相机能力


为了使用摄像头,我们必须启用WebCam能力。

  1. 在Unity中打开Player settings
  2. 展开Windows Store标签页
  3. 在"Publishing Settings > Capabilities"部分勾选WebCam能力

同一时刻只能执行一次相机操作。为了识别当前相机处在哪种模式下(拍照还是视频),你可以通过UnityEngine.VR.WSA.WebCam.Mode API检查。

Photo Capture 捕获照片


命名空间UnityEngine.VR.WSA.WebCam

类型PhotoCapture

PhotoCapture类允许我们使用相机拍摄静态照片。正常的使用模式如下:

  1. 创建PhotoCapture对象
  2. 使用我们想要的设置来创建一个CameraParameters对象
  3. 调用StartPhotoModeAsync()方法开始拍照模式
  4. 拍摄想要的照片
    • (可选项)进一步处理捕获的图像
  5. 关闭拍照模式并释放资源

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格式把视频直接存储到磁盘上。步骤如下:

  1. 创建VideoCapture对象
  2. 使用我们想要的设置来创建一个CameraParameters对象
  3. 调用 StartVideoModeAsync()方法开始视频捕获模式
  4. 开始录制视频
  5. 停止录制视频
  6. 停止视频捕获模式并释放相机资源

创建并配置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 使用相机的更多相关文章

  1. HoloLens开发手记 - Unity development overview 使用Unity开发概述

    Unity Technical Preview for HoloLens最新发行版为:Beta 24,发布于 09/07/2016 开始使用Unity开发HoloLens应用之前,确保你已经安装好了必 ...

  2. HoloLens开发手记 - Unity之摄像头篇

    当你穿戴好HoloLens后,你就会处在全息应用世界的中心.当你的项目开启了"Virtual Reality Support"选项并选中了"Windows Hologra ...

  3. HoloLens开发手记 - Unity之Gaze凝视射线

    凝视是HoloLens首要输入方式,形式功能类似于桌面系统的光标,用于选择操作全息对象.然而在Unity中并没有明确的Gaze API或者组件. 实现Gaze Implementing Gaze 概念 ...

  4. HoloLens开发手记 - Unity之Spatial mapping 空间映射

    本文主要讨论如何在Unity项目中集成空间映射功能.Unity内置了对空间映射功能的支持,通过以下两种方式提供给开发者: HoloToolkit项目中你可以找到空间映射组件,这可以让你便捷快速地开始使 ...

  5. HoloLens开发手记 - Unity之Tracking loss

    当HoloLens设备不能识别到自己在世界中的位置时,应用就会发生tracking loss.默认情况下,Unity会暂停Update更新循环并显示一张闪屏图片给用户.当设备重新能追踪到位置时,闪屏图 ...

  6. HoloLens开发手记 - Unity之Recommended settings 推荐设置

    Unity提供了大量的设置选项来满足全平台的配置,对于HoloLens,Unity可以通过切换一些特定的设置来启用HoloLens特定的行为. Holographic splash screen 闪屏 ...

  7. HoloLens开发手记 - Unity之语音输入

    对于HoloLens,语音输入是三大基本输入方式之一,广泛地运用在各种交互中.HoloLens上语音输入有三种形式,分别是: 语音命令 Voice Command 听写 Diction 语法识别 Gr ...

  8. HoloLens开发手记 - Unity之Persistence 场景保持

    Persistence 场景保持是HoloLens全息体验的一个关键特性,当用户离开原场景中时,原场景中全息对象会保持在特定位置,当用户回到原场景时,能够准确还原原场景的全息内容.WorldAncho ...

  9. HoloLens开发手记 - Unity之Spatial Sounds 空间声音

    本文主要讲述如何在项目中使用空间声音特性.我们主要讲述必须的插件组件和Unity声音组件和属性的设置来确保空间声音的实现. Enabling Spatial Sound in Unity 在Unity ...

随机推荐

  1. Effective Java 40 Design method signatures carefully

    Principle Choose method names carefully. Don't go overboard in providing convenience methods. Avoid ...

  2. CI框架SESSION重写

    这个是我平时用的是 PHP 自己的 Session 机制,是真正的 PHP Session,存储在服务器端,而不是用的 cookie 接口完全兼容于 CI 2.0.x 的 Session 类库,也就是 ...

  3. 在Windows8下安装SQL Server 2005无法启动服务

    因为尝鲜安装了Windows8,的确很不错,唯一的遗憾就是不支持Sql Server 2005的安装.找了很多办法,基本上都有缺陷.现在终于找到一种完全正常没有缺陷的办法了,和大家分享一下. 0.一定 ...

  4. SQL Server服务器名称与默认实例名不一致的修复方法

    SQL Server服务器名称与默认实例名不一致的修复方法 分类: 个人累积 SQl SERVER 数据库复制2011-08-10 09:49 10157人阅读 评论(0) 收藏 举报 sql ser ...

  5. 如何解决分布式系统数据事务一致性问题(HBase加Solr)

    如何解决分布式系统数据事务一致性问题 (HBase加Solr) 摘要:对于所有的分布式系统,我想事务一致性问题是极其非常重要的问题,因为它直接影响到系统的可用性.本文以下所述所要解决的问题是:对于入H ...

  6. 通过java的Runtime.getRuntime()和System.getProperties()来获取系统的信息

    第一种,通过Runtime.getRuntime()来获取系统信息. 通过java来获取系统以下的信息: 主机名: OS 名称:         OS 版本: OS 制造商: OS 配置: 独立工作站 ...

  7. linux中如何查看进程对应的cpu使用情况?

    使用ps aux | grep <进程名>即可查看指定进程的cpu使用情况.

  8. python 小程序练习

    还有一些小bug 基本有 输入用户名密码 认证成功后显示欢迎信息 输出三次后锁定 # -*- coding:utf-8 -*- account_file=('C:\Users\guigu\Deskto ...

  9. Linux iptables

    一.简介 http://liaoph.com/iptables/ 二.操作 1)查看规则 iptables -t filter -L -n iptables -t nat -L -n iptables ...

  10. zookeeper中Watcher和Notifications

    问题导读:1.zookeeper观察者什么时候调用?2.传统远程轮询服务存在什么问题?3.zk中回调服务的机制是什么?4.zk中watcher为什么不永久注册?5.什么是znode? 在阅读之前首先明 ...