2017-08-07 27 views
10

我让用户使用Multer-S3,然后通过循环显示在前端的那些图像上传多个图像直接到Amazon-S3。所有的作品完美。错误图像方向时 - 亚马逊S3

但是,当通过手机上传图片(在iPhone或Android上拍摄的图片)时,手机的方向是正确的,但在桌面上没有正确的方向。主要问题。

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

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

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

感谢您的帮助!

继承人的如何我让用户同时直接上传多张图片,以亚马逊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是文件路径到我的亚马逊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> 
+0

看看[this](https://stackoverflow.com/q/46135349/643039) –

+0

@MathieudeLorimier感谢您的发送。很有意思。我想我宁愿将它固定在后端而不是前端。有什么想法吗? :) – AndrewLeonardi

+1

我同意,@mostafazh有很好的建议。 –

回答

7

的问题是,iOS的设置导致这种现象的图片的EXIF元数据。您可以使用可以读取EXIF元数据并为您旋转图像的库。

JPEG-自动旋转https://github.com/johansatge/jpeg-autorotate)是一个非常简单 lib和具有非常好的文件(你应该检查出来)。

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!"); 
    }); 
}); 

可以从here

找到不同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__h4OJ4https://www.youtube.com/watch?v=PEatXsXIkLc

请确保您已经正确的权限(读,写),功能正确触发,正确“处理程序”时,创造功能!确保在CloudWatch中检出功能日志,使调试变得更加容易。如果它开始超时,增加功能超时并增加它的内存。

+0

嘿@mostafazh感谢您的好评!我的一个麻烦是用户一次上传多张图片。一次最多25个。在这两个例子中,它看起来像是它的一个旋转图像:'fixed.jpg'和'IMG_0001.jpg'。这将如何处理多个图像?非常感谢! – AndrewLeonardi

+0

您需要为每个图像做。也可能会“幻想”并创建一个AWS Lambda函数,该函数将侦听上传到S3的所有图像,并使Lambda函数自动旋转图像。Lambda的一个好处是它们并行执行,并且会保持您的请求不变将文件上传到S3)。关于AWS Lambda的更多信息http://docs.aws.amazon.com/lambda/latest/dg/lambda-introduction.html – mostafazh

+0

感谢您发送过来!任何机会,您可以更新您的答案显示一个如何可能做的例子?:) – AndrewLeonardi