2013-02-16 74 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類型和請求頭部處理抽象化,這將大大簡化您的代碼。

相關問題