Over the last 48 hours, I have been trying to troubleshoot a problem with my Cordova android app for Face recognition using Microsoft Cognitive Services. To capture images, I utilized the Cordova Camera plugin and implemented JS for face detection and identification. In this post, I will walk through the code step by step. Below are my Content Security Policies:
<meta http-equiv="Content-Security-Policy" content="media-src * blob:; script-src 'self' 'unsafe-inline' 'unsafe-eval' *; style-src 'self' 'unsafe-inline' *">
<meta name="format-detection" content="telephone=no">
<meta name="msapplication-tap-highlight" content="no">
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
Following the security policies, here is the standard HTML Code to display the button for capturing pictures:
<button id="take-picture-button">Take Picture</button>
Now, let's move on to the .js file which contains the logic for the Cordova Camera plugin events:
bindEvents: function () {
document.addEventListener('deviceready', this.onDeviceReady, false);
document.addEventListener('pause', this.onPause, false);
document.addEventListener('resume', this.onResume, false);
},
onDeviceReady: function () {
document.getElementById("take-picture-button").addEventListener("click", function () {
appState.takingPicture = true;
navigator.camera.getPicture(cameraSuccessCallback, cameraFailureCallback,
{
sourceType: Camera.PictureSourceType.CAMERA,
destinationType: Camera.DestinationType.FILE_URI,
targetWidth: 500,
targetHeight: 500
}); });
},
Additionally, there are functions for onPause() and onResume(). The following code snippet showcases the AJAX call made to the MS-Cognitive services Face API for face detection. Note that image conversion into binary data is necessary before sending it in the POST request.
var img = new Image();
img.src = imageUri;
var canvas = document.createElement("canvas");
canvas.width = $(window).width();
canvas.height = $(window).height();
var ctx = canvas.getContext("2d");
img.onload = function () {
ctx.drawImage(img, 0, 0);
}
var dataURL = canvas.toDataURL("image/jpeg");
var data = dataURL.split(',')[1];
var mimeType = dataURL.split(';')[0].slice(5)
var bytes = window.atob(data);
var buf = new ArrayBuffer(bytes.length);
var byteArr = new Uint8Array(buf);
for (var i = 0; i < bytes.length; i++) {
byteArr[i] = bytes.charCodeAt(i);
}
var params = {
"returnFaceId": "true",
"returnFaceLandmarks": "false",
"returnFaceAttributes": "age",
};
var faceIds = new Array();
$.ajax({
url: "https://australiaeast.api.cognitive.microsoft.com/face/v1.0/detect?" + $.param(params),
beforeSend: function (xhrObj) {
xhrObj.setRequestHeader("Content-Type", "application/octet-stream");
xhrObj.setRequestHeader("Ocp-Apim-Subscription-Key", "API_KEY");
},
type: "POST",
data: byteArr,
processData: false,
})
.done(function (data) {
for (var i = 0; i < data.length; i++) {
faceIds.push(data.faceId);
alert("FaceID at index"+ i+" is " + JSON.stringify(data.faceId[i]));
}
})
.fail(function (jqXHR, textStatus, errorThrown) {
alert("Failed in Face Detect, Details: Status:: " + jqXHR.status + " ResponseText:: " + jqXHR.statusText + "");
});
The output of the above code is showing "Failed in Face Detect, Details: Status::400 ResponseText:: Bad Request". I am currently stuck and unsure where changes are needed or if something is missing. Your assistance would be greatly appreciated. Thank You