2012-09-22 37 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); 

希望这将帮助别人。