我正在尝试将图像发送到我在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。)
// 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);
});
})
});
});
}
})
});
});
});
});
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);
});
})
});
}
});
});
});