使用aws-sdk将base64编码缓冲区PUT到AWS S3存储桶,同时在node.js服务器上保存缩略图

时间:2014-03-02 03:33:47

标签: node.js amazon-web-services amazon-s3 graphicsmagick

我正在尝试将图像发送到我在Heroku上托管的node.js服务器到AWS上的S3存储桶,同时还在mongoLab的托管mongoDB中保存图像的缩略图。我已经成功地能够直接上传到S3,但是由于我添加了一个graphicsMagick / imageMagick回调来创建缩略图,因此每次尝试都会收到错误。我有一个python脚本,它拍摄照片并将PUT请求发送到我的服务器,并附上相关的请求详细信息,包括一个包含该图像的base64编码字符串。

我当前代码收到的错误是来自Heroku的超时错误。我很确定这是由于由于格式不正确的缓冲区导致AWS缺乏响应。

我遇到了this stack overflow question所见的类似问题。

从这里开始,我不确定如何移动缓冲区。非常感谢任何帮助。

我的app.js中的相关代码如下所示:

更新

14年3月3日 通过我在issue 94下的aws-sdk github网站上找到的一个例子,我能够得到这个。相关更新的app.js代码如下。原来是在那之下。 (请注意,创建缩略图的完整解决方案不是100%,因为保存到数据库的缓冲区格式不正确,我认为。但是图像以缩小的文件大小成功保存到s3。)

更新了app.js

// PUT
app.put("/api/events/:id", function (req, res){

console.log("PUT: ");

var buffer = new Buffer(req.body.photo, "base64");

var fullsizeBuffer = imageMagick(buffer, "image.jpg")
.quality(60)
.stream(function (err, stdout, stderror) {

if (stderror) {
  console.log("Error in creating an image from a Buffer: ", stderror);
}

var buf = new Buffer(0);

stdout.on("data", function(d) {
  buf = Buffer.concat([buf, d]);
});

stdout.on("end", function() {

  // Connect to AWS to process photo in PUT request
  s3.createBucket({Bucket: "theheartboothTEST"}, function() {

    var params = {
      Bucket: "theheartboothTEST",
      Key: req.body.photoID,
      Body: buf,
      ContentType: "image/jpeg",
      ContentEncoding: "base64",
      ACL: "public-read"
    };

    s3.putObject(params, function(err, data) {

      if (err) {
        console.log("Error uploading data to AWS S3: ", err);
      } else {

        imageMagick(buf, "thumb.jpg")
        .resize(320)
        .stream(function (err, stdout2, stderror2) {

          if (err) {
            console.log("Error in creating an thumbnail from a Buffer: ", err);
          }

          var thumbBuf = new Buffer(0);
          stdout2.on("data", function(d) {
            thumbBuf = Buffer.concat([thumbBuf, d]);
          });

          stdout2.on("end", function() {

            var photo = new PhotoModel({
              photoID : data.ETag,
              url     : "https://s3.amazonaws.com/theheartboothTEST/" + params.Key,
              thumbnail : thumbBuf,
            });

            EventModel.findById(req.params.id, function (err, partyEvent) {
              partyEvent.title        = req.body.title;
              partyEvent.description  = req.body.description;
              partyEvent.date         = req.body.date;
              partyEvent.location     = req.body.location;
              partyEvent.photos.push(photo);

              partyEvent.save(function (err) {
                if (!err) {
                  console.log("updated");
                } else {
                  console.log(err);
                }
                console.log("Successfully uploaded data to S3 Bucket: theheartboothTEST");
                res.send(partyEvent);
              });
            })
          });
        });
      }
    })
  });
});
});
});

原创app.js

var application_root = __dirname,
express = require('express'),
path = require('path'),
mongoose = require('mongoose'),
AWS = require('aws-sdk'),
// fs = require('fs'),
gm = require('gm'),
imageMagick = gm.subClass({ imageMagick: true });

// decode64 = require('base64').decode;
// config = require('./config.json');

var app = express();

// MongoDB Database
var mongoURI = process.env.MONGOLAB_URI;
var db = mongoose.createConnection(mongoURI);

// AWS Session
var s3 = new AWS.S3();

// Config
app.configure(function () {
app.use(express.bodyParser({limit: '6mb'}));
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(application_root, 'public')));
app.use(express.errorHandler({
   dumpexceptions: true,
   showStack: true}));
});

var Schema = mongoose.Schema;

var Photos = new Schema({
  photoID: {type: String, required: true},
  url: {type: String, required: true},
  thumbnail: {type: Buffer, required: false},
});

var PartyEvent = new Schema({
  title: { type: String, required: true },
  description: { type: String, required: true },
  date: { type: Date },
  location: { type: String, required: true },
  photos: [Photos],
});

var PhotoModel = db.model('Photo', Photos);
var EventModel = db.model('Event', PartyEvent);    

app.put("/api/events/:id", function (req, res){

console.log("PUT: ");

var buffer = new Buffer(req.body.photo, "base64");

gm(buffer, "image.jpg")
.quality(80)
.toBuffer("base64", function(err, buf) {

  var params = {
    Bucket: "theheartboothTEST",
    Key: req.body.photoID,
    Body: buf,
    ContentType: "image/jpeg",
    ACL: "public-read"
  };
  s3.putObject(params, function(err, data) {
    if (err) {
      console.log("Error uploading data to AWS S3: ", err);
    } else {

      gm(buffer, "image.jpg")
      .quality(80)
      .resize(320)
      .toBuffer("base64", function(err, thumbBuffer) {

        var photo = new PhotoModel({
          photoID : data.ETag,
          url     : "https://s3.amazonaws.com/theheartboothTEST/" + params.Key,
          thumbnail : thumbBuffer,
        });

        return EventModel.findById(req.params.id, function (err, partyEvent) {
          partyEvent.title        = req.body.title;
          partyEvent.description  = req.body.description;
          partyEvent.date         = req.body.date;
          partyEvent.location     = req.body.location;
          partyEvent.photos.push(photo);

          return partyEvent.save(function (err) {
            if (!err) {
              console.log("updated");
            } else {
              console.log(err);
            }
            console.log("Successfully uploaded data to S3 Bucket: theheartboothTEST");
            return res.send(partyEvent);
          });
        })
      });
    }
  });
});    
});

0 个答案:

没有答案