2013-02-16 40 views
3

我有一个图像编码为base64字符串,我试图POST它作为另一个REST API(http://ocrapiservice.com/documentation/)的参数。如何将base64编码在内存中的图像作为文件参数

我不想将文件存储在磁盘上 - 我想将文件保存在内存中,因为最终我想在客户端上使用getUserMedia创建映像,我可能会使用托管服务不允许直接文件IO。

我遇到的问题是,我可以使用fs.createReadStream(somePath);(例如, https://github.com/mikeal/request/blob/master/README.md#forms

我更喜欢使用库,如request库,但也许这是不可能的。

我现在所拥有的代码是:

var fs = require('fs'); 
var path = require('path'); 

var request = require('request'); 
var WS_URL = 'http://api.ocrapiservice.com/1.0/rest/ocr'; 

function ocr(postData) { 
    var r = request.post(WS_URL, completed); 
    var form = r.form(); 

    form.append('apikey', 'REMOVED'); 
    form.append('language', 'en'); 
    form.append('image', postData); 

    function completed(error, response, body) { 
     console.log(body); 
    } 
} 

// This works 
ocr(fs.createReadStream(path.join(__dirname, 'example.png'))); 

// This does not work 
// ignore that it's being read from a file (the next line) 
var base64Str = fs.readFileSync('example.png').toString('base64'); 

var buffer = new Buffer(base64Str, 'base64'); 
ocr(buffer.toString('binary')); 

form.append确实允许额外的参数,如此发送,如果额外的头需要进行设置,然后这是可能的。

是否有我可以使用的某种Stream包装?我试过使用这个StringReader的例子,它可以修改它至少发送一个文件名和正确的内容类型。

如何实现将内存文件作为参数传递给Web服务?

更新:

我已经固定/更新上面的代码。

我从上面列出的REST API得到的回应是:

HTTP/1.1 400

没有文件提供错误的请求

下面是我运行的实际代码: https://gist.github.com/leggetter/4968764

回答

0

在流版本中,您正在处理文件碎片,但是在您正在使用base64字符串的base64Image版本。由于流版本的工作原理,ocr API显然期望表单只包含二进制数据,因此您需要在发送Base64数据之前对其进行解码。

// Reading straight from a Buffer. 
var imageData = fs.readFileSync('example.png'); 
ocr(imageData); 

// Reading from a new Buffer created from a base64 string. 
var base64Image = '...'; 
ocr(new Buffer(base64Image, 'base64')); 

另外请注意,在你的示例代码:

// This line: 
var base64Image = new Buffer(imageData, 'binary').toString('base64'); 

// does the same thing as this, because 'imageData' is alreadya Buffer 
var base64Image = imageData.toString('base64'); 
+0

我已经更新了发送二进制数据的问题(据我所知),并提供了一个链接到我正在执行的代码中。 – leggetter 2013-02-17 10:21:38

+0

为什么添加'.toString('binary')'?这完全不同。 – loganfsmyth 2013-02-17 16:51:04

0

我相信你可以直接使用Buffer的要求,而无需将其包装成一个Stream

它不工作,因为您使用不正确的编码。如果编码不存在,readFileSync默认返回Buffer。缓冲区默认使用utf-8作为其编码。但是你之间使用的是二进制编码,这与你在缓冲区中的不一致。

var imageData = fs.readFileSync('example.png');//After you get imageData 
var base64Image = imageData.toString('base64'); //base64 encoded string 
var decodedImage = new Buffer(base64Image, 'base64'); //base64 encoded buffer 
ocr (imageData); //You can use the file directly 
ocr (base64Image); //Or you can use either the base-64 string or the base64-buffer 

在这里寻找更多的编码/解码细节 NodeJS base64 image encoding/decoding not quite working

0

您应该能够使用base64-image-upload NPM包我刮起了,因为我有同样的问题。

这样做正好是由user568109概述的方法,从base64字符串创建一个缓冲区并发布它。最重要的部分是它将编码,MIME类型和请求头部处理抽象化,这将大大简化您的代码。

相关问题