#はじめに
AWS Lambdaを使って、ある一つのバケット内にある画像全てのサムネイルを生成する関数を作成しておりまして、その処理に関わる質問になります。
#問題
下記のコードをラムダで実行し、バケット内の画像を一つずつ取得しその画像のサムネイルを作成した後に別のバケットにアップロードする処理を行っておりまして
var async = require('async'); var AWS = require('aws-sdk'); var gm = require('gm').subClass({ imageMagick: true }); // Enable ImageMagick integration. var util = require('util'); var path = require('path'); // get reference to S3 client var s3 = new AWS.S3(); exports.handler = function(event, context) { var bucket = "develop-hoge-files"; var items = []; // 関数の箱を入れる箱 var imageFns = []; var params = { Bucket: bucket, Prefix: "images/" }; s3.listObjects(params, function(err, data) { if (err) console.log(err, err.stack); // an error occurred else for (var i = 0; i < data.Contents.length; i++) { if (data.Contents[i].Key.match(".jpeg") && data.Contents[i].Key.match("images/")) { // こうすることでimagesの中にkey引数を束縛した関数が次々と飛び込んでいく var imageFn = imageResizeUpload(data.Contents[i].Key); imageFns.push(imageFn); } } async.waterfall(imageFns, function(err) { if (err) console.log(err); console.log('完了'); }); }); }; function imageResizeUpload(key) { return function(next) { // 旧imageResizeUploadとほぼ同じ挙動だが、最後にnext()と実行する作りに変更 async.waterfall([ function download(next) { // Download the image from S3 into a buffer. s3.getObject({ Bucket: "develop-hoge-files", Key: key }, next); }, function transform(response, next) { gm(response.Body).size(function(err, size) { var width = 640; var height = 480; // Transform the image buffer in memory. // 比率をそのままにリサイズし、左右に黒帯をつける. this.resize(width, height) .toBuffer("jpeg", function(err, buffer) { if (err) { next(err); } else { next(null, response.ContentType, buffer); } }); }); }, function upload(contentType, data, next) { // Stream the transformed image to a different S3 bucket. s3.putObject({ Bucket: "develop-hoge-files", Key: key.replace("images", "test-thumbnail-images"), Body: data, ContentType: contentType }, next); } ], function(err) { if (err) { console.log(err); } else { console.log("success"); } next(); }); } }
ほとんどの画像の変換とアップロードに成功するのですが、一部 Stream yields empty buffer lambda gm
というエラーが出まして、
下記の記事を参考に対象の関数を以下のように変えたところ(変えた部分だけ載せます)、
Lambdaで画像のサムネイルを作る [Stream yields empty buffer対策済]
gm(response.Body).size(function(err, size) { var width = 640; var height = 480; // Transform the image buffer in memory. // 比率をそのままにリサイズし、左右に黒帯をつける. this.resize(width, height) .stream(function(err, stdout, stderr) { // ストリームで出力する if (err) { console.log("gm process error"); console.log(err, stdout, stderr); context.fail(err); } var chunks = []; // ストリームのチャンクを溜め込むための配列 stdout.on('data', function(chunk) { console.log('===========pushed============='); chunks.push(chunk); // チャンクを溜め込む }); stdout.on('end', function() { var buffer = Buffer.concat(chunks); next(null, response.ContentType, buffer); }); }); });
下記の画像のように0KBで保存されました。(上記のエラーが出てなかったものに関しては、サムネイルの作成に成功しています)
.stream(function(err, stdout, stderr) { /
のコールバックで返ってくる、stdoutやstderrなどを調べましたが原因となりそうな情報を見つけられませんでした。どなたかわかる方おりませんでしょうか?
ちなみに画像の大きさによっては、上記の現象は変わらなそうでした。
どうぞよろしくお願いいたしますm(_ _)m
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/01/11 08:46