HoloLens — Capturing Photo in Unity and Saving to Disk

拜拜、爱过 提交于 2019-12-23 21:16:14

问题


I'm trying to save a captured photo to the disk on HoloLens. I'm getting the following exception error when trying to save a photo in Unity, based on this example. For a while I couldn't get the correct directory to save the file in, and now I think I've finally got that part working (see the getFolderPath function below). However, now I get this exception quoted below. Any ideas on how to fix this?

I'm using the Origami example code and I've simply attached this script PhotoCaptureTest.cs to the OrigamiCollection game object in Unity. Does anyone know how to fix this or how I can debug this more easily?

Exception thrown: 'System.NullReferenceException' in UnityEngine.dll NullReferenceException: Object reference not set to an instance of an object. at UnityEngine.VR.WSA.WebCam.PhotoCapture.InvokeOnCapturedPhotoToDiskDelegate(OnCapturedToDiskCallback callback, Int64 hResult) at UnityEngine.VR.WSA.WebCam.PhotoCapture.$Invoke9(Int64 instance, Int64* args) at UnityEngine.Internal.$MethodUtility.InvokeMethod(Int64 instance, Int64* args, IntPtr method) (Filename: Line: 0)

using UnityEngine;
using System.Collections;
using UnityEngine.VR.WSA.WebCam;
using System.Linq;
using Windows.Storage;
using System;
using System.IO;

public class PhotoCaptureTest : MonoBehaviour {

    PhotoCapture photoCaptureObject = null;
    string folderPath = "";
    bool haveFolderPath = false;

    // Use this for initialization
    void Start ()
    {
        getFolderPath();
        while (!haveFolderPath)
        {
            Debug.Log("Waiting for folder path...");
        }
        Debug.Log("About to call CreateAsync");
        PhotoCapture.CreateAsync(false, OnPhotoCaptureCreated);
        Debug.Log("Called CreateAsync");
    }

    // Update is called once per frame
    void Update () {

    }

    async void getFolderPath()
    {
        StorageLibrary myPictures = await Windows.Storage.StorageLibrary.GetLibraryAsync(Windows.Storage.KnownLibraryId.Pictures);
        Windows.Storage.StorageFolder savePicturesFolder = myPictures.SaveFolder;
        Debug.Log("savePicturesFolder.Path is " + savePicturesFolder.Path);
        folderPath = savePicturesFolder.Path;
        haveFolderPath = true;
    }

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

    private void OnPhotoModeStarted(PhotoCapture.PhotoCaptureResult result)
    {
        if (result.success)
        {
            string filename = string.Format(@"\CapturedImage{0}_n.jpg", Time.time);
            string filePath = folderPath + filename;
            string currentDir = Directory.GetCurrentDirectory();
            Debug.Log("Current working direcotry is " + currentDir);
            Debug.Log("Saving photo to " + filePath);

            try
            {
                photoCaptureObject.TakePhotoAsync(filePath, PhotoCaptureFileOutputFormat.JPG, OnCapturedPhotoToDisk);
            }
            catch (System.ArgumentException e)
            {
                Debug.LogError("System.ArgumentException:\n" + e.Message);
            }
        }
        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");
        }
    }
}

回答1:


Be sure to attach Visual Studio to unity and set breakpoints right before you save your file, and check your references. I suspect it's coming up null, also be sure to enable WebCam + Photos support in your manifest, that might be causing a null as well.




回答2:


I find that your code to capture and save photos should be correct and I ran into the same error as you.

To avoid the error, I was able to save photos by changing the directory to Application.persistentDataPath, i.e., modifying Start() to the following

// ...
void Start()
{
    folderPath = Application.persistentDataPath;
    PhotoCapture.CreateAsync(false, OnPhotoCaptureCreated);
}
// ...

The photo is then available at the path UserFiles\LocalAppData\<APPNAME>\LocalState\, which can be found through the Hololens Device Portal's File Explorer.



来源:https://stackoverflow.com/questions/38357706/hololens-capturing-photo-in-unity-and-saving-to-disk

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!