먼저 기본 내용은 아래 AWS Blog를 통해 확인하자.
Resizing Images with Amazon CloudFront & Lambda@Edge | AWS CDN Blog | Amazon Web Services
Do you have lots of images that need to be modified before delivery? No problem with Amazon CloudFront and Lambda@Edge. Read more on how you can use our services to modify image dimensions, apply watermarks, or optimize formats based on browser support all
aws.amazon.com
중요 키워드는 Lambda Edge 그리고 Origin Response를 활용하는 것이다. 이 워크플로우는 기타 여러 블로그에 기재되어 있다.
AWS Lambda@edge로 실시간 이미지 리사이징(updated)
AWS Lambda@edge(CloudFront)로 실시간 이미지 리사이징 기능을 구현합니다. Cloud 9으로 람다 함수를 작성하고 CloudWatch로 로그를 확인합니다.
heropy.blog
내 경우 원본이 S3가 아닌 IDC 혹은 EC2의 경우 axios를 활용해 이미지 데이터를 다운 받은 후 sharp를 통해 이미지 리사이징을 구현했다. AWS Blog의 코드를 참고 했으며 조금 수정했다.
[index.js] v.10.18.0
'use strict';
const querystring = require('querystring'); // Don't install.
const AWS = require('aws-sdk'); // Don't install.
const sharp = require('sharp');
const axios = require('axios');
const fs = require('fs');
exports.handler = async(event, context, callback) => {
let origin = "http://52.78.189.144" //Custom Origin URL
console.log(event.Records[0].cf)
const { request, response } = event.Records[0].cf
console.log(`request: ${request}`)
console.log(`response: ${response}`)
const params = querystring.parse(request.querystring)
if (!params.w && !params.h) {
return callback(null, response)
}
const { uri } = request
const [, imageName, extension] = uri.match(/\/?(.*)\.(.*)/)
let width
let height
let format
width = parseInt(params.w, 10) ? parseInt(params.w, 10) : null;
height = parseInt(params.h, 10) ? parseInt(params.h, 10) : null;
format = params.f ? params.f : extension;
format = format === 'jpg' ? 'jpeg' : format
console.log(`format: ${format}`)
console.log(`parmas: ${JSON.stringify(params)}`) // Cannot convert object to primitive value.
console.log(`name: ${imageName}.${extension}`) // Favicon error, if name is `favicon.ico`.
console.log(origin + '/' + imageName + '.' + extension)
const data = await originCheck(origin + '/' + imageName + '.' + extension)
const resizedImage = await resize(data, width, height)
const resizedImageByteLength = Buffer.byteLength(resizedImage, 'base64');
console.log('byteLength: ', resizedImageByteLength);
if (resizedImageByteLength >= 1 * 1024 * 1024) {
return callback(null, response);
}
response.status = 200;
response.body = resizedImage.toString('base64');
response.bodyEncoding = 'base64';
response.headers['content-type'] = [{
key: 'Content-Type',
value: `image/${format}`
}];
return callback(null, response);
}
const originCheck = async(uri) => {
try {
const body = await axios.get(uri, { responseType: "arraybuffer" })
return body.data
}
catch (err) {
console.log(`axios err: ${err}`)
}
}
const resize = async(data, width, height) => {
try {
// const result = await sharp(data).resize(200, 100, { fit: "fill" }).toFile("./200x500_outside.jpg");
const result = await sharp(data).resize(width, height, { fit: "fill" }).toFormat('jpeg').toBuffer()
return result
}
catch (err) {
console.log(`resize: ${err}`)
}
}
[package.json]
{
"name": "resize-image",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"aws-sdk": "^2.595.0",
"axios": "^0.19.0",
"base64-img": "^1.0.4",
"sharp": "^0.23.4"
}
}
결과
TEST URI: http://d3ois01c955xts.cloudfront.net/test.jpg
Thumnail URI: http://d3ois01c955xts.cloudfront.net/test.jpg?w=100&h=200
[github]
https://github.com/leedoing/imageResize-lambdaedge
람다 로깅 레벨은 아래와 같이 정의 가능
import logging
logger = logging.getLogger()
logger.setLevel(logging.ERROR)
'Compute > Lambda' 카테고리의 다른 글
AWS Lambda Edge 콜드스타트? (0) | 2021.10.12 |
---|---|
AWS Lambda@Edge Redirect / Add Custom Header (0) | 2021.10.08 |
AWS Lambda 활용 태깅 없는 EC2 Instance 정지 (0) | 2017.11.14 |
AWS Lambda 활용 EIP 변경 (0) | 2017.04.12 |
AWS Lambda를 이용하여 Security Group 자동 제어 (0) | 2016.10.21 |