将图像发送到节点服务器并调用 OCR microsoft vision API

Sending an image to node server and calling OCR microsoft vision API

我正在尝试将图像(由 phone 相机拍摄)从 android 设备发送到 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();