如何 post 一张图片正确地传送到 alchemy node.js 服务器?

How to post a image correctly to alchemy node.js server?

我尝试在 node.js 服务器上实现一个 post 方法用于炼金术。 问题是如何处理移动应用程序提供的给定图像。

我将图像作为 json 的一部分。 json 提取图像并将其转换为二进制文件。 (希望是对的) 然后准备post方法,需要alchemy参数。 执行 post 并检查结果。

存在'cannot-analyze:downstream-issue'问题。

2016-07-12T00:57:29.185+0200
[App/0]
OUT
'x-alchemyapi-params': 'sentiment=0&knowledgeGraph=0&detectedLanguage=unknown&submitLanguage=detect',
2016-07-12T00:57:29.186+0200
[App/0]
OUT
"NOTICE": "THIS API FUNCTIONALITY IS DEPRECATED AND HAS BEEN MIGRATED TO WATSON VISUAL RECOGNITION. THIS API WILL BE DISABLED ON MAY 19, 2017.",
2016-07-12T00:57:29.186+0200
[App/0]
OUT
"usage": "By accessing AlchemyAPI or using information generated by AlchemyAPI, you are agreeing to be bound by the AlchemyAPI Terms of Use: http://www.alchemyapi.com/company/terms.html",
2016-07-12T00:57:29.185+0200
[App/0]
OUT
'access-control-allow-origin': '*' }
2016-07-12T00:57:29.186+0200
[App/0]
OUT
}
2016-07-12T00:57:29.185+0200
[App/0]
OUT
'x-alchemyapi-error-msg': 'cannot-analyze:downstream-issue',

这是服务器方法的源代码以及我找到的文档信息:

// Documentation: http://www.ibm.com/watson/developercloud/doc/visual-recognition/tutorials.shtml#classify
// curl -X POST -F "images_file=@prez.jpg" "https://gateway-a.watsonplatform.net/visual-recognition/api/v3/detect_faces?api_key={api-key}&version=2016-05-20"
// Other Documentation: https://www.npmjs.com/package/form-data
// 
// https://github.com/expressjs/body-parser#limit
// https://www.npmjs.com/package/multer#limits
app.post('/myInformation', function(req, res){
  var theImage = 'unassigned';
  var result = 'unassigned';

  if (req.method == 'POST') {
      console.log("[200] " + req.method + " to " + req.url);
      var fullBody = '';
      req.on('data', function(chunk) {
        // append the current chunk of data to the fullBody variable
        fullBody += chunk.toString();
      });
      console.log('---> fullBody : ',fullBody);
  }

  if(req.body.body.image) {
    theImage = req.body.body.image;
    console.log('---> Type : ', req.body.body.type);

    // Create Base64 Object
    var Base64={_keyStr:" XXXXXXXXX rn t}}

    var rawData = theImage;
    var data = rawData.split(",").pop();
    var decodedString = Base64.decode(data);

    var https = require('http'); // Changed to http
    var theHost = 'gateway-a.watsonplatform.net';
    var thePort = 80;
    var theMethode = 'POST';
    var api_key = 'XXXXXXXXXXXX';
    var thePath = '/calls/image/ImageGetRankedImageKeywords?apikey='+api_key+'&outputMode=json&imagePostMode=raw';

    var postheaders = {
      'Content-Type'  : 'application/x-www-form-urlencoded',
      'Content-Length': Buffer.byteLength(decodedString)
    };

    // the post options
    var optionspost = {
      host : theHost,
      port : thePort,
      path : thePath,
      method : theMethode,
      headers : postheaders
    };

    console.info('---> Options prepared:');
    console.info(optionspost);
    console.info('---> Do the POST call');

    // do the POST call using https or http
    var reqPost = https.request(optionspost, function(res) {
        console.log("---> statusCode: ", res.statusCode);
        // uncomment it for header details
        console.log("---> headers: ", res.headers);

        res.on('data', function(d) {
            console.info('---> POST result:\n');
            process.stdout.write(d);
            console.info('\n\n---> POST completed');
        });
    });

    // write the image Push Data
    reqPost.write(decodedString);
    reqPost.end();
    reqPost.on('error', function(e) {
      console.error(e);
    });

    console.log("---> Keywords for Images");
  };
  res.end("OK");
});

Alchemy Vision API 在今年 5 月被弃用,不确定这是否与您遇到的问题有关,但迁移到 IBM Watson Visual Recognition 服务可能是您未来的最佳选择。

有关详细信息,请参阅服务 documentation and also the migration guide

我能够做到 post。

app.post函数内部:

  1. 将图像发布为 json 内容。
  2. 检查服务器上的文件系统
  3. 使用回调函数连接到 Alchemy 服务

回调函数内部:

  1. 设置炼金服务的密钥
  2. 查看json内容
  3. 将图像转换为可存储格式
  4. 创建一个文件来保存临时图像
  5. 将临时图像文件写入服务器目录
  6. 关闭文件
  7. 准备炼金服务参数
  8. 向炼金术请求标签信息
  9. 删除临时文件
    1. 提供标签结果作为回调

app.post 函数:

app.post('/visualRecognition', function(req, res){
    var result = 'unassigned';
    var path   = '/app/public';
    // getTags(req, result, callback)
    // check filesystem
    if (fs.existsSync(path)) {
       console.log('---> starting point - path exists -> /app/public ');

       if (onFinished.isFinished(req)) {
              var input = req;
              getTags(input, result, function extractCallbackGetTags(req,result){
                 console.log('---> last step - extractCallbackGetTags --> RESULT: ', JSON.stringify(result));
                 //res.json(JSON.stringify(result));
                 res.end(JSON.stringify(result));
              });
       }
    }
}); // end post

回调函数:

function getTags(inputdata, result, callback){
  var theInputData = inputdata;
  var theImage = 'unassigned';
  var filepath = '/app/public/images/temp.jpg';
  var serverfilepath = '/images/temp.jpg';
  var serverURL = 'http://XXXXXXXXXXXX.mybluemix.net';
  var imageURL = serverURL + serverfilepath;

  // prepare service call
  console.log('---> step 1 - alchemy_vision');
  var alchemy_vision = watson.alchemy_vision({
    api_key: 'XXXXXXXXXXXX'
  });

  // check data
  if(theInputData.body.body.image) {
    theImage = theInputData.body.body.image;
    var theImageBuffer = decodeBase64Image(theImage);
    // Create file
    var fd = fs.openSync(filepath, 'w');

    // Write file
    fs.writeFile(filepath, theImageBuffer.data, function (err) {
      // Save file
      if(err) {
        console.log(err);
        result = {'err': err };
        callback(theInputData,result);
      } else {
            console.log('--> step 2 - File saved!');
            // Close file
            fs.close( fd, function(err) {
              if (err){
                console.log(err);
                callback(theInputData,result);
              }
              console.log('--> step 3 - File closed successfully.');

              // prepare service parameter
              var params = {
                url: imageURL
              };

              // call service
              alchemy_vision.getImageKeywords(params, function (err, keywords){
               if (err) {
                 console.log('--->  alchemy_vision error:', err);
                 result = {'error': err };
                 callback(theInputData,result);
               } else {
                 result = JSON.stringify(keywords, null, 2);
                 console.log('---> step 4 - alchemy_vision keywords JSON: ', JSON.stringify(keywords, null, 2));
                 // delete file
                 fs.unlink(filepath,function(err) {
                   if(err){
                     console.log('---> Error : ', err);
                     result = {'error': err };
                     callback(theInputData,result);
                   } else {
                    console.log('---> step 5 - File deleted successfully and JSON Result is: ', result);
                    callback(theInputData,result);
                   }}); // end delete file
                }; // end else  alchemy_vision
              }); //  end alchemy_vision
            }); // end file close
       }}); // end else and filewrite
    } else { //end if
       result = {'error': "No Image"};
       //res.end(JSON.stringify(result));
       callback(theInputData,result);
  }
}

poster 结果:

控制台结果: