2016-02-21 43 views
2

我目前正在爲我的用戶實施文件/圖像上傳服務。我想在上傳到我的s3存儲區之前轉換這些圖像(調整大小/優化)。使用NodeJS Multer轉換上傳

目前我在做什麼:我前端使用多形式的(我認爲實際的實現並不重要這裏..)和我的後端的multermulter-s3包。

在這裏,我的實施剝離了重要的部分。

// SETUP 
var multer = require('multer'); 
var s3 = require('multer-s3'); 
var storage = s3({ 
    dirname: 'user/uploads', 
    bucket: auth.aws.s3.bucket, 
    secretAccessKey: auth.aws.s3.secretAccessKey, 
    accessKeyId: auth.aws.s3.accessKeyId, 
    region: auth.aws.s3.region, 
    filename: function (req, file, cb) { 
     cb(null, Date.now()); 
    } 
}); 
var upload = multer({storage: storage}).single('img'); 

// ROUTE 
module.exports = Router() 
    .post('/', function (req, res, next) { 
     upload(req, res, function (err) { 
      if (err) { 
       return res.status(401).json({err: '...'}); 
      } 
      return res.json({err:null,url: '..'}); 
     }); 
    }); 

我想要做的是:在上傳圖像之前轉換圖像。我不確定是否需要在這裏使用multer/busboy,或者我可以用NodeJS來做(因此我也標記了NodeJS並表達了它)。

所以我的問題是:我可以在哪裏攔截上傳並將其上傳到我的S3存儲桶之前進行轉換?

+0

嗯,你可以在一些臨時文件夾中保存文件上傳到S3之前?如果您不想保存文件,您可以在內存中執行此操作,這取決於圖像的大小,但此方法不適合較大的文件。 –

+0

@RistoNovik我很可能可以做到這一點。但是這聽起來非常昂貴/不方便。 – Brettetete

+0

您可以在將其發送到後端之前轉換前端上的圖像。 –

回答

2

不知道你是否仍在尋找答案,但我有同樣的問題。我決定延長multer-s3包。

我已經打開了original repository的拉取請求,但現在,您可以使用my fork

這裏有一個如何使用擴展版本的例子:

var upload = multer({ 
    storage: multerS3({ 
     s3: s3, 
     bucket: 'some-bucket', 
     shouldTransform: function (req, file, cb) { 
     cb(null, /^image/i.test(file.mimetype)) 
     }, 
     transforms: [{ 
     id: 'original', 
     key: function (req, file, cb) { 
      cb(null, 'image-original.jpg') 
     }, 
     transform: function (req, file, cb) { 
      cb(null, sharp().jpg()) 
     } 
     }, { 
     id: 'thumbnail', 
     key: function (req, file, cb) { 
      cb(null, 'image-thumbnail.jpg') 
     }, 
     transform: function (req, file, cb) { 
      cb(null, sharp().resize(100, 100).jpg()) 
     } 
     }] 
    }) 
    }) 

編輯:我叉現在也通過NPM提供的名稱multer-s3-transform下。

0

我試過使用@ ItsGreg的fork,但無法讓它正常工作。我設法得到這種行爲採用multer-s3標準配置工作,和我的文件上傳端點內,即

app.post('/files/upload', upload.single('file'), (req, res) => {...})

我檢索使用request文件,並通過緩衝區sharp。下面的工作(並假設您正在使用~/.aws/credentials):

let request = require('request').defaults({ encoding: null }); 
    let dataURI = `https://s3.amazonaws.com/${process.env.AWS_S3_BUCKET}/${image.defaultUrl}`; 
    request.get(dataURI, function (error, response, body) { 
     if (! error && response.statusCode === 200) { 
      let buffer = new Buffer(body); 
      const sizes = ['thumbnail', 'medium', 'large']; 
      sizes.forEach(size => { 
       sharp(buffer) 
        .resize(image.sizes[size]) 
        .toBuffer() 
        .then(data => { 

         // Upload the resized image Buffer to AWS S3. 
         let params = { 
          Body: data, 
          Bucket: process.env.AWS_S3_BUCKET, 
          Key: `${image.filePath}${image.names[size]}`, 
          ServerSideEncryption: "AES256", 
         }; 

         s3.putObject(params, (err, data) => { 
          if (err) console.log(err, err.stack); // an error occurred 
          else console.log(data);   // successful response 
         }); 
        }) 
      }) 
     } 
    }); 
+0

拍點!我相應地更新了我的答案。 – andrewhl