接受请求后,将图像添加到 Reality Capture API 结果文件大小为 0

问题描述

我目前正在使用 Reality Capture API。我正在 Mac 上进行开发并使用 Unity3D 作为我的主要开发工具。将图像添加到我的 PhotoScene 时,我看到每个文件大小导致大小为 0。我还看到通过返回响应每个请求只处理一个图像

在下面的文档中

https://forge.autodesk.com/en/docs/reality-capture/v1/tutorials/create-3d-mesh-from-photos/

在第 3 步中,将图像添加到 API,您可以通过路径上传。目前,我的路径如下所示,总图像最多可增加 350 张。正如 API 所述,每个请求最多只能有 20 张图像。

/Users/kreutsx1/Documents/ImagesMe/0001.jpg

我用来创建请求和查看图像的代码如下,现在我只提交前 20 张图像的请求,以验证它们是否被正确添加到场景中。

[ContextMenu("AddImages")]
    public async void AddImages()
    {
        PhotoSceneAddImage photosceneAddImage = new PhotoSceneAddImage();
        var url = "https://developer.api.autodesk.com/photo-to-3d/v1/file";

        WWWForm form = new WWWForm();
        photosceneAddImage.SceneID = sceneID;
        form.AddField("photosceneid",photosceneAddImage.SceneID);
        form.AddField("type",photosceneAddImage.Type);
        photosceneAddImage.FilePath = filePath;

        photosceneAddImage.Files = new String[photosceneAddImage.totalFiles];
        photosceneAddImage.Files = Directory.GetFiles(photosceneAddImage.FilePath);

        photosceneAddImage.totalFiles = photosceneAddImage.Files.Length;

        Debug.Log(photosceneAddImage.totalFiles);

        for (int i = 0; i < 20; i++) //20 is the total amount of images we can upload in a single request
        {
            form.AddField(String.Format("file[{0}]",photosceneAddImage.fileCount),photosceneAddImage.Files[i]);

            photosceneAddImage.fileCount++;
            Debug.Log(photosceneAddImage.fileCount);
        }


        using var www = UnityWebRequest.Post(url,form);

        Debug.Log(form.ToString());

        www.SetRequestHeader("Authorization","Bearer " + token);
        www.SetRequestHeader("Content-Type","multipart/form-data");

        var operation = www.SendWebRequest();

        while (!operation.isDone)
            await Task.Yield();

        if (www.result == UnityWebRequest.Result.Success)
        {

            Debug.Log($"Success: {www.downloadHandler.text}");
            var deserializedPostData = JsonUtility.FromJson<PostResult>(www.downloadHandler.text);
            Debug.Log(deserializedPostData.success);
            string response = System.Text.Encoding.UTF8.GetString(www.downloadHandler.data);
        }
        else
        {
            Debug.Log($"Failed: {www.error}");
        }


    }

我向 API 提交我的 Post 请求并得到以下返回响应

{"Usage":"1.0667450428009","Resource":"\/file","photosceneid":"jz4IuwgoPy6nT1isatnezWwnuZBiMYG3DqOSkulAOQQ","Files":{"file":{"filename":"1.jpg","fileid":"AxyOFMJOBN1wyUgKQoXQrIoUrhLPbU3apE8W6Ih5m2M=-001","filesize":"0","msg":"No error","url":"https:\/\/adsk-rc-photofly-prod.s3.amazonaws.com\/IMAGES\/AxyO\/FMJO\/BN1w\/yUgK\/QoXQ\/rIoU\/rhLP\/bU3a\/pE8W\/6Ih5\/m2M%3D-001?x-amz-server-side-encryption=AES256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Security-Token=IQoJb3JpZ2luX2VjEPz%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEacxvzLWVhc3QtMSJHMEUCIQC2iNoL1MNS2cN4EJwprPdr4kC4zE16dTE8t5Htv%2Fr8fQIgVo8NqtHMl3Erhph1vvniO9YQYvoBFzV5eUf2mpDxzJ4qvQMIlf%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FaraAGgw0MzY5MDc0MzgyMzYiDGY88UZM%2BhV%2F%2BzhfbyqRA8gY%2FK7MwV5SKcMM9lpo4Y2Tdzejnw0%2BdBswlX%2BkNDM9SaBlnjh2JE%2FoTv0%2BZyAGGhMQ0JzlyunJufMB5xA3Ty8YDt9Kl4BmcCtbX0U4iBkLG4ccbFX1EfHj3YostA371hQuheiGm15RVv1bkrEgHINM%2FjmARrMsHYsnXW%2F4GzXOihtLXDOu5hyqkjnbBZ32ZlSDUJvpk2EUVC%2BcF6%2BzMRa4dcNhMr%2FiUL3BVKX9rmJhk9SFirw0NYVgBUqhhMvQT0%2B0iPJw61fb557fPGvX9cFu9GH4Mu7qcytwCzFe%2BqEsbdgDjaMaYEqmNFoZXPw3zM2G7Jv3974og9tT7BXbNbp5cPTtiB2NJ4kfO4nEfRiuqXrOFliFRk2y0mn9H3DzTiVuVZ52jlAPYbyZsu%2FgGEd7Cel%2FqGCvq5kEVeK%2F6evoHV9YvFzmS3sQwBEWRMjZKdGp5TH5MM1%2BjlGDBcL2dLKVJYE6NfLjyGLIbuosMO7paWZhGEh%2Fr0sD3KR9BXRIwKzOflCAgTRnsT42Hj9W8n0iMMv3moUGOusBX1cXrOSXyTrkGs0UVo7aFaugYgUosCGkJHhcCaZoq94YgU1ZeViqr%2FqgTXbX9F937FbJ9rZNwz7PoX7a5iMOrOYcGTlHk5LBCA5H4%2fpmlUGqKNBLnNVpTYA3Xb%2Bv%2F3ItycqdKqagqINA4sVlqqZ%2BK4wcaXVZhMVO7wZ2bDFH6rE0eg0LyCL%2BFz7qVqDZoxtQzg1ilLKt4XmyX4qVTsycgX882V7f4dWa2wIm10xTqSKZ1OaeF31gl2CFH8QeNWKxm2MztmzKQDPRCHfzBBkKptYqToIzj5I4z7AycIAuNN80nb6LK1OwXHepuQ%3D%3D&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ASIAWLONWOCOAUKYLIWW%2F20210520%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20210520T194701Z&X-Amz-SignedHeaders=host%3Bx-amz-server-side-encryption&X-Amz-Expires=7200&X-Amz-Signature=e06ce57a531f31a68f0121345c59c0dd9c9571c5dffffb7204fcb21d09a52b0e"}}}

据我所知,我有两个问题,

  1. 生成文件大小 "filesize":"0"
  2. 即使使用以下内容将分配的最大 20 张图像添加到我的表单中,我也只看到一个图像被添加到场景中。
        for (int i = 0; i < 20; i++) //20 is the total amount of images we can upload in a single request
        {
            form.AddField(String.Format("file[{0}]",photosceneAddImage.Files[i]);

            photosceneAddImage.fileCount++;
            Debug.Log(photosceneAddImage.fileCount);
        }

更新

我一直在浏览代码并更新到以下内容

[ContextMenu("AddImages")]
    public async void AddImages()
    {
        PhotoSceneAddImage photosceneAddImage = new PhotoSceneAddImage();
        var url = "https://developer.api.autodesk.com/photo-to-3d/v1/file";

        WWWForm form = new WWWForm();
        photosceneAddImage.SceneID = sceneID;
        form.AddField("photosceneid",sceneID);
        form.AddField("type",photosceneAddImage.Type);
        photosceneAddImage.FilePath = filePath;

        photosceneAddImage.Files = new String[photosceneAddImage.totalFiles];
        photosceneAddImage.Files = Directory.GetFiles(photosceneAddImage.FilePath);

        
        photosceneAddImage.totalFiles = photosceneAddImage.Files.Length;
        for (int i = 0; i < 20; i++) //20 is the total amount of images we can upload in a single request
        {
            byte[] img = File.ReadAllBytes("/Users/kreutsx1/Documents/ImagesMe/" + String.Format("{0}.jpg",photosceneAddImage.fileCount + 1));
            form.AddBinaryData(String.Format("file[{0}]",photosceneAddImage.fileCount+1),img);
            photosceneAddImage.fileCount++;
            Debug.Log(photosceneAddImage.fileCount);
        }

        
        Debug.Log(photosceneAddImage.totalFiles);
        using var www = UnityWebRequest.Post(url,form);
        Debug.Log(www.responseCode);
        www.SetRequestHeader("Authorization","multipart/form-data");

        Debug.Log(form.data);

        Debug.Log(www.GetRequestHeader("photosceneid") + "PhotoId");
 
        var operation = www.SendWebRequest();
        if(www.uploadProgress <1)
        {
            Debug.Log(www.uploadProgress);
        }
        while (!operation.isDone)
        {
            if (www.uploadProgress < 1f)
            {
                Debug.Log(www.uploadProgress);
            }
            else
            {
                Debug.Log("finished");
            }
            await Task.Yield();
        }

        if (www.result == UnityWebRequest.Result.Success)
        {

            Debug.Log($"Success: {www.downloadHandler.text}");
            var deserializedPostData = JsonUtility.FromJson<PostResult>(www.downloadHandler.text);
            Debug.Log(deserializedPostData.success);

            string response = System.Text.Encoding.UTF8.GetString(www.downloadHandler.data);
        }
        else
        {
            Debug.Log($"Failed: {www.error}");
        }


    }

我仍然无法实现上传,因为当前代码从请求返回以下响应

"Usage":"2.1459798812866","Error":{"code":"19","msg":"Specified Photoscene ID doesn't exist in the database"}}
UnityEngine.Debug:Log (object)

我在调试过程中注意到,在删除以下代码片段后,我不再收到 error code 19 。但是当尝试添加带有字节数据的单个图像时,我会返回没有 Photoscene ID 的问题。

        for (int i = 0; i < 20; i++) //20 is the total amount of images we can upload in a single request
        {
            byte[] img = File.ReadAllBytes("/Users/kreutsx1/Documents/ImagesMe/" + String.Format("{0}.jpg",img);
            photosceneAddImage.fileCount++;
            Debug.Log(photosceneAddImage.fileCount);
        }

解决方法

问题似乎出在代码级别。如果文件显示在 photoscene 中,但文件大小为零,则表示文件已分配,但“上传协议”错误。根据我的粗浅经验,这通常是由于错误的内容类型或文件上传。

我在 Unity 和 C# 中都不是很“精通技术”,但我的建议是尝试将其上传为“multipart/form-data”,而不是“application/x-www-form-urlencoded” ”。

只需在 Unity 之外的 vanilla C# env 中尝试类似的操作:

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

我建议,在开始编写代码之前,先检查 Postman 之类的 Reality Capture 工作流程,以适应 API 和最终问题。 看看这篇博文:https://forge.autodesk.com/blog/hitchhikers-guide-reality-capture-api

您不仅可以找到可供使用的 Postman Collection,还可以找到未记录的调用,例如调查 photoscene 内容以查看上传文件的数量及其大小。