AWS S3 实时图片Resize & 添加水印 手把手教学
需求
近期OSS从阿里云迁移到了AWS S3,发现图片的各种处理效果都失效了,导致用户在APP加载商品列表比较缓慢。所以希望能够让用户在列表访问的是缩略图。
阿里云的图片只需要简单在路径上加参数即可实现resize,而AWS没有提供类似实现,只能采用其他方案。
经过调研发现,CloudFront + API Gateway + Lambda的实现能满足需求。使用Gateway 拦截用户请求,调用Lambda 解析请求参数并生成相应尺寸的图片提供给用户,CloudFront 作为缓存。
整体架构
流程描述:
- 用户通过CloudFront 请求Resized 尺寸的图片,如果图片存在,直接返回
- CloudFront 从S3 Bucket 请求资源;
- 请求尺寸的图片不存在,浏览器将被重定向(307)到API Gateway 端点(存储桶静态网站托管中配置)
- API Gateway 触发Lambda 函数
- Lambda 函数从S3 存储同下载原始图片,调整大小后,将图片上传回存储桶
- API Gateway 重定向(301) 到新创建的CloudFront URL
操作步骤
权限策略
- IAM -> 策略 -> 创建策略 -> 按下图指定权限 -> 下一步填写名称和描述创建即可
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*"
},
{
"Effect": "Allow",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::YOUR_BUCKET_NAME/*"
}]
}
- IAM -> 角色 -> 创建角色
Lambda
- Lambda -> 函数 -> 创建函数
- 代码是基于nodejs18,这里要注意版本选择
- 角色选择上面创建的角色
API Gateway
- API Gateway -> API -> 创建API
- REST API -> 构建
-
配置资源
- 创建方法(Lambda函数选择上面创建的函数)
- 创建资源
- 编辑集成
- 部署API
- 前往阶段列表,编辑第四步新建的阶段
- 编辑成功后,复制该页面的URL, 下一步配置要用
- 创建方法(Lambda函数选择上面创建的函数)
存储桶静态网站托管
- S3 -> 存储桶 -> 点击目标存储桶 -> 属性
-
页面拉到底部 -> 静态网站托管 -> 编辑(HostName填你上面复制的链接的域名)
[ { "Condition": { "HttpErrorCodeReturnedEquals": "404" }, "Redirect": { "HostName": "c7xxxx.execute-api.ap-southeast-2.amazonaws.com", "HttpRedirectCode": "307", "Protocol": "https", "ReplaceKeyPrefixWith": "image?path=" } } ]
- 保存成功后,会得到终端节点,注意该节点链接是http,后续测试访问缩略图链接将会访问这个链接(先以http://test.s3-website-ap-southeast-2.amazonaws.com为例,下面将用该链接)
上传代码
- Lambda -> 函数 -> 目标函数
- 代码 -> 上传 zip文件
- 常规配置
- 配置 -> 环境变量 -> 编辑(URL填静态网站托管的地址)
- 以上配置后就可以访问图片了,例如你bucket的图片路径为 image/test.jpg,你可以直接访问 http://test.s3-website-ap-southeast-2.amazonaws.com/750xAUTO/images/test.jpg
注:750xAUTO可以修改为想要的尺寸,但由于我的水印图片是200x56, 我将最小尺寸设置为250x100, 小于该尺寸会加水印失败
CloudFront
- CloudFront -> 分配 -> 创建分配
- 创建好之后需要等一会才能生效
- 假设分配的域名为 https://dzupxxx.cloudfront.net,则图片访问路径为 https://dzupxxx.cloudfront.net/750xAUTO/images/test.jpg
自定义功能
- 水印图片需要替换成你们自身的水印图
- 关键代码位于zip文件的index.js,用了Sharp库来处理图片,目前只实现了Resize和加水印,如有需要,可根据Sharp文档定制其他功能。
总结
今天我们学习了如何使用 CloudFront + API Gateway + Lambda 来实现图片处理及访问。我们可以按照自己需求去灵活修改代码上传到Lambda,但要注意图片的处理时间,如果是比较复杂的图片处理,则需要修改Lambda配置的超时时间和内存。
而且Lambda支持多种编程语言,包括Node.js、Python、Java、Go、Ruby、.NET Core等,对开发者比较友好。
Tags
Lambda
CloudFront