Thomas Suedbroecker Thomas Suedbroecker - 3 months ago 9
JSON Question

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

I try to implement a post method on the node.js server for alchemy.
The problem is how to handle the give image provided be a mobile app.

I get the Image as a part of a json.
The json extract the image and convert it to a binary. (hopefully right)
Then prepare the post method, with the need alchemy parameter.
Doing the post and examine the result.

There is a 'cannot-analyze:downstream-issue' problem.

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',


Here is the source code to the server method with the documentation information I found:

// 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
// http://stackoverflow.com/questions/6926016/nodejs-saving-a-base64-encoded-image-to-disk
// 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");
});

Answer

I was able to do the post.

Inside the app.post function:

  1. Posting the image as a json content.
  2. Check the filesystem on the server
  3. using a callback function to connect to the alchemy service

Inside the callback function:

  1. set key of the alchemy service
  2. check the json content
  3. convert the image to a storeable format
  4. create a file to save a temp image
  5. write the temp image-file to a server directory
  6. close the file
  7. prepare the alchemy service parameter
  8. request tag information from alchemy
  9. delete temp file
    1. provide the tag result as callback

app.post function:

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

callback function:

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 result:

enter image description here

consol result:

enter image description here

Comments