图片上传至AWS S3时触发Lambda执行压缩图片,并将压缩后的图片上传至S3 bucket


【1】建S3 bucket

创建4个bucket:test-jtmm-sharp、test-jtmm-sharp-50x50、test-jtmm-sharp-100x100、test-jtmm-sharp-200x200

 

【2】安装并配置Amazon AWS CLI

https://docs.aws.amazon.com/zh_cn/cli/latest/userguide/cli-chap-install.html

https://docs.aws.amazon.com/zh_cn/cli/latest/userguide/cli-chap-configure.html

 

【3】安装Node.js环境(环境版本需要跟AWS Lambda版本一致)

$ curl -sL https://rpm.nodesource.com/setup_14.x | sudo bash

命令执行完后会显示如下:

 

 

 接着执行红色部分

$ sudo yum install -y nodejs

 

 

 看到Complete了。

# 看一下Node.js版本
$ node -v

 

【4】看一下将AWS S3和Lambda结合使用的教程

https://docs.aws.amazon.com/zh_cn/lambda/latest/dg/with-s3-example.html

 

【5】使用 npm 安装 Sharp 库。

对于 Linux,请使用以下命令。

$ npm install sharp

对于 macOS,请使用以下命令。 

$ npm install --arch=x64 --platform=linux --target=12.13.0  sharp

 

【6】将JS代码保存为index.js

// dependencies
const AWS = require('aws-sdk');
const util = require('util');
const sharp = require('sharp');

// get reference to S3 client
const s3 = new AWS.S3();

exports.handler = async (event, context, callback) => {
    
    console.log("11111111111111111111");

    // Read options from the event parameter.
    // console.log("Reading options from event:\n", util.inspect(event, {depth: 5}));
    const srcBucket = event.Records[0].s3.bucket.name;
    // Object key may have spaces or unicode non-ASCII characters.
    const srcKey    = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, " "));
    
    console.log("2222222222222222");
    
    // const dstBucket = srcBucket + "-resized";
    // const dstKey    = "resized-" + srcKey;

    // Infer the image type from the file suffix.
/*
    const typeMatch = srcKey.match(/\.([^.]*)$/);
    if (!typeMatch) {
        console.log("Could not determine the image type.");
        return;
    }
*/

    // Check that the image type is supported  
/*
    const imageType = typeMatch[1].toLowerCase();
    if (imageType != "jpg" && imageType != "png") {
        console.log(`Unsupported image type: ${imageType}`);
        return;
    }
*/

    // Download the image from the S3 source bucket. 
    var origimage;
    try {
        const params = {
            Bucket: srcBucket,
            Key: srcKey
        };
        origimage = await s3.getObject(params).promise();
    
    console.log("333333333333333333333");
    } catch (error) {
    
    console.log("444444444444444444444444");
        console.log("<<<::: error :::>>> at origimage = await s3.getObject(params).promise();");
        console.log(error);
        return;
    }  

    // set thumbnail width. Resize will set the height automatically to maintain aspect ratio.
    // const width  = 200;

    // Use the Sharp module to resize the image and save in a buffer.
    var buffer_x50;
    var buffer_x100;
    var buffer_x200;
    
    console.log("555555555555555555555");
    try { 
        buffer_x50 = await sharp(origimage.Body).resize(50,50).toBuffer();
    
    console.log("66666666666666666666666");
        buffer_x100 = await sharp(origimage.Body).resize(100,100).toBuffer();
    
    console.log("77777777777777777777777");
        buffer_x200 = await sharp(origimage.Body).resize(200,200).toBuffer();
    
    console.log("8888888888888888888888888888");
    } catch (error) {
    
    console.log("999999999999999999999999999");
        console.log(error);
        console.log("<<<::: error :::>>> at await sharp(origimage.Body).resize(*,*).toBuffer();");
        return;
    } 

    // Upload the thumbnail image to the destination bucket
    try {
    
    console.log("00000000000000000000000000000000000");
        const destparams_x50 = {
            Bucket: srcBucket + "-50x50",
            Key: srcKey,
            Body: buffer_x50,
            ContentType: "image"
        };
    
    console.log("aaaaaaaaaaaaaaaaaaaaaaa");
        const putResult_x50 = await s3.putObject(destparams_x50).promise(); 
    
    console.log("bbbbbbbbbbbbbbbbbbbbbbb");
    } catch (error) {
    
    console.log("cccccccccccccccccccccc");
        console.log(error);
        console.log("<<<::: error :::>>> at putObject buffer_x50");
        return;
    } 
    try {
    
    console.log("ddddddddddddddddddddd");
        const destparams_x100 = {
            Bucket: srcBucket + "-100x100",
            Key: srcKey,
            Body: buffer_x100,
            ContentType: "image"
        };
    
    console.log("eeeeeeeeeeeeeeeeeeeeee");
        const putResult_x100 = await s3.putObject(destparams_x100).promise(); 
    
    console.log("fffffffffffffffffffff");
    } catch (error) {
    
    console.log("ggggggggggggggggggggggggggggg");
        console.log(error);
        console.log("<<<::: error :::>>> at putObject buffer_x100");
        return;
    } 
    try {
    
    console.log("hhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
        const destparams_x200 = {
            Bucket: srcBucket + "-200x200",
            Key: srcKey,
            Body: buffer_x200,
            ContentType: "image"
        };
    
    console.log("iiiiiiiiiiiiiiiiiiiiiiiiii");
        const putResult_x200 = await s3.putObject(destparams_x200).promise(); 
    
    console.log("jjjjjjjjjjjjjjjjjjjjjjjjjjj");
    } catch (error) {
    
    console.log("kkkkkkkkkkkkkkkkkkkkkkk");
        console.log(error);
        console.log("<<<::: error :::>>> at putObject buffer_x200");
        return;
    } 
        
    console.log('$$$ <<< Successfully >>> $$$'); 
};

 

 

 

 

完成此步骤后,文件夹结构如下:

lambda-s3
┣━ index.js
┣━ /node_modules/sharp
┗━ /node_modules/...

 

【7】创建包含函数代码和依赖项的部署包。为 zip 命令设置 -r(递归)选项以压缩子文件夹。

$ zip -r function.zip .

 

【8】创建Lambda函数,使用Node.js 14.x环境,将上一步的function.zip包上传。

 

 

 

【9】创建一个IAM策略,并将此策略附于上一步创建Lambda函数时一同创建的角色。

策略明取为 test-jtmm-sharp---policy-0001 。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "logs:PutLogEvents",
                "logs:CreateLogGroup",
                "logs:CreateLogStream"
            ],
            "Resource": "arn:aws:logs:*:*:*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:PutObject"
            ],
            "Resource": "arn:aws:s3:::test-jtmm-sharp/*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:PutObject"
            ],
            "Resource": "arn:aws:s3:::test-jtmm-sharp-100x100/*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:PutObject"
            ],
            "Resource": "arn:aws:s3:::test-jtmm-sharp-200x200/*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:PutObject"
            ],
            "Resource": "arn:aws:s3:::test-jtmm-sharp-50x50/*"
        }
    ]
}         
        

 

 

【10】在IAM角色中找到步骤【8】中创建Lambda函数时同时创建的角色

 

 

将步骤【9】中创建的策略附加到此角色上,如下图所示:

 

 

【11】在test-jtmm-sharp这个bucket上创建一个通知,当有图片上传时,触发Lambda函数执行。

点击bucket的“属性”标签页

 

 

 

往下拉,找到“创建事件通知”按钮,并点击

 

 

随便取个事件名。

 

选中“所有对象创建事件”

 

 

 

拉倒最下面,选择刚才创建的Lambda函数,点击“保存更改”按钮。

 

 

 

【12】往test-jtmm-sharp上传一张图片,然后看一下其他bucket以及相关的日志组。

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM