NodeJS base64图像编码/解码不太合适

我一直在试图把保存的图像发送到nodeJS(和expression框架)到数据库,并一直有一些麻烦。 忽略所有的Web处理,我认为我已经将问题缩小到了base64编码在节点中发生的方式。 我相信下面简单的示例应该可以工作,但输出图像总是被损坏。

示例(1)加载到图像(2)中保存if( image_orig )的副本,以确认节点能够正确读取文件。 这总是有效的。 (3)我把图像和base64编码的内容,(4)然后解码它。 最终的输出图像( image_decoded )总是被破坏。

帮帮我! (OSX Lion上的node.js 0.6.0)

 console.log("starting"); process.chdir(__dirname); var fs = require("fs"); var image_origial = "image.jpg"; fs.readFile(image_origial, function(err, original_data){ fs.writeFile('image_orig.jpg', original_data, function(err) {}); var base64Image = new Buffer(original_data, 'binary').toString('base64'); var decodedImage = new Buffer(base64Image, 'base64').toString('binary'); fs.writeFile('image_decoded.jpg', decodedImage, function(err) {}); }); 

我认为你误解了编码参数的用法。 如果你要指定编码“二进制”,那么你需要一致地做。 但是,你真的不需要它。 你似乎混淆了使用缓冲区与二进制string。

 // This tells node to load the file into a Buffer 'original_data' because you // have not specified an encoding for the returned values. If you provided an // encoding, then original_data would be a string with that encoding. fs.readFile(image_origial, function(err, original_data){ // This tells node to take that buffer, and write it to the new filename. // Again no encoding is provided, so it will assume a Buffer or utf8 string. fs.writeFile('image_orig.jpg', original_data, function(err) {}); // This tells node to create a new buffer from the old buffer, which means // it will iterate over original_data copying the bytes one at a time. But // they will be identical buffers. It will ignore the 'binary' argument // since the object you are passing isn't a string. // Then it encodes the content of that Buffer to base64, which is fine. var base64Image = new Buffer(original_data, 'binary').toString('base64'); // Here you decode the base64 to a buffer, which is fine, but then you // convert the buffer into a string with encoding 'binary'. This means that // it is a string object whose code points are bytes of the buffer. var decodedImage = new Buffer(base64Image, 'base64').toString('binary'); // Here you try to write that String object to a file. Since the argument you // have given is a string and you have not given an encoding argument for the // write command, then it will assume that 'utf8' is the encoding. It will try to // decode your binary string into a utf8 encoded buffer, and write that buffer. // This will cause it to fail because that encoding conversion is wrong. // Really through, 'binary' is just wrong to use. Buffers are already binary. fs.writeFile('image_decoded.jpg', decodedImage, function(err) {}); }); 

下一个例子可以工作,但是效率很低,因为不需要随时更改编码,但是我只想表明它是清楚的。 如果你真的想要有一个特定的编码,你需要确保你是一致的。 每个函数都有一个编码参数。

 fs.readFile(image_origial, 'binary', function(err, original_data){ fs.writeFile('image_orig.jpg', original_data, 'binary', function(err) {}); var base64Image = new Buffer(original_data, 'binary').toString('base64'); var decodedImage = new Buffer(base64Image, 'base64').toString('binary'); fs.writeFile('image_decoded.jpg', decodedImage, 'binary', function(err) {}); }); 

这是正确的做法。 保持一切为缓冲区,除非你使base64。

 fs.readFile(image_origial, function(err, original_data){ fs.writeFile('image_orig.jpg', original_data, function(err) {}); var base64Image = original_data.toString('base64'); var decodedImage = new Buffer(base64Image, 'base64'); fs.writeFile('image_decoded.jpg', decodedImage, function(err) {}); }); 

稍微好一点的解决办法是删除所有可能的MIMEtypes:

 var buff = new Buffer(req.body.imageFile .replace(/^data:image\/(png|gif|jpeg);base64,/,''), 'base64'); fs.writeFile('/file/path/', buff, function (err) { console.log('done'); }); 

这是@ Herve的答案的补充。