2

我正在尝试从移动设备将图像上传到 Microsoft 计算机视觉 API,但我不断收到 400 Bad Request for Invalid File Format “输入数据不是有效图像”。该文档指出,我可以将数据作为 application/octet-stream 以下列形式发送:

[二进制图像数据]

我有基于base64编码的图像数据(“/9j/4AAQSkZJ..........”),我也有图像作为 FILE_URI,但我似乎无法弄清楚发送数据的格式。这是一个示例代码:

$(function() {
    $.ajax({
        url: "https://api.projectoxford.ai/vision/v1.0/describe",
        beforeSend: function (xhrObj) {
            // Request headers
            xhrObj.setRequestHeader("Content-Type", "application/octet-stream");
            xhrObj.setRequestHeader("Ocp-Apim-Subscription-Key", computerVisionKey);
        },
        type: "POST",
        // Request body
        data: base64image,
        processData: false        
    })
    .done(function(data) {
      alert("success");
    })
    .fail(function(error) {
      alert("fail");
    });
});

我尝试了以下方法:

  • [base64image]
  • {base64image}
  • "数据:图像/jpeg;base64," + base64image
  • "图像/jpeg;base64," + base64image

和更多。

我确实在计算机视觉 API 控制台上测试了这些。是因为 base64 编码的二进制文件不是可接受的格式吗?还是我完全以不正确的格式发送它?

注意:该操作在以 application/json 形式发送 URL 时有效。

4

2 回答 2

3

请查看Emotion API Project Oxford base64 image,或直接转到此处的代码片段:如何通过 .ajax 以 base64 编码发布图像?.

由于这是一个反复出现的主题,因此我提出了一个功能请求,以使 API 在UserVoice上直接处理数据 URI 。

于 2016-06-18T22:28:19.587 回答
1

只是想添加这个以防它对其他人有帮助。上面 cthrash 引用的答案工作正常,但它引导我采用一种更简单的方法,不会将图像转换为 base64,然后再转换回二进制。

只需将图像读取为 ArrayBuffer 并使用它为帖子的正文构造一个新的 Blob。另外,不要忘记将 processData 设置为 false。完整的解决方案如下所示:

//onChange event handler for file input
function fileInputOnChange(evt) {
    var imageFile = evt.target.files[0];     
    var reader = new FileReader();
    var fileType;

    //wire up the listener for the async 'loadend' event
    reader.addEventListener('loadend', function () {

        //get the result of the async readAsArrayBuffer call
        var fileContentArrayBuffer = reader.result;

            //now that we've read the file, make the ajax call
            $.ajax({
                url: "https://westcentralus.api.cognitive.microsoft.com/face/v1.0/detect",
                beforeSend: function (xhrObj) {
                    // Request headers
                    xhrObj.setRequestHeader("Content-Type", "application/octet-stream");
                    xhrObj.setRequestHeader("Ocp-Apim-Subscription-Key", "<your subscription key goes here>");
                },
                type: "POST",

                //don't forget this!
                processData: false,

                //NOTE: the fileContentArrayBuffer is the single element 
                //IN AN ARRAY passed to the constructor!
                data: new Blob([fileContentArrayBuffer], { type: fileType })
            })
            .done(function (data) {
                console.log(data)
            })
            .fail(function (err) {
                console.log(err)
            });

    });
    if (imageFile) {
        //save the mime type of the file
        fileType = imageFile.type;

        //read the file asynchronously
        reader.readAsArrayBuffer(imageFile);
    }    
}
于 2017-04-26T12:12:22.550 回答