android - 将图像发送到 Node 服务器并调用 OCR microsoft vision API

标签 android node.js ocr image-uploading azure-cognitive-services

我正在尝试将图像(由手机摄像头捕获)从 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/

相关文章:

由于默认禁用受支持的网址,Android 深层链接无法正常工作

Android EditText的光标坐标(绝对位置)

node.js - 不使用 npm 卸载 npm - 可能吗?

javascript - 在 Meter 中的每个循环中使用内部变量

java - Android:使用 HttpURLConnection 中的进度回调在 Cloudinary 中上传照片

android - 如何在android studio中更改应用程序的版本

node.js - 类型为 "string"的预期参数, "stdClass"给定错误

android - 精明边缘检测器后的opencv洪水填充

java - 使用 OCR 检测扫描文档是否创建 PDF [pdfbox]

machine-learning - 卷积神经网络在二值图像上运行得更快吗