如何在本地将图像上传到S3存储桶并自动生成缩略图?

时间:2019-12-17 15:38:29

标签: node.js amazon-s3

晚上好

我有这个任务。我必须使用Node JS将图像上传到S3存储桶,并在旅途中而不是通过使用lambda触发器来生成缩略图。一切都应在我的本地计算机终端(或)在本地服务器(邮递员)中完成。我尝试了这段代码。

const fs = require('fs');

const ACESS_ID = 'A**********KV';
const SECRET_ID = 'G***********0';
const BUCKET_NAME = 'node-image-bucket';

// Initializing s3 interface
const s3 = new AWS.S3({
    accessKeyId: ACESS_ID,
    secretAccessKey: SECRET_ID,
});

// File reading function to S3
const uploadFile = (fileName) => {
    // Read content from the file
    const fileContent = fs.readFileSync(fileName);

    // Setting up S3 upload parameters
    const params = {
        Bucket: BUCKET_NAME,
        Key: 'scene2.jpg',
        Body: fileContent
    };

    // Uploading files to the bucket
    s3.upload(params, function(err, data){
        if(err){
            throw err;
        }
        console.log(data);

        console.log(`File uploaded Successfully. ${data.Location}`);
    });
};


uploadFile('./images/bg-hd.jpg');

上面的代码可以在单个图像上正常工作,问题是每次我将文件上传到S3存储桶时,我都需要更改S3 params键字符串值

我想一次上传多张图片并创建一个性能缓冲区,它应该在同一存储桶中的不同文件夹中自动创建缩略图。

任何人都可以帮助我!请任何帮助表示感谢!

2 个答案:

答案 0 :(得分:2)

您无法通过 one s3操作上传多个文件,但是可以在上传https://www.npmjs.com/package/sharp之前使用Sharp模块 在调用s3 api之前调整图像大小。

import * as sharp from 'sharp';

async function resize(buffer , width, height) {
  return sharp(buffer).resize(width, height).toBuffer();
}

const thumbnailWidthSize = 200;
const thumbnailWidthHeight = 200;
const thumbnailImage = await resize(fileContent, thumbnailWidthSize, thumbnailWidthHeight)

然后,您可以重复使用当前的上传功能,并使用不同的键将其调整为所需大小的图像,然后将这些调用包装在promise.all周围,以确保在任何上传失败时操作都会失败。

await promise.all([ 
  s3upload(image, imageKey), 
  s3upload(thumbnailImage, thumbnailImageKey) 
])

答案 1 :(得分:2)

所以,您的问题分为两部分-

  • 在将图像上传到s3存储桶时将其转换为缩略图-

    您可以使用thumbd npm模块并创建一个thumbd服务器。

    Thumbd是基于Node.js,SQS,S3和ImageMagick构建的图像缩略图服务器。

    拇指服务器的要求- Thumbd需要设置以下环境变量:

    • AWS_KEY 用于您的AWS账户的密钥(IAM用户必须有权访问适当的SQS和S3资源)。
    • AWS_SECRET AWS密钥。
    • BUCKET (桶),以从中下载原始图像。缩略图也将放置在此存储桶中
    • AWS_REGION 存储桶的AWS区域。默认值为:us-east-1。
    • CONVERT_COMMAND ImageMagick转换命令。默认为转换。
    • REQUEST_TIMEOUT (以毫秒为单位),然后中止远程请求。默认值为15000。
    • S3_ACL 要在上传的图片上设置的ACL。必须是私有或公开读取的内容之一。默认为私人。
    • S3_STORAGE_CLASS 上载图像的存储类。必须为STANDARD或REDUCED_REDUNDANCY。默认为标准。
    • SQS_QUEUE 队列名称以侦听图像缩略图。
    • 在本地运行时,我将这些环境变量设置为.env文件,并使用pm2 / forever / foreman执行thumbd。

    设置-

    • apt-get install imagemagick
    • npm install thumbd -g
    • 缩略图安装
    • thumbd start //作为服务器运行

拇指服务器启动并运行后,请参考以下代码在将图像上传到s3存储桶时将其更改为缩略图。

    var aws = require('aws-sdk');
    var url = require("url");
    var awsS3Config = { 
        accessKeyId: ACESS_ID,
        secretAccessKey: SECRET_ID,
        region: 'us-west-2' 
        }


    var BUCKET_NAME = 'node-image-bucket';
    var sourceImageDirectory = "/tmp/"
    var imageUploadDir = "/thumbnails/"
    var imageName = 'image.jpg'
    var uploadImageName = 'image.jpg'

    aws.config.update(awsS3Config);
    var s3 = new aws.S3();

    var Client = require('thumbd').Client,
        client = new Client({
            awsKey: awsS3Config.accessKeyId,
            awsSecret: awsS3Config.secretAccessKey,
            s3Bucket: BUCKET_NAME,
            sqsQueue: 'ThumbnailCreator',
            awsRegion: awsS3Config.region,
            s3Acl: 'public-read'
        });

    export function uploadAndResize(sourceImageDirectory, imageName, imageUploadDir, uploadImageName) {

       return new Promise((resolve, reject)=>{

            client.upload(sourceImageDirectory + imageName, imageUploadDir + uploadImageName, function(err) {

            if (err) {

                reject(err);
            } else {
                client.thumbnail(imageUploadDir + uploadImageName, [{
                    "suffix": "medium",
                    "width": 360,
                    "height": 360,
                    "background": "white",
                    "strategy": "%(command)s %(localPaths[0])s -resize %(width)sX%(height)s^ -gravity north -extent %(width)sX%(height)s  %(convertedPath)s"
                }, {
                    "suffix": "thumb",
                    "width": 100,
                    "height": 100,
                    "background": "white",
                    "strategy": "%(command)s %(localPaths[0])s -resize %(width)sX%(height)s^ -gravity north -extent %(width)sX%(height)s  %(convertedPath)s"
                }], {
                    //notify: 'https://callback.example.com'
                });
                var response = {};

                //https://s3-ap-us-west-2.amazonaws.com/node-image-bucket/1/5825c7d0-127f-4dac-b802-ca24efba2bcd-original.jpeg

                response.url = 'https://s3-' + awsS3Config.region + '.amazonaws.com/' + BUCKET_NAME + '/' + imageUploadDir;
                response.uploadImageName = uploadImageName;
                response.sourceImageName = imageName;

                 resolve(response);

                }

            })
       })
  1. 第二,您想上传多个图像而不更改字符串-

    遍历以下方法查找本地路径中的所有文件,一切顺利。

export function uploadFiles(localPath, localFileName, fileUploadDir, uploadFileName) {

  return new Promise((resolve, reject) => {

    fs.readFile(localPath + localFileName, function (err, file) {
      if (err) {

        defered.reject(err);
      }

      var params = {
        ACL: 'public-read',
        Bucket: BUCKET_NAME,
        Key: uploadFileName,
        Body: file
      };

      s3.upload(params, function (err, data) {

        fs.unlink(localPath + localFileName, function (err) {

          if (err) {
            reject(err);
          } else {
            resolve(data)
          }
        });
      });

    });

  })

}