画像のアップロードについて

806 views
Skip to first unread message

daaishi

unread,
Apr 9, 2013, 4:15:38 AM4/9/13
to node...@googlegroups.com
はじめまして。
石田と申します。

現在、チャット機能に画像を投稿できる機能を追加しようと考えています。
そこで、クライアント側のformから画像を選択し、XHRでデータをサーバーにPOSTし、サーバーでパスを変更して、フォルダに保存し、それをhtmlで表示する機能を実装しました。

これをherokuで利用したいので、画像データをAmazon S3に保存し、それを取り出してhtmlで表示したいのですが、サーバーで受け取ったデータをどのようにしてAmazon S3に保存すれば良いかわかりません。

知識が足りなく、説明不足の点があるかと思いますが、
アドバイス頂けないでしょうか?
宜しくお願い致します。

EBIHARA, Yuichiro

unread,
Apr 9, 2013, 7:27:11 AM4/9/13
to node...@googlegroups.com
はじめまして、海老原と申します。

ちょうどいま同じようなことをやっています。
以下のサイトが参考になりました。

Expressでファイルをアップロード

Node.jsからAmazon S3にアップロード

だいたい以下の様な手順でうまくいっています。

1.いったんファイルシステムに保存
2.それをfs.readFileで読み込み、S3にアップロード
3.1のファイルをfs.unlinkで削除

あと、私の場合はアップロードされたファイルのリサイズ、サムネイル作成もやっていますが、以下のリストが役に立ちました。
リサイズとS3へのアップロードをいっぺんにやってくれるようなものもあります。
(私はEasyImageを選びましたが)


以上、お役に立てば幸いです。

--
海老原 雄一郎 / EBIHARA, Yuichiro
 Email: e...@mercury.ne.jp
 Twitter: @yebihara



2013年4月9日 17:15 daaishi <sho1...@gmail.com>:

--
 
---
このメールは Google グループのグループ「Node.js 日本ユーザグループ」の登録者に送られています。
このグループから退会し、メールの受信を停止するには、nodejs_jp+...@googlegroups.com にメールを送信します。
その他のオプションについては、https://groups.google.com/groups/opt_out にアクセスしてください。
 
 

daaishi

unread,
Apr 9, 2013, 7:44:08 AM4/9/13
to node...@googlegroups.com
ご連絡ありがとうございます。
はじめまして、宜しくお願いします。

1.いったんファイルシステムに保存

herokuでは読み出しだけという記事を見つけ、実際に画像を保存できませんでした。
ファイルシステムに保存というのはまた別の方法があるのでしょうか?

お手数ですが、宜しくお願いします。

石田
twitter: @sho1i4da

2013年4月9日火曜日 20時27分11秒 UTC+9 Ebihara Yuichiro:
このグループから退会し、メールの受信を停止するには、nodejs_jp+unsubscribe@googlegroups.com にメールを送信します。
その他のオプションについては、https://groups.google.com/groups/opt_out にアクセスしてください。
 
 

Kazuyuki Honda

unread,
Apr 9, 2013, 8:35:08 AM4/9/13
to nodejs_jp
石田さん

本多@hakobera です。

なんとなくネタとして面白そうだったの、
express 3.1 + AWS公式SDK for Node.jsで実装してみました。
Heroku でも Node.js 0.10.3 が動いています。


4/11まで期間限定のLiveデモはこちら
 ※ 1MBまでのファイルしかあげられないようにしてあります
 ※ ファイルは適当なタイミングで消していきます


> herokuでは読み出しだけという記事を見つけ、
> 実際に画像を保存できませんでした。ファイルシステムに保存というのはまた別の方法があるのでしょうか?

今回のサンプルだと、express が処理を隠蔽してしまっていますが、
Heroku はファイルを保存できない(=再起動すると消えてしまう)だけで、このように /tmp 以下にはファイルを書き込むことが可能です。

上記リポジトリの routes/upload.js の19行目の下に console.log を追加してみると、実際のファイルのパスが見えます。

  var uploadFile = req.files.upload;
  if (!uploadFile) {
    return res.send('No file is uploaded!');
  }
  console.log(uploadFile); // <= 追加

出力結果

{
  domain: null,
  _events: {},
  size: 115013,
  path: '/tmp/4ad3d88c6a6fb7e6a6fa7ae6fb7884b1.png',
  type: 'image/png',
...
}

というわけで、expresss(実際の処理は formidable https://github.com/felixge/node-formidable がやっています)
 を使う場合は特に意識する必要もないですし、
自分でファイルを保存したい場合は、/tmp 以下にファイルを書きだして、同様の処理をすれば良いです。

今回はサンプルですのでそのままファイルを保存していますが、
画像は海老原さんの言うとおり、なんらかの画像処理ライブラリ(ImageMagick のラッパーなら Heroku で動きます)で、
本当に画像なのかのチェック、サムネイル作成、リサイズなどを組み込んだ方が良いと思います。

以上、なにか参考になれば。

P.S 今回、海老原さんの所で紹介されているAWSの公式SDKを使ってみましたが、最初 Promise スタイルだったのが、いつのまにか Node.js 標準API準拠の
コールバックスタイルに変わっていて、使いやすくなってきたなと思いました。


2013年4月9日 20:44 daaishi <sho1...@gmail.com>:
このグループから退会し、メールの受信を停止するには、nodejs_jp+...@googlegroups.com にメールを送信します。
その他のオプションについては、https://groups.google.com/groups/opt_out にアクセスしてください。
 
 

daaishi

unread,
Apr 10, 2013, 1:58:05 AM4/10/13
to node...@googlegroups.com
本多さん

非常に参考になります!
/tmp以下に書き込むことは可能なのですね。

socket通信を使い、画面の遷移をせずに画像をアップしていく場合には、ファイルをサーバーに送り、/tmpに保存し、pathを書き換えれば宜しいのでしょうか?

宜しくお願い致します。

2013年4月9日火曜日 21時35分08秒 UTC+9 hakobera:

daaishi

unread,
Apr 11, 2013, 7:34:47 AM4/11/13
to node...@googlegroups.com
海老原さん、本多さん

アドバイスありがとうございました。
画像をアップロードすることができました。

更に質問があります。
iPhone、iPadから画像をアップロードすると画像が90度回転してしまいます。
exifに回転のデータがあり、それをimagemagickで確認することができました。

これを書き換えて、画像が回転しないようにと考えているのですが、行き詰まっています。

アドバイス頂けないでしょうか。
宜しくお願い致します。

石田

2013年4月10日水曜日 14時58分05秒 UTC+9 daaishi:

Kazuyuki Honda

unread,
Apr 11, 2013, 8:28:57 AM4/11/13
to nodejs_jp
石田さん

本多@hakobera です。

以下のブログに書いてあるように、
-auto-orient オプションを付けて、imagemagick を実行してあげれば良いと思います。

iPhone / iPadの画像が90度回転してしまっているのをサーバ側で直す

http://lab.flama.co.jp/archives/765

node-imagemagick だと、customArgs: ['-auto-orient'] とかしてあげれば良いみたいですね。



2013年4月11日 20:34 daaishi <sho1...@gmail.com>:
このグループから退会し、メールの受信を停止するには、nodejs_jp+...@googlegroups.com にメールを送信します。
その他のオプションについては、https://groups.google.com/groups/opt_out にアクセスしてください。
 
 

Message has been deleted

daaishi

unread,
Apr 12, 2013, 7:39:09 AM4/12/13
to node...@googlegroups.com
本多さん

ありがとうございます!
無事、サーバにて回転を直すことができました。

また問題がありまして。
サーバーで回転を直す処理をすると、新しく画像データが生成され、
それをtmpに保存して、そのデータのパスを利用して、amazon s3に保存するという
ものを実装しようと挑戦しています。

しかし、新しい画像データをtmpに保存した後、パスを利用しようとすると、
もとのパスのままになっています。

おそらくなのですが、回転を直す処理が完了する前に、次の処理をしてしまっているからでは
ないかと考えているのですが、この場合、どのように処理をすればよろしいのでしょうか?

もしくは、別の問題が考えられるかもしれません。

アドバイス宜しくお願い致します。

石田

2013年4月11日木曜日 21時28分57秒 UTC+9 hakobera:

Kazuyuki Honda

unread,
Apr 12, 2013, 8:14:54 AM4/12/13
to nodejs_jp
石田さん

本多@hakoberaです。

> おそらくなのですが、回転を直す処理が完了する前に、次の処理をしてしまっているからでは
> ないかと考えているのですが、この場合、どのように処理をすればよろしいのでしょうか?

本当はソースをどこかに公開してもらえると、より具体的にコメントできるのですが、ないので推測になりますが、これは普通に Node のコールバックスタイルでの実行順序をきちんと把握せずにプログラムを書いているからではないでしょうか。

fs.readFile を例にすると、

// 1
fs.readFile('some.txt', function (err, data) {
// 2
});
// 3

と書いた場合、処理の順番は、1 => 3 => 2 になります。

ということで、以前に提示したサンプルを node-imagemagick を利用して、
リサイズしてからS3にアップロードするように改造してみました。

https://bitbucket.org/hakobera/s3-image-upload-nodejs-on-heroku/src/5c9f8b3a2cac46ac8ba0c3bb419fa344f7ec9c4a/routes/upload.js?at=master#cl-27

      var srcPath = uploadFile.path;
      var dstPath = srcPath + '_converted';

      console.log('src=%s, dst=%s', srcPath, dstPath);

      im.resize({
        srcPath: srcPath,
        dstPath: dstPath,
        width: 128,
        customArgs: [ '-auto-orient' ]
      }, function (err, stdout, stderr) {
        if (err) return next(err);
        fs.readFile(dstPath, next);
      });

こんな感じで、im.resize() のコールバックで変換後のファイルを読みこめば良いはずです。

2013年4月12日 20:39 daaishi <sho1...@gmail.com>:
このグループから退会し、メールの受信を停止するには、nodejs_jp+...@googlegroups.com にメールを送信します。
その他のオプションについては、https://groups.google.com/groups/opt_out にアクセスしてください。
 
 

daaishi

unread,
Apr 16, 2013, 8:04:24 AM4/16/13
to node...@googlegroups.com


2013年4月9日火曜日 17時15分38秒 UTC+9 daaishi:

daaishi

unread,
Apr 16, 2013, 8:05:00 AM4/16/13
to node...@googlegroups.com
本多さん

石田です。
連絡が遅くなりましてすいません。

アドバイス頂いた通り、コールバックで変換後のファイルを読み込むことで
回転を修正することができました。

アドバイスありがとうございます!

石田

2013年4月12日金曜日 21時14分54秒 UTC+9 hakobera:

daaishi

unread,
Apr 22, 2013, 3:46:45 AM4/22/13
to node...@googlegroups.com
本多さん

石田@sho1i4daです。

これまでアドバイスを頂き、開発と勉強が非常に捗っています。

画像をAmazon S3にアップロードし、画像をリアルタイムに投稿することが可能になりました。
ここで、質問があります。

アップロードされている画像を全てAmazon S3から取得し、それを表示したいと考えています。

アドバイス頂けないでしょうか?
宜しくお願い致します。

2013年4月12日金曜日 21時14分54秒 UTC+9 hakobera:
Reply all
Reply to author
Forward
0 new messages