web-dev-qa-db-ja.com

アップロード時の画像の向きが間違っている-AmazonS3

ユーザーがMulter-S3を使用してAmazon-S3に直接複数の画像をアップロードして表示できるようにしていますループを介してフロントエンドにあるこれらの画像。すべてが完璧に機能します。

ただし、画像がモバイル経由でアップロードされた場合(iPhoneまたはAndroidで撮影された画像)、モバイルでは向きが正しくなりますが、デスクトップでは向きが正しくありません。大きな問題。

これは、私が信じている画像[〜#〜] exif [〜#〜]データによるものです。

ImageMagickやKrakenJSのようです https://kraken.io/docs/storage-s それを解決する方法かもしれませんが、私の人生では、どちらの方法でも実装する方法を理解できません。以下の画像をアップロードして表示しています。

画像を自動向きにするには、以下のコードをどのように変更しますか?注:複数の画像で機能する必要があります

助けてくれてありがとう!

ユーザーが一度に複数の画像を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>
10
AndrewLeonardi

問題は、iOSがこの動作を引き起こす画像のEXIFメタデータを設定することです。 EXIFメタデータを読み取り、画像を回転できるライブラリを使用できます。

jpeg-autorotatehttps://github.com/johansatge/jpeg-autorotate )はvery単純なlibであり、very素晴らしいドキュメントがあります(チェックしてください)。

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回転メタデータを持ついくつかのサンプル画像を見つけることができます

AWSLambda関数として変換

// 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の関数ログもチェックアウトしてください。デバッグがはるかに簡単になります。タイムアウトが発生した場合は、関数のタイムアウトを増やし、メモリを増やします。

13
mostafazh