Node.js NodeJS base64图像编码/解码不太正常

Node.js NodeJS base64图像编码/解码不太正常,node.js,base64,Node.js,Base64,我一直在尝试将发布到nodeJS(和express框架)的图像保存到数据库,但遇到了一些问题。忽略所有的web处理,我认为我已经将问题缩小到了节点中base64编码的方式。我相信下面这个过于简单的例子应该可以工作,但是输出图像总是被破坏的 示例(1)加载图像(2)保存if(image\u orig)的副本,以确认节点可以正确读取文件。这总是有效的。(3) 我获取图像并对其内容进行base64编码,(4)然后对其进行解码。最终输出图像(image\u decoded)始终损坏 救命啊! (OSX

我一直在尝试将发布到nodeJS(和express框架)的图像保存到数据库,但遇到了一些问题。忽略所有的web处理,我认为我已经将问题缩小到了节点中base64编码的方式。我相信下面这个过于简单的例子应该可以工作,但是输出图像总是被破坏的

示例(1)加载图像(2)保存if(
image\u orig
)的副本,以确认节点可以正确读取文件。这总是有效的。(3) 我获取图像并对其内容进行base64编码,(4)然后对其进行解码。最终输出图像(
image\u decoded
)始终损坏

救命啊! (OSX Lion上的node.js 0.6.0)


我认为您对编码参数的用法有点误解。如果要指定“二进制”编码,则需要一致地进行。但实际上你根本不需要它。您似乎混淆了缓冲区和二进制字符串的用法

//这告诉节点将文件加载到缓冲区“原始数据”中,因为
//尚未为返回的值指定编码。如果你提供了
//编码,则原始_数据将是具有该编码的字符串。
fs.readFile(图像原始、函数(错误、原始数据){
//这会告诉节点获取该缓冲区,并将其写入新文件名。
//同样,没有提供编码,因此它将假定为缓冲区或utf8字符串。
fs.writeFile('image\u orig.jpg',原始数据,函数(err){});
//这告诉节点从旧的缓冲区创建一个新的缓冲区,这意味着
//它将迭代原始_数据,一次复制一个字节
//它们将是相同的缓冲区。它将忽略“binary”参数
//因为您传递的对象不是字符串。
//然后将该缓冲区的内容编码为base64,这很好。
var base64Image=新缓冲区(原始_数据,'binary')。toString('base64');
//在这里,您将base64解码为一个缓冲区,这很好,但是
//将缓冲区转换为编码为“binary”的字符串。这意味着
//它是一个字符串对象,其代码点是缓冲区的字节。
var decodedImage=新缓冲区(base64Image,'base64')。toString('binary');
//在这里,您尝试将该字符串对象写入一个文件
//have give是一个字符串,但尚未为
//写入命令,然后它将假定“utf8”是编码。它将尝试
//将二进制字符串解码为utf8编码的缓冲区,然后写入该缓冲区。
//这将导致它失败,因为编码转换是错误的。
//实际上,使用“二进制”是错误的。缓冲区已经是二进制的了。
writeFile('image_decoded.jpg',decodedImage,function(err){});
});
下一个示例将起作用,但效率非常低,因为不需要一直更改编码,但我只想清楚地说明这一点。如果你真的想有一个特定的编码,你需要确保你是一致的。这些函数中的每一个都有一个编码参数

fs.readFile(图像原始,“二进制”函数(错误,原始数据){
writeFile('image\u orig.jpg',原始数据,'binary',函数(err){});
var base64Image=新缓冲区(原始_数据,'binary')。toString('base64');
var decodedImage=新缓冲区(base64Image,'base64')。toString('binary');
writeFile('image_decoded.jpg',decodedImage',binary',function(err){});
});
这是正确的做法。保留所有内容作为缓冲区,除非将其设为base64

fs.readFile(图像原始,函数(错误,原始数据){
fs.writeFile('image\u orig.jpg',原始数据,函数(err){});
var base64Image=原始数据.toString('base64');
var decodedImage=新缓冲区(base64Image,'base64');
writeFile('image_decoded.jpg',decodedImage,function(err){});
});

稍微好一点的解决方案是删除所有可能的mime类型:

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答案的补充。

感谢您提供的信息丰富的回复!我还可以使用您的指导原则将图像编码到base64。@ZainShaikh请提出一个新问题。为什么需要删除mime类型?元数据仅在浏览器中使用。如果不删除,节点将存储损坏的图像。
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');
});