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 のコメントを外すと、正しく動作します。
次の 2 つの場合の 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 00 07 07 06a 08 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 080 0a 10 0e 09a 09 0c 10 ...>
ご覧のとおり、良いものは適切な jpeg であり、悪いものには 4a 46 49 46 = JFIF のような同様のシーケンスが含まれていますが、一部のバイトがオフになっており、シフトがあり、悪いケースではファイル全体が約 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
when FF D8 FF .. まさに私が期待していたものです。
一時ファイルなしでコードを機能させる方法を知っています ( var x = new Buffer(stdout);を var x = new Buffer(stdout, 'binary')に置き換えます)
ただし、ここで何が起こったのかを完全に理解しているとは言えません。これは Buffer() ラッピングなしで行う必要があります。どのコンポーネントに問題がありますか? イメージマジック? バッファ?