2012-09-22 92 views
1

在我的node.js服務器中,我從另一臺服務器上下載文件。下載的文件是兩次使用Base64編碼的JPG圖像數據,這意味着我必須解碼它兩次。鑑於是我的代碼。使用Node.JS創建JPG文件

var base64DecodedFileData = new Buffer(file_data, 'base64').toString('binary'); 
var tmp = base64DecodedFileData.split("base64,"); 
var base64DecodedFileData = new Buffer(tmp[1], 'base64').toString('binary');                           
var file = fs.createWriteStream(file_path, stream_options); 
file.write(base64DecodedFileData); 
file.end(); 

我知道我的圖像數據是有效的,我第一次已經破譯它(我已經驗證,通過第二次解碼它在網上的base64解碼器的數據,我已經得到了正確的圖像),但是當我將其解碼第二次,並用這些數據創建一個文件。我沒有得到一個有效的JPG文件。

我已經將它與實際圖像進行了比較,這兩個文件的開始和結束似乎都很好,但是在我構建的文件中有些不正確。構建的文件的大小也比原來的大。

PS:我做了拆分,因爲第一解碼後的數據與

數據開始解碼第二次之前:; base64,DATASTARTS

任何想法。 Farrukh Arshad。

+0

只是爲了澄清 - 爲什麼它被編碼了兩次? – DeadAlready

+0

這只是服務器(我從哪裏下載文件)上傳文件的方式。 –

回答

0

我已經解決了我的問題。這個問題似乎是從node.js解碼出來的,所以我編寫了一個C++插件來完成這項工作。這是代碼。我非常肯定,如果我們只有一次圖像文件編碼,問題將會保持。

js文件

ModUtils.generateImageFromData(file_data,FILE_PATH);

C++插件:它使用的base64 C++編碼器/解碼器從 http://www.adp-gmbh.ch/cpp/common/base64.html

#define BUILDING_NODE_EXTENSION 
#include <node.h> 
#include <iostream> 
#include <fstream> 
#include "base64.h" 

using namespace std; 
using namespace v8; 

static const std::string decoding_prefix = 
"data:;base64,"; 

// -------------------------------------------------------- 
// Decode the image data and save it as image 
// -------------------------------------------------------- 
Handle<Value> GenerateImageFromData(const Arguments& args) { 
HandleScope scope; 

// FIXME: Improve argument checking here. 
// FIXME: Add error handling here. 

if (args.Length() < 2) return v8::Undefined(); 

Handle<Value> fileDataArg = args[0]; 
Handle<Value> filePathArg = args[1]; 
String::Utf8Value encodedData(fileDataArg); 
String::Utf8Value filePath(filePathArg); 
std::string std_FilePath = std::string(*filePath); 

// We have received image data which is encoded with Base64 two times 
// so we have to decode it twice. 
std::string decoderParam = std::string(*encodedData); 
std::string decodedString = base64_decode(decoderParam); 

// After first decoding the data will also contains a encoding prefix like 
    // data:;base64, 
// We have to remove this prefix to get actual encoded image data. 
std::string second_pass = decodedString.substr(decoding_prefix.length(),  (decodedString.length() - decoding_prefix.length())); 
std::string imageData = base64_decode(second_pass); 

// Write image to file 
ofstream image; 
image.open(std_FilePath.c_str()); 
image << imageData; 
image.close(); 

return scope.Close(String::New(" ")); 
//return scope.Close(decoded); 
} 

void Init(Handle<Object> target) { 

// Register all functions here 
target->Set(String::NewSymbol("generateImageFromData"), 
    FunctionTemplate::New(GenerateImageFromData)->GetFunction()); 
} 

NODE_MODULE(modutils, Init); 

希望這將幫助別人。