Hello everyone.

The Mixed Reality Forums here are no longer being used or maintained.

There are a few other places we would like to direct you to for support, both from Microsoft and from the community.

The first way we want to connect with you is our mixed reality developer program, which you can sign up for at https://aka.ms/IWantMR.

For technical questions, please use Stack Overflow, and tag your questions using either hololens or windows-mixed-reality.

If you want to join in discussions, please do so in the HoloDevelopers Slack, which you can join by going to https://aka.ms/holodevelopers, or in our Microsoft Tech Communities forums at https://techcommunity.microsoft.com/t5/mixed-reality/ct-p/MicrosoftMixedReality.

And always feel free to hit us up on Twitter @MxdRealityDev.
Options

Access to Application.persistentDataPath within hololens app?

Hello!!

In my application, I would like to be able to take a picture, and then access the picture within the same code. I have the picture being taken successfully, and I can look at it through the Hololens web portal. But when I try to access the picture using the file path and file name the picture was JUST saved to, I get the following error:

"Exception thrown: 'System.IO.FileNotFoundException' in System.IO.FileSystem.dll
FileNotFoundException: Could not find file 'C:\Data\Users\"

et cetera. What could be the issue here? I'm storing the initial file path and file name in a variable, and then using that same variable to try and access the picture a few lines down. Is this an issue with accessing Application.persistentDataPath? That's where I'm currently storing the picture once it is taken.

Thank you so much for any help or ideas!

Best Answer

Answers

  • Options
    ahillierahillier mod
    edited August 2016

    Hi @ckesterson,
    You might try saving your pictures to one of the 'Known Folders':
    https://developer.microsoft.com/en-us/windows/holographic/App_model.html#app_file_storage

    I would suggest saving pictures to the 'PicturesLibrary' and then edit your appxmanifest capabilities to include access to that folder.

  • Options
    edited August 2016

    q

  • Options

    Would you mind posting your script? I can take a look.

    ===
    This post provided as-is with no warranties and confers no rights. Using information provided is done at own risk.

    (Daddy, what does 'now formatting drive C:' mean?)

  • Options
    edited August 2016

    @Patrick Sure, this was the function I'm having trouble with... A lot of it is actually from the code that you had posted on the other forum you just answered my question on. I was hoping to avoid using your workaround way of storing a picture to persistentDataPath and THEN moving it somewhere else, so I was thinking maybe I could hard code the path to the Pictures folder on the hololens? Or just somewhere that I can then send it to an API after, so it needs to be somewhere that is accessible. Do you think CameraRoll would be better for this, and if so, how can I get the file path to it?

    private void OnPhotoModeStarted(PhotoCapture.PhotoCaptureResult result)
    {
    string filePath = null;
    if (result.success)
    {
    // capturing a frame to memory---
    string filename = string.Format(@CapturedImage{0}_n.jpg, Time.time);
    filePath = System.IO.Path.Combine(Application.persistentDataPath, filename);

                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!");
            }
    
            // ADDING IN API CODE CALL
            if (!(filePath == null)) {
                Debug.Log ("Starting Coroutine UploadJPG");
                string uploadURL = "https://theAPI.com";
                StartCoroutine (UploadJPG (filePath, uploadURL));
            } else
                Debug.Log ("API cannot be run, no file path set.");
        }
    
  • Options

    Where does UploadJPG come from? I'm assuming that's where the file not found is hitting occuring.

    ===
    This post provided as-is with no warranties and confers no rights. Using information provided is done at own risk.

    (Daddy, what does 'now formatting drive C:' mean?)

  • Options
    edited August 2016

    Here is my UploadJPG function, it's below the OnPhotoModeStarted function in the same class. I definitely think that's where it's occurring as well, I'm guessing it's unable to find the file path when it tries to convert the JPG file there into bytes.

    IEnumerator UploadJPG (string localFilePath, string uploadURL) {

            // Read bytes from JPG file
            string bytes = System.Convert.ToBase64String (System.IO.File.ReadAllBytes(localFilePath));
    
            // Create form containing Base64String representation of JPG
            WWWForm form = new WWWForm ();
            form.AddField ("image_bytes", bytes);
    
            // Upload form to web
            WWW upload = new WWW(uploadURL,form);        
            yield return upload;
            if (upload.error == null)
                Debug.Log("upload done :" + upload.text);
            else
                Debug.Log("Error during upload: " + upload.error);
    
        }
    
  • Options

    Is the failure happing on this line?

     // Read bytes from JPG file
            string bytes = System.Convert.ToBase64String (System.IO.File.ReadAllBytes(localFilePath));
    

    Give me a few and I'll see if I can get you past this line. :)

    and to answer your other question...

    you can't just save to the pictures folder from an API that runs inside of the Unityplayer.dll because the UnityPlayer.dll doesn't have the same 'capabilities' as your actual application. It's also likely that a unity api also cannot read from the pictures folder for the same reason.

    ===
    This post provided as-is with no warranties and confers no rights. Using information provided is done at own risk.

    (Daddy, what does 'now formatting drive C:' mean?)

  • Options
    edited August 2016

    @Patrick well so I don't want to save to the pictures folder FROM the API, I am able to take pictures from within my app currently. What I haven't been able to do yet is then take that picture, convert it to a base64 string of bytes, and then send THAT to an API. It's currently saving the photo correctly, and I can see the photo from the Web Portal, but it seems like my application is unable to get back to where the photo was stored.

  • Options

    Do you care if the picture ever is stored on the device?

    ===
    This post provided as-is with no warranties and confers no rights. Using information provided is done at own risk.

    (Daddy, what does 'now formatting drive C:' mean?)

  • Options

    @Patrick I think that it's preferable that it be stored, but if it'd be easier to not have it stored (or if it isn't possible to do what I'm trying to do), then I would certainly welcome not storing it as a temporary fix. I guess the only parts that _definitely _ need to happen are that the picture get taken, that the picture is stored as a base64 string of bytes, and that the string of bytes is then sent to the API. So if not storing the picture is an easy workaround, then I'm all ears :blush:

  • Options

    It's way easier if you don't want to store the picture. It looks something like:

    photoCaptureObject.TakePhotoAsync((memoryResult, memoryData) =>
                {
                    if (memoryResult.resultType == PhotoCapture.CaptureResultType.Success)
                    {
                        List<byte> buffer = new List<byte>();
                        memoryData.CopyRawImageDataIntoBuffer(buffer);
                        string bytes = System.Convert.ToBase64String(buffer.ToArray());
    
    // and now you have your bytes as a string, you can upload them or whatever.
    
                    }
                });
    

    ===
    This post provided as-is with no warranties and confers no rights. Using information provided is done at own risk.

    (Daddy, what does 'now formatting drive C:' mean?)

  • Options
    PatrickPatrick mod
    edited August 2016

    OHHHHHHH!!!!!!!!

    I see a major problem with the code you posted. :)

    This block:

            if (!(filePath == null)) {
                Debug.Log ("Starting Coroutine UploadJPG");
                string uploadURL = "https://theAPI.com";
                StartCoroutine (UploadJPG (filePath, uploadURL));
            } else
                Debug.Log ("API cannot be run, no file path set.");
    

    should really be in the OnPhotoCapturedToDisk function.

    ===
    This post provided as-is with no warranties and confers no rights. Using information provided is done at own risk.

    (Daddy, what does 'now formatting drive C:' mean?)

  • Options
    edited August 2016

    @Patrick I'll try that now and get back to you, thank you!!!

    --------------------edit-----------------------------

    would you recommend simply moving that block of code down instead? Also what is the reasoning behind moving that block of code?

  • Options
    edited August 2016

    @Patrick ahhhh okay that makes a lot of sense!! Wow that's frustrating, thank you so much for your help! So persistentDataPath should be okay for what I need to do then? I shouldn't need to change that?

  • Options

    I think so.

    ===
    This post provided as-is with no warranties and confers no rights. Using information provided is done at own risk.

    (Daddy, what does 'now formatting drive C:' mean?)

  • Options

    It worked!!!!!!!!!!!! Thanks so much, you rock!!

Sign In or Register to comment.