【问题标题】:Loopback-component-storage: How to convert image to thumbnail before uploading to Amazon S3Loopback-component-storage:如何在上传到 Amazon S3 之前将图像转换为缩略图
【发布时间】:2015-12-18 16:51:51
【问题描述】:

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

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

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

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

这是我在使用文件存储实现它时所做的事情。

现在将其图像转换为缩略图大小

使用quickthumb

这是我如何将它与环回一起使用的。

common/models/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,但这在环回中是不可能的吗? 请帮忙。

【问题讨论】:

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


    【解决方案1】:

    谢谢。 @Dennis 回答。 我也发现了自己的其他方式,我正在发布它。

    容器.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..
    

    数据源.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"
      }
    }
    

    【讨论】:

    • @RobbinsGupta 我在服务器上有图像文件夹从那个文件夹我必须在亚马逊服务器上一张一张地上传图像。现在我能做什么?需要您的任何建议。
    【解决方案2】:

    您可以完成您正在尝试的事情,但这需要三个步骤。

    首先,使用 loopback-component-storage 将文件上传到本地。一旦你有了它,你可以根据需要对图像进行尽可能多的调整。但您会希望为图像指定某种唯一名称以避免冲突。

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

    最后,删除本地文件自己清理。

    这很简单。看看我为解决这些问题而整理的这个食谱:

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

    干杯!

    丹尼斯

    【讨论】:

      【解决方案3】:

      你检查过 Strongloop 钩子https://docs.strongloop.com/display/public/LB/Adding+logic+to+models 吗?您可以尝试在调用存储组件之前创建一个 Hooks

      【讨论】:

      • @Bethoven 我已经在使用远程挂钩。但是在将其转换为缩略图视图然后将其上传到亚马逊 s3 的情况下,它将无法以某种方式工作。为此,我需要一些明确的语法,例如req.files.image
      猜你喜欢
      • 2017-12-12
      • 2015-01-05
      • 2019-04-24
      • 2019-12-02
      • 1970-01-01
      • 2015-07-18
      • 2019-02-10
      • 2018-03-03
      • 2021-07-23
      相关资源
      最近更新 更多