2017-08-09 6 views
0

それぞれのURLから2つのPNG画像をダウンロードしてからpixelmatchを使用してそれらを比較し、3番目の画像を生成します。ラムダのノードから生成されたPNGをamazon S3にアップロード

次に、3番目の画像をS3バケットにアップロードしようとしていますが、苦労しています。コードが続きます。

promise1およびpromise2は、それぞれpng1およびpng2を得る2つの呼び出しです。以下に使用されるdimensions1配列はpromise1に作成されます。 PNGpngjsパッケージです。

const promArr = [promise1, promise2]; 

Promise.all(promArr).then(() => { 
    const diff = new PNG({ width: dimensions1[0], height: dimensions1[1] }); 
    const pix = pixelmatch(png1.data, png2.data, diff.data, dimensions1[0], dimensions1[1], { threshold: 0.1 }); 
    const size = dimensions1[0] * dimensions1[1]; 
    diff.pack().pipe(fs.createWriteStream(`/tmp/${targetHash}.png`)); 
    const percentage = ((pix/size) * 100); 

    const fileBuffer = fs.readFileSync(`/tmp/${targetHash}.png`); 

    const s3 = new AWS.S3(); 
    s3.putObject({ 
    ACL: 'public-read', 
    Key: targetFilename, 
    Body: fileBuffer, 
    Bucket: targetBucket, 
    ContentType: 'image/png', 
    }, (err) => { 
    if (err) { 
     console.warn(err); 
     cb(err); 
    } else { 
     cb(null, { 
     percentage, 
     hash: `${targetFilename}`, 
     key: `${targetFilename}`, 
     bucket: targetBucket, 
     url: `${event.stageVariables.endpoint}${targetFilename}`, 
     }); 
    } 
    return; 
    }); 
}) 
.catch((err) => { 
    console.warn(`error: ${err}`); 
    cb(err); 
}); 

これは、macレポートの[プレビュー]が空であるイメージへのURLを返します。これは、私には非同期の問題があることを示唆しています。

diff.pack()を身体として渡してみましたが、エラー:Cannot determine length of [object Object]がありました。私はこのエラーの議論を見つけたhere

私は本当に解決策に近いと感じていますが、私はそこにはあまり行きません。誰も助けることができますか?ありがとうございます

+0

S3バケットに付与されている権限をチェックしましたか?ラムダ関数に関連付けられたIAMロールは、バケットを書き込むことができるように書き込みアクセスを許可する必要があります。 [ドキュメント](http://docs.aws.amazon.com/lambda/latest/dg/intro-permission-model.html#lambda-intro-execution-role)を参照してください。あなたのコメントのために – Olli

+0

@olliありがとうございました!私はserverlessを使用してIAMルールを設定しています。ここに私のYMLの一部です: 'iamRoleStatements: - 効果: アクション "許可": - "S3:ListBucket" - "S3:入れ*" - "S3:GetObject関数" リソース: - 「ARNを:aws:s3 ::: $ {self:custom.bucket_name} " - " arn:aws:s3 ::: $ {self:custom.bucket_name}/* "' 私は何かを必要としますか?書きます? 編集:私は動作するようにフォーマットしようとしていますが、それを解読することはできません: –

答えて

0

以下の解決策を参照してください。それは非同期の問題でした。ノートをhereから取得しました。 一時ファイルを作成するパイプが終了すると、s3のものがキックオフされます。 NBは、hereと記載されているcreateReadStreamを使用しています。

const promArr = [promise1, promise2]; 

Promise.all(promArr).then(() => { 
    const diff = new PNG({ width: dimensions1[0], height: dimensions1[1] }); 
    const pix = pixelmatch(png1.data, png2.data, diff.data, dimensions1[0], dimensions1[1], { threshold: 0.1 }); 
    const size = dimensions1[0] * dimensions1[1]; 
    const percentage = ((pix/size) * 100); 

    diff.pack().pipe(fs.createWriteStream(`/tmp/${targetHash}.png`).on('finish',() => { 
    const fileBuffer = fs.createReadStream(`/tmp/${targetHash}.png`); 

    const s3 = new AWS.S3(); 
    s3.putObject({ 
     ACL: 'public-read', 
     Key: targetFilename, 
     Body: fileBuffer, 
     Bucket: targetBucket, 
     ContentType: 'image/png', 
    }, (err) => { 
     if (err) { 
     console.warn(err); 
     cb(err); 
     } else { 
     cb(null, { 
      percentage, 
      hash: `${targetFilename}`, 
      key: `${targetFilename}`, 
      bucket: targetBucket, 
      url: `${event.stageVariables.endpoint}${targetFilename}`, 
     }); 
     } 
     return; 
    }); 
    })); 
}) 
.catch((err) => { 
    console.warn(`error: ${err}`); 
    cb(err); 
}); 

私は再び戻って読んだ後、tmpにする書き込みと完全に満足していないが、今のところ、AWS-SDKの制限に対処するための最も簡単な方法のようです。

関連する問題