-
-
Save eyelove/f6804769bd1ac7137ecff03507d519ff to your computer and use it in GitHub Desktop.
이미지 리사이징 람다 함수
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
const querystring = require('querystring'); // Don't install. | |
const axios = require('axios'); | |
// http://sharp.pixelplumbing.com/en/stable/api-resize/ | |
const Sharp = require('sharp'); | |
// Image types that can be handled by Sharp | |
const supportImageTypes = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg', 'tiff']; | |
exports.handler = async(event, context, callback) => { | |
const { request, response } = event.Records[0].cf; | |
// console.log('request:', request); | |
// console.log('response:', response); | |
// Parameters are w, h, f, q and indicate width, height, format and quality. | |
const { uri } = request; | |
const ObjectKey = decodeURIComponent(uri).substring(1); | |
const params = querystring.parse(request.querystring); | |
const { w, h, q, f } = params | |
/** | |
* ex) https://dilgv5hokpawv.cloudfront.net/dev/item.ssgcdn.com/53/02/00/item/0000000000253_i1_350.jpg?w=200&h=150&f=webp&q=90 | |
* - ObjectKey: 'dev/item.ssgcdn.com/53/02/00/item/0000000000253_i1_350.jpg' | |
* - w: '200' | |
* - h: '150' | |
* - f: 'webp' | |
* - q: '90' | |
*/ | |
// console.log('Object key:', ObjectKey); | |
const extension = uri.match(/\/?(.*)\.(.*)/)[2].toLowerCase(); | |
const width = parseInt(w, 10) || null; | |
const height = parseInt(h, 10) || null; | |
const quality = parseInt(q, 10) || 100; // Sharp는 이미지 포맷에 따라서 품질(quality)의 기본값이 다릅니다. | |
let format = (f || extension).toLowerCase(); // 요청포맷이 없을 경우 원본 포맷을 유지한다. | |
let resizedImage; | |
// 포맷 변환이 없는 GIF 포맷 요청은 원본 반환. | |
if (extension === 'gif' && !f) { | |
return callback(null, response); | |
} | |
// Init format. | |
format = format === 'jpg' ? 'jpeg' : format; | |
if (!supportImageTypes.some(type => type === extension )) { | |
responseHandler( | |
403, | |
'Forbidden', | |
'Unsupported image type', [{ | |
key: 'Content-Type', | |
value: 'text/plain' | |
}], | |
); | |
return callback(null, response); | |
} | |
// Verify For AWS CloudWatch. | |
// console.log(`parmas: ${JSON.stringify(params)}`); // Cannot convert object to primitive value. | |
const originImageBuffer = (await axios({ url: "http://" + ObjectKey, responseType: "arraybuffer" })).data; | |
// 크기 조절이 없는 경우 원본 반환. | |
if (!(w || h)) { | |
responseHandler( | |
200, | |
'OK', | |
originImageBuffer.toString('base64'), [{ | |
key: 'Content-Type', | |
value: `image/${format}` | |
}], | |
'base64' | |
); | |
return callback(null, response); | |
} | |
try { | |
resizedImage = await Sharp(originImageBuffer) | |
.resize(width, height, { | |
kernel: Sharp.kernel.nearest, | |
fit: 'contain', | |
position: 'centre', | |
background: { r: 255, g: 255, b: 255, alpha: 1 } | |
}) | |
.toFormat(format, { | |
quality | |
}) | |
.toBuffer(); | |
} | |
catch (error) { | |
responseHandler( | |
500, | |
'Internal Server Error', | |
'Fail to resize image.', [{ | |
key: 'Content-Type', | |
value: 'text/plain' | |
}], | |
); | |
return callback(null, response); | |
} | |
// 응답 이미지 용량이 1MB 이상일 경우 원본 반환. | |
if (Buffer.byteLength(resizedImage, 'base64') >= 1048576) { | |
return callback(null, response); | |
} | |
responseHandler( | |
200, | |
'OK', | |
resizedImage.toString('base64'), [{ | |
key: 'Content-Type', | |
value: `image/${format}` | |
}], | |
'base64' | |
); | |
/** | |
* @summary response 객체 수정을 위한 wrapping 함수 | |
*/ | |
function responseHandler(status, statusDescription, body, contentHeader, bodyEncoding) { | |
response.status = status; | |
response.statusDescription = statusDescription; | |
response.body = body; | |
response.headers['content-type'] = contentHeader; | |
if (bodyEncoding) { | |
response.bodyEncoding = bodyEncoding; | |
} | |
} | |
// console.log('Success resizing image'); | |
return callback(null, response); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
s3 파일을 리자이징 하는 방식에서 원격지 파일을 다운받아 리자이즈 되도록 기능 개선