【问题标题】:Creating a JPG file with Node.JS使用 Node.JS 创建 JPG 文件
【发布时间】:2012-09-22 08:03:27
【问题描述】:

在我的 node.js 服务器中,我正在从另一台服务器下载文件。下载的文件是用Base64编码两次的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,数据开始

任何想法。 法鲁克·阿尔沙德。

【问题讨论】:

  • 澄清一下——为什么要编码两次?
  • 这只是服务器(从我下载文件的位置)上传文件的方式。

标签: node.js download base64 jpeg decoding


【解决方案1】:

我已经解决了我的问题。问题似乎出在 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);

希望对其他人有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-09-12
    • 1970-01-01
    • 2013-10-29
    • 1970-01-01
    • 1970-01-01
    • 2012-11-21
    • 1970-01-01
    相关资源
    最近更新 更多