将图像发送到节点服务器并调用 OCR 微软视觉 API



我正在尝试将图像(由手机摄像头捕获)从安卓设备发送到nodeJS服务器,然后从那里调用Microsoft OCR。我遵循的技术是,压缩图像,获取字节数组并使用HTTP POST方法发送到节点服务器,从节点服务器,只需从请求中获取字节数组并调用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();

从节点端看,这是代码:

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();

最新更新