MongoDBに画像を保存してnode.js(Express)とangularJSで表示する

  • 55
    Like
  • 0
    Comment
More than 1 year has passed since last update.

画像をBASE64エンコードしてMongoDBに保存すれば、取り出してそのまま<img>タグにセットできるじゃん!!という横着な方法です。
BASE64エンコードするとバイナリよりサイズが大きくなるのでMongoDBの容量を節約したいときはやめましょう。

(画像はファイルシステムに保存して、パスなどをMongoDBに保存するのが王道なのかな??)

流れ

  1. クライアントから画像(BASE64エンコード済み文字列)をアップロード(例としてandroidから送る)
  2. expressで受け取って、MongoDBに保存(Mongoose使用)
  3. 取り出してangularJSでブラウザに表示

1. クライアントから画像をアップロード

node.jsやMongoDBで扱い易いのでJSONに入れて送ります。
例えばAndroidから送るのであれば、こんなメソッドを用意して、BitmapをBase64エンコードした文字列を取得して、JSONに詰めて送信。
送信するところは省略。volleyなりなんなり使ってどうぞ。

↓この部分はJavaのソースコードなので注意。

java
private String stringifyBitmap(Bitmap bitmap) {
        ByteArrayOutputStream byteArrayBitmapStream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayBitmapStream);
        return Base64.encodeToString(byteArrayBitmapStream.toByteArray(), Base64.DEFAULT);
}

http://<ホスト名>/book にPOSTします。
JSONはこんな感じの想定。

jsondata
{
  jsondata: {
    title: 'とある本',
    coverImage: <BASE64エンコード済みの文字列>
  }
}

2. expressで受け取って、MongoDBに保存(Mongoose使用)

express

web.js
app.post('/book', db.book.create); // POSTの処理
model.js
// Bookスキーマを定義
var BookSchema = new mongoose.Schema({
    title  : String,
    coverImage : String
});

exports.Book = db.model('Book', BookSchema);

db.js
// jsonからPOSTデータを取り出す。
var content = JSON.parse(req.body.jsondata);

// MongoDBにBookドキュメントを保存
exports.book.create = function(req, res) {
  Book.create(content, function (err, data) {
    if (err) throw new Error(err);
    res.send('{ result: "ok" }');
  });
};

3. 取り出してangularJSでブラウザに表示

express

web.js
app.get('/book', db.book.read); // GETの処理。要認証

db.js
exports.book.read = function(req, res) {
  Book.find({ title: 'とある本' }, function(err, docs) {
    if (err) throw new Error(err);
    res.send(docs);
  });
};

angularJS

main.js
angular.module('angularApp').controller('MainCtrl', function ($scope, $http) {
  var url = '/book';

  $scope.book = [];
  $scope.getBook = function() {
    $http.get(url).success(function(data) {
      $scope.book = data;
    });
  };

  $scope.getBook();
});

imgタグのsrc属性にdataスキームとしてそのままセット!!!

main.html
<img src="data:image/gif;base64,{{book.coverImage}}"/>

最初にBASE64エンコードして以降、データを一切変換・加工してないところがポイント。