我正在尝试将图像(由手机摄像头捕获)从 Android 设备发送到 nodeJS 服务器,然后从那里调用 Microsoft OCR。 我遵循的技术是,图像被压缩,获取字节数组并使用 HTTP POST 方法发送到 Node 服务器,从 Node 服务器,仅从请求中获取字节数组并调用 API。
这是使用的过程: 1).获取位图图像
2).创建 HTTP 请求如下:
HttpURLConnection conn = (HttpURLConnection)connectURL.openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Cache-Control", "no-cache");
conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"title\""+ lineEnd);
dos.writeBytes(lineEnd);
ByteArrayOutputStream output = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 50, output);
byte[] bufAry = output.toByteArray();
dos.write( bufAry, 0, bufAry.length);
dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
dos.flush();
这里是 Node 端的代码:
router.post('/', rawBody, function(req, res, next)
{
console.log("post request");
if (req.rawBody && req.bodyLength > 0) {
sendRequestForOCR(req.rawBody, res );
} else {
res.send(500);
}
});
function rawBody(req, res, next) {
var chunks = [];
req.on('data', function(chunk) {
chunks.push(chunk);
});
req.on('end', function() {
var buffer = Buffer.concat(chunks);
req.bodyLength = buffer.length;
req.rawBody = buffer;
next();
});
req.on('error', function(err) {
console.log(err);
res.status(500);
});
}
function sendRequestForOCR( image, res ) {
var encodedImg = querystring.stringify({
data: image
});
var options = {
host: 'api.projectoxford.ai',
path: '/vision/v1.0/ocr',
port: '80',
method: 'POST',
headers: {
'Content-Type' : 'application/octet-stream',
'Ocp-Apim-Subscription-Key': 'my_key'
}
};
var httpreq = http.request(options, function (response) {
response.setEncoding('utf8');
response.on('data', function (chunk) {
console.log("body: " + chunk);
});
response.on('end', function() {
res.send('ok');
})
});
httpreq.write(encodedImg);
httpreq.end();
}
但是当执行时我得到的信息是:
"code":"InvalidImageFormat", "message":"Input data is not a valid image."
谁能告诉我代码中的问题是什么? 是图片压缩问题还是串流问题?
谢谢。
最佳答案
由于您实际上一次只能处理一张图像,因此您应该修改 Java 代码以简单地发送原始的 JPG 字节,而不使用多部分 MIME。在您编写代码时,nodejs 服务器接收的有效负载包含多部分 MIME 所需的附加修饰(边界、名称等)。所以:
HttpURLConnection conn = (HttpURLConnection)connectURL.openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Cache-Control", "no-cache");
conn.setRequestProperty("Content-Type", "application/octet-stream");
DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
ByteArrayOutputStream output = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 50, output);
byte[] bufAry = output.toByteArray();
dos.write(bufAry, 0, bufAry.length);
dos.flush();
一个选项是让此 Java 代码直接调用 Microsoft 认知服务 URL。但是,如果您需要中间 nodejs 服务器进行一些其他处理,您将希望在不修改的情况下传递二进制有效负载。换句话说,
function sendRequestForOCR( image, res ) {
var options = {
host: 'api.projectoxford.ai',
path: '/vision/v1.0/ocr'
method: 'POST',
headers: {
'Content-Type' : 'application/octet-stream',
'Ocp-Apim-Subscription-Key': 'my_key'
}
};
var httpreq = https.request(options, function (response) {
response.on('data', function (chunk) {
console.log("body: " + chunk);
});
response.on('end', function() {
res.send('ok');
})
});
httpreq.write(image);
httpreq.end();
关于android - 将图像发送到 Node 服务器并调用 OCR microsoft vision API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38346498/