Loopback-component-storage:如何在上传到Amazon S3之前将图像转换为缩略图

时间:2015-09-21 21:02:56

标签: node.js express amazon-s3 loopbackjs strongloop

我正在使用环回组件存储将图片上传到服务器。

我想将通过服务器上传的每张图片转换为缩略图视图并将其保存到容器中。 最初我使用本地文件存储来存储文件,一切正常。

在文件存储空间中,我使用" quickthumb" 将图像转换为缩略图,然后将原始图像和缩略图图像保存到容器中。

但现在我想使用 amazon S3 存储我的图像以及环回组件存储。通过遵循文档,我可以轻松地将图像上传到亚马逊S3桶。但我无法弄清如何将图像调整为缩略图视图,并在Amazon S3服务器上存储不同版本的图像以及原始图像。

以下是我在使用文件存储实现时所做的工作。

现在将图片转换为缩略图尺寸

使用quickthumb

以下是我如何使用环回。

  

公共/模型/ container.js

module.exports = function(Container) {

    var qt = require('quickthumb');

    Container.afterRemote('upload', function(ctx, res, next) {

        var file = res.result.files.file[0];
        var file_path = "./server/storage/" + file.container + "/" + file.name;
        var file_thumb_path = "./server/storage/" + file.container + "/thumb/" + file.name;

        qt.convert({
            src: file_path,
            dst: file_thumb_path,
            width: 100
        }, function (err, path) {

        });

        next();
    });

};

但是现在要在将图像上传到S3服务器之前实现调整大小,我需要一些像express这样的req.files.image语法,但这在环回中是不可能的? 请帮忙。

3 个答案:

答案 0 :(得分:5)

你可以完成你正在尝试的东西,但它需要三个步骤。

首先,使用loopback-component-storage在本地上传文件。一旦你有它,你可以根据自己的喜好创建尽可能多的图像调整。但是你需要给图像一些独特的名称以避免碰撞。

其次,使用AWS Node SDK将这些新图像推送到S3存储桶。

最后,删除要自行清理的本地文件。

非常简单。看看我把这个问题放在一起来解决这些问题:

https://github.com/dashby3000/recipe-s3-image-uploader

干杯!

丹尼斯

答案 1 :(得分:2)

感谢名单。 @Dennis回答。 我发现自己也是其他方式而且我发布了它。

  

Container.js

    var fs = require('fs');
    //Formidable to modify the form obtained as requests.
    var IncomingForm = require('formidable');
    //Imager for sending and modifying image to amazon
    var Imager = require('imager');

    Container.beforeRemote('upload', function(ctx,  modelInstance, next){
       var app       = Container.app;
       var container = ctx.req.params.container;
       //IF u have large image then. use this to avoid timeout..    
       ctx.req.connection.setTimeout(16000);

       //Checking if the container name is valid or not..
       var Customer = app.models.Customer;
       //http://apidocs.strongloop.com/loopback/#persistedmodel-exists
       //Now manually uploading to the provider and first converting the file to the thumbnail..
       upload(app, ctx.req, ctx.res, function(err, data){
         console.log("Image loaded successfully..");
       });                      

    });//beforeRemote








    //For handling the upload 
    var upload = function(app, req, res, options, cb) {
        var storageService =  app.dataSources.presImage.connector;
        if (!cb && 'function' === typeof options) {
             cb = options;
             options = {};
        }
        if (storageService.getFilename && !options.getFilename) {
           options.getFilename = storageService.getFilename;
        }
        if (storageService.acl && !options.acl) {
           options.acl = storageService.acl;
        }
        if (storageService.allowedContentTypes && !options.allowedContentTypes) {
           options.allowedContentTypes = storageService.allowedContentTypes;
        }
        if (storageService.maxFileSize && !options.maxFileSize) {
           options.maxFileSize = storageService.maxFileSize;
        }
        return handler(app, storageService.client, req, res, options, cb);
    }


   //Using handler for form parsing.. 
   var handler = function (app, provider, req, res, options, cb) {
        if (!cb && 'function' === typeof options) {
        cb = options;
        options = {};
        }

        if (!options.maxFileSize) {
        options.maxFileSize = defaultOptions.maxFileSize;
        }

        var form = new IncomingForm(options);

        var fields = {};
        var files = [];


          form
            .on('field', function(field, value) {
              fields[field] = value;
            })
            .on('file', function(field, file) {
              //Now upload the file to the amazon server.. 
              uploadToCloud(app,  fields.container, res, cb);
            })
            .on('end', function(name, file) {
                console.log("END-> File fetched from user phone.\n");
            });

          form.parse(req);
    }





   var uploadToCloud = function(app,  container, res, callback ){
      var fileName, extension;
      var time = new Date();
      time = time.getTime();
      fileName = '' + container + '_' + time;

      imagerConfig = {
         variants: {
            items: {
              rename: function (filename) {
                 return fileName + "." + extension;
              },

              resize: {
                 thumb: "200x200",
                 original: "100%"
              }
          }
       },

      storage: {
        S3: {
          key: 'AMAZON KEY',
          secret: 'AMAZON SECRET',
          bucket: 'YOUR BUCKET NAME HERE',
          storageClass: 'REDUCED_REDUNDANCY',
          secure: false
        }
      },
      debug: true
    }

    CHECK IF FILE IS IMAGE ONLY..
    var pattern = /^image\/(.+)$/;
    extension = pattern.exec(path.type);
    try{
        if(extension.length){
             extension = extension[1];
        }else{
             throw "Error. Only image type file is permitted";
        }   
      }catch(err){
           throw "Error getting extension of file..";
      }


      if(!extension || extension == 'jpeg'){
           extension = "jpg";   
      }

      imager = new Imager(imagerConfig, 'S3') // or 'S3' for amazon
      imager.upload([path], function (err, cdnUri, files) {
           // do your stuff
           if(err) throw err; 
           console.log("Successfully saved to the amazon server..");
           var fileArr = [];
           for(var i=0; i < files.length; i++){
                //Preparing the order object..
                fileArr.push({
                    name: files[i],
                    container: container
                }); 
            }

            //Sending the result fast..
            //Dont wait for image to get upload..
            res.send({
               result:{
                  files:{
                    file:fileArr
                  }
               } 
            }); //res.status  
            callback();
            //Now deleting the original file here...path is "os.tmp()"

       }, 'items');

   }//uploadToCloud..
  

Datasource.json

{
  "db": {
    "host": "",
    "port": 0,
    "database": "",
    "password": "",
    "name": "db",
    "connector": "memory",
    "user": ""
  },
  "Image": {
    "name": "Image",
    "connector": "loopback-component-storage",
    "provider": "amazon",
    "key": "YOUR AMAZON KEY",
    "keyId": "YOUR AMAZON KEY ID",
    "maxFileSize": "15728640"
  }
}

答案 2 :(得分:0)

您是否检查过Strongloop挂钩https://docs.strongloop.com/display/public/LB/Adding+logic+to+models?您可以在调用存储组件

之前尝试创建Hook