質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

ImageMagick

ImageMagickとは、画像の表示や操作を行うオープンソースのソフトウェアです。プログラムはCで書かれており、GIFやJPEG、PDFなど画像ファイルフォーマット100種類以上に対応しています。

Q&A

解決済

1回答

3108閲覧

[AWS Lambda, 画像リサイズ] S3のある一つのバケットに存在する全ての画像のサムネイル作成で発生するエラーに関して

komo_ta

総合スコア275

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

ImageMagick

ImageMagickとは、画像の表示や操作を行うオープンソースのソフトウェアです。プログラムはCで書かれており、GIFやJPEG、PDFなど画像ファイルフォーマット100種類以上に対応しています。

0グッド

0クリップ

投稿2019/01/11 08:10

#はじめに
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

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

目星をつけるために、まずはもっともっとミニマルな構成で試すべきです。

  • S3からエラーが出る画像ファイルをローカルに持ち帰る
  • 拡張子詐欺じゃないか、バイナリエディタで開いて先頭付近の数十バイトを調査してみる(画像ファイルの特徴はぐぐれば出る)
  • 素のImageMagickを使ってサムネ画像の生成を試みる
  • Node.jsのfsとgmモジュール使ってローカルでサムネ画像の生成を試みる

まずはこれ全部やってみて下さい。
恐らく何処かで躓くでしょうから、それを元に更に調査して絞り込んで行きましょう。


正直今のままでは画像ファイルはない、エラーもなし、なんか変なラッパー使ってる
「これで出来ません」ってじゃあ誰ならどうやって答えられるんだ状態です。

画像ファイルは機密情報だから公開出来ない情報でしょうし、
秘密保持契約交わして、金もらって変わりに上記の仕事を受けるという感じの流れになるのは確実ですからね。
この質問文のままではクラウドワークスで発注しないと解決出来ないと思います。

最終的にまたteratailに戻ってくる可能性はありますが、
汎用的な問題に咀嚼できるよう、まずは出来る事を一つずつ潰していきましょう。

投稿2019/01/11 08:41

miyabi-sun

総合スコア21158

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

komo_ta

2019/01/11 08:46

了解です、ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問