S3にアップした画像をLambdaでリサイズして別バケット(bucket)に保存するNode.jsのサンプルコード

とある案件でS3にアップされるオリジナル画像をリサイズで別バケットに保存したい要望があり先人の知恵と伝家の宝刀コピペを駆使して組んでみました。

処理の流れ
[オリジナル.jpg]→PUT→S3bucket→イベントキック→Lambda(リサイズbyNode.js)→S3別bucket保存

この処理の流れですが、案外ナレッジがネットにコロガッテいない。ナレッジの多くは同一バケットにリサイズした画像を保存するものばかりで私の要件には合わないのです
例えば

AWS Lambdaを使ってS3にアップロードされた画像をリサイズする - Qiita
Lambdaファンクションを作る ブループリント AWSの管理画面からLambdaに行くと、ブループリントという画面が出て 用途に応じたLambdaファンクションのテンプレートが選べます。 今回は「image-proces...

どうしたものかとGoogle検索で様々なキーワードで検索をしていると

LambdaでS3にアップロードされが画像をサムネイルにしてみた。 – ただいま名刺を切らしておりまして

このコードなら理解といいますか加工すれば、なんか出来そうな気がしてきました。
Lambdaファンクション用のNode.jsコードです

var im = require('imagemagick');
var aws = require('aws-sdk');
var s3 = new aws.S3({ apiVersion: '2006-03-01' });

exports.handler = function(event, context) {
    var bucket = event.Records[0].s3.bucket.name;
    var key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' '));
    var params = {
        Bucket: bucket,
        Key: key
    };
    s3.getObject(params, function(err, data) {
        if (err) {
            console.log(err);
            var message = "Error getting object " + key + " from bucket " + bucket +
                ". Make sure they exist and your bucket is in the same region as this function.";
            console.log(message);
            context.fail(message);
        } else {
            var contentType = data.ContentType;
            var extension = contentType.split('/').pop();
            
            var filename = 'images/' + (key.match(/^origin\/(.+)$/) ? RegExp.$1 : key);

            im.resize({
                srcData: data.Body,
                format: extension,
                width: 480 // リサイズする画像サイズを指定
            }, function(err, stdout, stderr) {
                if(err) {
                    context.fail(err);
                    return;
                }
                s3.putObject({
                    Bucket: bucket,
                    Key : filename,
                    Body: new Buffer(stdout, 'binary'),
                    ACL : 'public-read',
                    ContentType: contentType
                }, function(err, res) {
                    if (err) {
                        context.fail(err);
                    } else {
                        context.succeed();
                    }
                });
            });
        }
    });
};

このコードだと
S3-UPBucket(オリジナル画像がアップされるバケット)
└images/ (オリジナルをリサイズしたらimages/以下に保存される)

私の要件は
S3┬UPBucket(オリジナル画像がアップされるバケット)
└ReSizeBucket(リサイズした画像は別のバケットに保存したい)

なので

                s3.putObject({
                    Bucket: bucket,←このbucketが'ReSizeBucket'になれば良い
                    Key : filename,
                    Body: new Buffer(stdout, 'binary'),
                    ACL : 'public-read',
                    ContentType: contentType

加えて

            var filename = 'images/' + (key.match(/^origin\/(.+)$/) ? RegExp.$1 : key);
       ↓
            var filename = 'バケット以下のフォルダを指定する' + (key.match(/^origin\/(.+)$/) ? RegExp.$1 : key);

さすれば、私の要件が叶えられるはず
でNode.jsとかコードを書けないので「サルでもわかる」系を見てみる。
で完成したのが以下のコードです

var im = require('imagemagick');
var aws = require('aws-sdk');
var s3 = new aws.S3({ apiVersion: '2006-03-01' });
var outbucket = "ReSizeBucketName"; // リサイズ後の画像を保存するバケットを指定

exports.handler = function(event, context) {
    var bucket = event.Records[0].s3.bucket.name;
    var key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' '));
    var params = {
        Bucket: bucket,
        Key: key
    };
    s3.getObject(params, function(err, data) {
        if (err) {
            console.log(err);
            var message = "Error getting object " + key + " from bucket " + bucket +
                ". Make sure they exist and your bucket is in the same region as this function.";
            console.log(message);
            context.fail(message);
        } else {
            var contentType = data.ContentType;
            var extension = contentType.split('/').pop();
            //保存バケット以下のパス情報を指定
            var filename = 'Resize-Image/○○○○/○○○/' + (key.match(/^origin\/(.+)$/) ? RegExp.$1 : key);

            im.resize({
                srcData: data.Body,
                format: extension,
                width: 320 // リサイズする画像サイズを指定
            }, function(err, stdout, stderr) {
                if(err) {
                    context.fail(err);
                    return;
                }
                s3.putObject({
                    Bucket: outbucket, // 変数outbucketをPUTするbucketに指定する
                    Key : filename,
                    Body: new Buffer(stdout, 'binary'),
                    ACL : 'public-read',
                    ContentType: contentType
                }, function(err, res) {
                    if (err) {
                        context.fail(err);
                    } else {
                        context.succeed();
                    }
                });
            });
        }
    });
};

でLambdaに早速コードを入れてテスト実行したら、何事もなく正常終了しました。おぉーーーーー

オリジナル画像をアップするS3のバケットを選択して「Events」で*******.jpgがPutされたらリサイズ処理をするLambdaがキックされるように設定する。

次にバケットに適当な画像.jpgをアップロードしてみます。・・・・・・

するとvar outbucket = “ReSizeBucketName”;で指定したバケットにリサイズされた画像が生成されている。。。

何が大変だったか サンプルを探す時間です
そして無限ループに注意と言われても やっちゃうんだよなぁ 数百枚分のLambdaを実行してしまった。

シェアする

  • このエントリーをはてなブックマークに追加

フォローする

adana escort adıyaman escort afyon escort ağrı escort aksaray escort amasya escort ankara escort antalya escort ardahan escort artvin escort aydın escort balıkesir escort bartın escort batman escort bayburt escort bilecik escort bingöl escort bitlis escort bolu escort burdur escort bursa escort çanakkale escort çankırı escort çorum escort denizli escort diyarbakır escort düzce escort edirne escort elazığ escort erzincan escort erzurum escort eskişehir escort gaziantep escort gebze escort giresun escort gümüşhane escort hakkari escort hatay escort ığdır escort ısparta escort istanbul escort izmir escort izmit escort kahramanmaraş escort karabük escort karaman escort kars escort kastamonu escort kayseri escort kilis escort kırıkkale escort kırklareli escort kırşehir escort kocaeli escort konya escort kütahya escort malatya escort manisa escort mardin escort mersin escort muğla escort muş escort nevşehir escort niğde escort ordu escort osmaniye escort rize escort sakarya escort samsun escort şanlıurfa escort siirt escort sinop escort şırnak escort sivas escort tekirdağ escort tokat escort trabzon escort tunceli escort uşak escort van escort yalova escort yozgat escort zonguldak escort