【问题标题】:node.js uploading output of imagemagick to AWS S3node.js 将 imagemagick 的输出上传到 AWS S3
【发布时间】:2013-10-24 15:20:27
【问题描述】:

我在使用 imagemagick 处理图像时遇到问题,然后将其上传到 S3。生成的对象具有不同(更大)的大小,并且似乎已损坏。如果我做了一个中间步骤并首先将输出保存到本地 tmp 文件并读回,然后上传结果一切似乎都很好。这是不起作用的代码。

im.resize({
    srcData: imageObject.Body,
    width: variant.width,
    height: variant.height,
    customArgs: ['-auto-orient']
}, function(err, stdout, stderr) {
    if (err) {
        // This resize completed successfully
        log.err('Failed calling imageMagick, bail out', err);
        callback(err);
        return;
    }

    var fileName = cfg.aws.s3.uploadDir +
                    photo.imageId + '/' +
                    variant.width + 'x' + variant.height + '.jpg';
    log.info('Storing image at S3 ' + fileName);
    //fs.writeFileSync('/tmp/xxx.jpg', stdout, 'binary');
    //stdout = fs.readFileSync('/tmp/xxx.jpg');
    var x = new Buffer(stdout);
    console.log(x);
    s3.putObject(
        {
            Bucket: cfg.aws.s3.bucket,
            Key: fileName,
            Body: x,
            ContentType: 'image/jpeg',
            ACL: 'public-read'
        },
        function(err, data) {
            if (err) {
                // Failed saving to S3
                log.error('Failed saving to S3', err);
            }

            callback(err);
        }
    );
});

取消注释fileWriteSync和fileReadSync,它可以正常工作。

console.log(x) 命令在两种情况下的输出: 不好:

缓冲区 c3 bf c3 98 c3 bf c3 a0 00 10 4a 46 49 46 00 01 01 01 00 01 00 01 00 00 c3 bf c3 9b 00 43 00 06 04 05 06 05 04 06 06 05 06 07 07 06 08 0a 10 0a 0a 09 09 ...>

好:

缓冲区 ff d8 ff e0 00 10 4a 46 49 46 00 01 01 01 00 01 00 01 00 00 ff 分贝 00 43 00 06 04 05 06 05 04 06 06 05 06 07 07 06 08 0a 10 0a 0a 09 09 0a 14 0e 0f 0c 10 ...>

你可以看到好的一个是正确的 jpeg,坏的虽然包含类似的序列,如 4a 46 49 46 = JFIF,但是有些字节是关闭的,并且有移位,整个文件在坏的情况。

与编码有关吗?我已经尝试了几件事,但现在我迷路了。

谢谢!

更新 #1: 显然它与 UTF 编码有关,但我仍然不完全理解在这种情况下会发生什么。显然 c3 bf c3 98 c3 bf c3 a0 00 10 4a 46 49 46 00 01 是 UTF 编码:

U+00FF LATIN SMALL LETTER Y WITH DIAERESIS character (ÿ)
U+00D8 LATIN CAPITAL LETTER O WITH STROKE character (Ø)
U+00FF LATIN SMALL LETTER Y WITH DIAERESIS character (ÿ)
U+00E0 LATIN SMALL LETTER A WITH GRAVE character (à)
U+0000 <control> character
U+0010 <control> character
U+004A LATIN CAPITAL LETTER J character
U+0046 LATIN CAPITAL LETTER F character
U+0049 LATIN CAPITAL LETTER I character
U+0046 LATIN CAPITAL LETTER F character
U+0000 <control> character
U+0001 <control> character

当 FF D8 FF .. 正是我所期待的。

我知道如何在没有临时文件的情况下使代码工作(将 var x = new Buffer(stdout); 替换为 var x = new Buffer(stdout, 'binary')强>)

但是我仍然不能说我完全理解这里发生了什么,这应该没有 Buffer() 包装,哪个组件有问题?图像魔术师?缓冲?

【问题讨论】:

  • 哇,这是一个奇怪的问题。措辞良好的问题和有趣的问题。我会看看我今天某个时候能不能调查一下:)
  • 只是出于好奇,如果不将标准输出放入新的缓冲区对象会怎样?它是从 node-imagemagick 作为字符串出来的吗?如果它以缓冲区的形式出现,则损坏可能是双缓冲区包装器......
  • 您是否尝试过在您的 putObject 选项中使用 `Body: stdout` 来仅发送 stdout 而无需包装在不必要的缓冲区中?
  • 是的,我的原始代码没有 Buffer 包装,结果是一样的。我添加包装的原因是当我尝试执行 console.log(stdout) 时,我刚刚在屏幕上得到了一个完整缓冲区的二进制转储,缓冲区我得到了这个漂亮的打印输出,但同样对 blob 没有任何影响在 S3 中。无论如何,在坏情况下看到 c3 bf c3 标头?它的重复。而且,惊喜forums.adobe.com/thread/598204 这是标准的东西。我想知道它是什么,显然 fs.writeFile 处理得当
  • 你找到了答案我正在寻找类似的解决方案,采用 im.resize 方法并将其直接输出到 S3

标签: javascript node.js amazon-s3 imagemagick node-imagemagick


【解决方案1】:

这显然已经很晚了,但是我自己也遇到了这个问题,这就是我的工作方式;

ImageMagick.resize(params, function(err, stdout, stderr) {
    // Handle errors

    // Save the output of imagemagick to S3
    S3.putObject({
        Bucket: bucketName,
        Key: fileName,
        Body:  new Buffer(stdout, "binary")
    }).promise().then(function(data){
      // Success
    }).catch(function(err){
      // Error
    });
});

这其中的关键部分显然是; new Buffer(stdout, "binary")。如果您不知道响应是否是缓冲区,您可以使用Buffer.isBuffer 方法并执行以下操作;

var body = ( Buffer.isBuffer(stdout) ? stdout : new Buffer(stdout, "binary") );

【讨论】:

    【解决方案2】:

    不确定 OP 是否解决了问题,但我也遇到了类似的问题,上传到 S3 的图像比原始文件大。你能告诉我标准输出包含什么(即,它是一个原始字节流吗?)

    我通过将 Body: 参数设置为使用 base64 编码缓冲区而不是二进制缓冲区来解决了这个问题。我不完全确定为什么这解决了问题,但我怀疑它与此有关:

    当需要对二进制数据进行编码时,通常使用 Base64 编码方案,这些二进制数据需要通过旨在处理文本数据的媒体存储和传输。这是为了确保数据在传输过程中保持完好无损。

    来源:MDN

    【讨论】:

    • 无论如何你可以展示你的解决方案,我目前正在处理同样的问题。
    猜你喜欢
    • 1970-01-01
    • 2019-04-11
    • 2020-04-28
    • 2021-06-13
    • 2021-06-13
    • 2018-08-29
    • 2019-04-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多