问题
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");
});
回答1:
The Alchemy Vision API was deprecated in May this year, not sure that is related to the problem your having but migrating to the IBM Watson Visual Recognition service will likely be your best bet going forward.
See the service documentation and also the migration guide for details.
回答2:
I was able to do the post.
Inside the app.post function:
- Posting the image as a json content.
- Check the filesystem on the server
- using a callback function to connect to the alchemy service
Inside the callback function:
- set key of the alchemy service
- check the json content
- convert the image to a storeable format
- create a file to save a temp image
- write the temp image-file to a server directory
- close the file
- prepare the alchemy service parameter
- request tag information from alchemy
- delete temp file
- 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:
console result:
来源:https://stackoverflow.com/questions/38325741/how-to-post-a-image-correctly-to-alchemy-node-js-server