上传时图像方向错误 - Amazon S3



我让用户使用Multer-S3将多张图像直接上传到Amazon-S3,然后通过循环在前端显示这些图像。 一切正常。

但是,当通过移动设备上传图像(在iPhone或Android上拍摄的图像(时,方向在移动设备上是正确的,但在台式机上的方向不正确。主要问题。

这是由于我相信的图像EXIF数据。

似乎 ImageMagick 或 Kraken JS https://kraken.io/docs/storage-s3 可能是解决它的一种方法,但对于我的生活,我无法弄清楚如何通过上传和显示如下所示的图像的方式实现它们。

我将如何更改下面的代码以自动定向图像?注意:它必须适用于多个图像

感谢您的任何帮助!

以下是我让用户一次将多张图像直接上传到Amazon-S3的方式:

aws.config.update({
secretAccessKey: 'AccessKey',
accessKeyId: 'KeyID',
region: 'us-east-2'
});
var s3 = new aws.S3();
var storage =  multerS3({
limits : { files: 25 },
s3: s3,
bucket: 'files',
key: function (req, file, cb) {
var fileExtension = file.originalname.split(".")[1];
var path = "uploads/" + req.user._id + Date.now() + "." + fileExtension;
cb(null, path); 
},
})

var upload = multer({storage: storage}).any("images", 25);
router.post("/", middleware.isLoggedIn, function(req, res, next){
upload(req,res,function(err) {
if(err) {
console.log(err);
res.redirect('/')
}


Listings.findById(req.params.id, function(err, foundListings){
var allimages = []
if(typeof req.files !== "undefined") {
for(var i = 0; i < req.files.length; i++) {
allimages.push(req.files[i].key);
}
}
var currentimages = allimages;
var newListings = {currentimages:currentimages}
//Removed the other Model aspects
Listings.create(newListings, function(err, newlyCreated){
if(err){
console.log(err);
} else {
res.redirect("/listings");
}
});
});

我如何在前端显示图像。Listings.currentimages是一个包含所有图像链接的数组。

app.locals.awspath = "https://s3.us-east-2.amazonaws.com/myfiles/";

awspath是我的 Amazon-S3 路径的文件路径

<div id='allimages'>
<% for(var i = 0; i < listings.currentimages.length; i++ ) { %>
<div class='smallerImages'>
<%  var url2 = awspath + listings.currentimages[i] %>
<img class="small" src="<%= url2 %>">
</div>
<% } %>
</div>

问题是iOS设置了导致此行为的图像的EXIF元数据。您可以使用可以读取 EXIF 元数据并为您旋转图像的库。

JPEG-Autorotate(https://github.com/johansatge/jpeg-autorotate(是一个非常简单的库,并且有非常好的文档(你应该检查一下(。

var jo = require('jpeg-autorotate');
var fs = require('fs');
// var options = {quality: 85};
var options = {};
var path = '/tmp/Portrait_8.jpg'; // You can use a Buffer, too
jo.rotate(path, options, function(error, buffer, orientation) {
if (error) {
console.log('An error occurred when rotating the file: ' + error.message);
return;
}
console.log('Orientation was: ' + orientation);
// upload the buffer to s3, save to disk or more ...
fs.writeFile("/tmp/output.jpg", buffer, function(err) {
if(err) {
return console.log(err);
}
console.log("The file was saved!");
});
});

您可以从此处找到一些具有不同 EXIF 旋转元数据的示例图像

转换为 AWS Lambda 函数

// Name this file index.js and zip it + the node_modules then upload to AWS Lambda
console.log('Loading function');
var aws = require('aws-sdk');
var s3 = new aws.S3({apiVersion: '2006-03-01'});
var jo = require('jpeg-autorotate');
// Rotate an image given a buffer
var autorotateImage = function(data, callback) {
jo.rotate(data, {}, function(error, buffer, orientation) {
if (error) {
console.log('An error occurred when rotating the file: ' + error.message);
callback(error, null);
} else {
console.log('Orientation was: ' + orientation);
callback(null, buffer);
}
});
};
// AWS Lambda runs this on every new file upload to s3
exports.handler = function(event, context, callback) {
console.log('Received event:', JSON.stringify(event, null, 2));
// Get the object from the event and show its content type
var bucket = event.Records[0].s3.bucket.name;
var key = event.Records[0].s3.object.key;
s3.getObject({Bucket: bucket, Key: key}, function(err, data) {
if (err) {
console.log("Error getting object " + key + " from bucket " + bucket +
". Make sure they exist and your bucket is in the same region as this function.");
callback("Error getting file: " + err, null);
} else {
// log the content type, should be an image
console.log('CONTENT TYPE:', data.ContentType);
// rotate the image
autorotateImage(data.Body, function(error, image) {
if (error) {
callback("Error rotating image: " + error, null);
}
const params = {
Bucket: bucket,
Key: 'rotated/' + key,
Body: image
};
// Upload new image, careful not to upload it in a path that will trigger the function again!
s3.putObject(params, function (err, data) {
if (error) {
callback("Error uploading rotated image: " + error, null);
} else {
console.log("Successfully uploaded image on S3", data);
// call AWS Lambda's callback, function was successful!!!
callback(null, data);
}
});
});
}
});
};

注意此函数将旋转的图像上传到同一存储桶,但您可以轻松更改它。如果您刚刚开始使用 AWS Lambda,我建议您了解更多信息(https://www.youtube.com/watch?v=eOBq__h4OJ4、https://www.youtube.com/watch?v=PEatXsXIkLc(

确保在创建函数时具有正确的权限(读取和写入(、正确的函数触发器、正确的"处理程序"!确保在 CloudWatch 中也签出函数日志,使调试变得更加容易。如果它开始超时,请增加函数超时并增加其内存。

最新更新