node.js将imagemagick的输出上传到AWS S3

我有一个问题操纵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)命令的输出有两种情况:BAD:

缓冲区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 db 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,但是有些字节是closures的,并且有变化,在坏的情况下整个文件大约20% 。

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

谢谢!

更新#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,'binary') )replacevar x = new Buffer(stdout

不过我还是不能说我完全明白这里发生了什么,这个应该不用Buffer()来包装,哪个组件有问题? ImageMagick的? 缓冲?

这显然很晚,但是我自己刚刚遇到了这个问题,这是我如何得到这个工作;

 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") );

不知道是否OP解决了这个问题,但我也有类似的问题上传到S3的图像比原来的文件大。 你能告诉我什么标准input包含(即,它是一个原始的字节stream?)

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

Base64编码scheme通常用于需要对需要存储和传输的二进制数据进行编码以处理文本数据的介质。 这是为了确保数据在运输过程中保持不变,无需修改。

来源: MDN