【问题标题】:NodeJS base64 image encoding/decoding not quite workingNodeJS base64 图像编码/解码不太工作
【发布时间】:2011-12-27 23:01:47
【问题描述】:

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

示例 (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) {});
});

【问题讨论】:

    标签: node.js base64


    【解决方案1】:

    我认为您对编码参数的用法有点误解。如果您要指定编码“二进制”,那么您需要始终如一地执行此操作。但实际上你根本不需要它。您似乎混淆了 Buffer 与二进制字符串的用法。

    // 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) {});
    });
    

    这是正确的做法。将所有内容都保存为 Buffer,除非您将其设为 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) {});
    });
    

    【讨论】:

    • 感谢您提供信息丰富的回复!我也能够使用您的指南将图像编码为 base64。
    • @ZainShaikh 请创建一个新问题。
    【解决方案2】:

    稍微好一点的解决方案是删除所有可能的 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 答案的补充。

    【讨论】:

    • 为什么需要删除 mime 类型??
    • 元数据仅在浏览器中使用。如果您不删除它,节点存储的图像已损坏。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-31
    • 1970-01-01
    • 1970-01-01
    • 2012-06-21
    • 1970-01-01
    相关资源
    最近更新 更多