Reputation: 1321
I am trying to upload an image to the Microsoft Computer Vision API from a mobile device, but I am constantly receiving a 400 Bad Request for Invalid File Format "Input data is not a valid image". The documentation states that I can send the data as application/octet-stream in the following form:
[Binary image data]
I have the data of the image in terms of base64 encoding ("/9j/4AAQSkZJ.........."), and I also have the image as a FILE_URI, but I can't seem to figure out the format in which to send the data. Here is a sample code:
$(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");
});
});
I've tried the following:
and more.
I did tested these on the Computer Vision API console. Is it because base64 encoded binary isn't an acceptable format? Or am I sending it in the incorrect format completely?
Note: The operation works when sending a URL as application/json.
Upvotes: 2
Views: 4573
Reputation: 21
Just wanted to add this in case it helps anyone else. The answer referenced by cthrash above works fine, but it lead me to a simpler way that doesn't convert the image to base64 and then back to binary.
Just read the image as an ArrayBuffer and use that to construct a new Blob for the body of the post. Also, don't forget to set processData to false. The full solution looks like this:
//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);
}
}
Upvotes: 1
Reputation: 2973
Please take a look at Emotion API Project Oxford base64 image, or go directly to the code snippet here: How to post an image in base64 encoding via .ajax? .
Since this is a recurring topic, I've made a feature request to make the APIs handle data URIs directly, on UserVoice.
Upvotes: 3