Interfejs API twarzy z node.js przy użyciu Axios

Sep 19 2020

Do analizowania obrazów używam interfejsu API usługi poznawczej usługi Azure Face API. Sprawiłem, że działało wcześniej, używając linków URL do obrazów bez problemu, ale staram się, aby działało z lokalnymi obrazami. Znalazłem pytanie, którego właśnie szukam z a request.post, ale próbuję sprawić, by działało z axios. Mój kod:

"use strict";
const axios = require("axios").default;
const fs = require("fs");

let file = "localFile.jpg";

const imageBuffer = fs.readFileSync(file, { encoding: "base64" });

// Add a valid subscription key and endpoint to your environment variables.
var subscriptionKey = "<Subscription key>";
var urlApi=
    "https://.../face/v1.0/detect";


// Send a POST request
axios({
    method: "post",
    url: urlApi,
    params: {
        returnFaceId: true,
        returnFaceLandmarks: false,
        returnFaceAttributes:
            "age,gender,headPose,smile,facialHair,glasses,emotion,hair,makeup,occlusion,accessories,blur,exposure,noise",
    },
    headers: {
        "Content-Type": "application/octet-stream",
        "Ocp-Apim-Subscription-Key": subscriptionKey,
        "Content-Length": imageBuffer.length,
    },
    data: imageBuffer,
})
    .then((response) => {
        console.log("Status text: " + response.status);
        console.log("Status text: " + response.statusText);
        console.log();
        //console.log(response.data)
        response.data.forEach((face) => {
            console.log("Face ID: " + face.faceId);

            console.log("Smile: " + face.faceAttributes.smile);
            console.log(
                "Head pose: " + JSON.stringify(face.faceAttributes.headPose)
            );
            console.log("Gender: " + face.faceAttributes.gender);
            console.log("Age: " + face.faceAttributes.age);
            console.log(
                "Facial hair: " + JSON.stringify(face.faceAttributes.facialHair)
            );
            console.log("Glasses: " + face.faceAttributes.glasses);
            console.log("Smile: " + face.faceAttributes.smile);
            console.log(
                "Emotion: " + JSON.stringify(face.faceAttributes.emotion)
            );
            console.log("Blur: " + JSON.stringify(face.faceAttributes.blur));
            console.log(
                "Exposure: " + JSON.stringify(face.faceAttributes.exposure)
            );
            console.log("Noise: " + JSON.stringify(face.faceAttributes.noise));
            console.log(
                "Makeup: " + JSON.stringify(face.faceAttributes.makeup)
            );
            console.log(
                "Accessories: " +
                    JSON.stringify(face.faceAttributes.accessories)
            );
            console.log("Hair: " + JSON.stringify(face.faceAttributes.hair));
            console.log();
        });
    })
    .catch(function (error) {
        console.log(error);
    });

Spodziewałem się, że otrzymam podobny wynik w formacie json, ale zamiast tego otrzymuję status: 400, statusText: 'Bad Request'i nie jestem pewien, dlaczego. Każda pomoc w tej sprawie byłaby mile widziana.

Ja też próbowałem

const imageBuffer = fs.readFileSync(file);

i

const options = [
                "returnFaceId=true",
"returnFaceLandmarks=true",
"returnFaceAttributes=age,gender,headPose,smile,facialHair,glasses,emotion,hair,makeup,accessories",
                ];
        urlApi = urlApi.concat("?", options.join("&"));
        axios.post(urlApi,
                   { body: imageBuffer},
                   {     headers: {
    "Content-Type": "application/octet-stream",
    "Ocp-Apim-Subscription-Key": subscriptionKey,
    "Content-Length": imageBuffer.length,
},
                    )

Szczegółowa odpowiedź na błąd: (na żądanie Jima Xu)

response: {
status: 400,
statusText: 'Bad Request',
headers: {
  'transfer-encoding': 'chunked',
  'content-type': 'application/json; charset=utf-8',
  'x-envoy-upstream-service-time': '8',
  'apim-request-id': 'cb7f0380-a785-49f5-94fe-ff5ed0e36742',
  'strict-transport-security': 'max-age=31536000; includeSubDomains; preload',
  'x-content-type-options': 'nosniff',
  'csp-billing-usage': 'CognitiveServices.Face.Transaction=1',
  date: 'Sun, 20 Sep 2020 13:55:45 GMT',
  connection: 'close'
}

Odpowiedzi

2 JimXu Sep 21 2020 at 09:06

Jeśli chcesz działać Axiosw środowisku węzłów, powinniśmy użyć Stream, Bufferjako żądania danych treści. Więcej informacji można znaleźć tutaj .

Na przykład

axios
  .post(
    "<your face api endpoint>",
    fs.readFileSync("D:\\faces.jpg"),
    {
      headers: {
        "Ocp-Apim-Subscription-Key": subscriptionKey,
        "Content-Type": "application/octet-stream",
      },
      params: {
        returnFaceId: true,
        returnFaceLandmarks: false,
        returnFaceAttributes:
          "age,gender,headPose,smile,facialHair,glasses,emotion,hair,makeup,occlusion,accessories,blur,exposure,noise",
      },
    }
  )
  .then((response) => {
    console.log("Status text: " + response.status);
    console.log("Status text: " + response.statusText);
    console.log();
    //console.log(response.data)
    response.data.forEach((face) => {
      console.log("Face ID: " + face.faceId);
      console.log(
        "Face rectangle: " +
          face.faceRectangle.top +
          ", " +
          face.faceRectangle.left +
          ", " +
          face.faceRectangle.width +
          ", " +
          face.faceRectangle.height
      );
      console.log("Smile: " + face.faceAttributes.smile);
      console.log("Head pose: " + JSON.stringify(face.faceAttributes.headPose));
      console.log("Gender: " + face.faceAttributes.gender);
      console.log("Age: " + face.faceAttributes.age);
      console.log(
        "Facial hair: " + JSON.stringify(face.faceAttributes.facialHair)
      );
      console.log("Glasses: " + face.faceAttributes.glasses);
      console.log("Smile: " + face.faceAttributes.smile);
      console.log("Emotion: " + JSON.stringify(face.faceAttributes.emotion));
      console.log("Blur: " + JSON.stringify(face.faceAttributes.blur));
      console.log("Exposure: " + JSON.stringify(face.faceAttributes.exposure));
      console.log("Noise: " + JSON.stringify(face.faceAttributes.noise));
      console.log("Makeup: " + JSON.stringify(face.faceAttributes.makeup));
      console.log(
        "Accessories: " + JSON.stringify(face.faceAttributes.accessories)
      );
      console.log("Hair: " + JSON.stringify(face.faceAttributes.hair));
      console.log();
    });
  })
  .catch((err) => {
    throw err;
  });