Skip to content

Instantly share code, notes, and snippets.

@eyelove
Forked from devhaks/lambda_resizingImage.js
Last active June 23, 2020 08:10
Show Gist options
  • Save eyelove/f6804769bd1ac7137ecff03507d519ff to your computer and use it in GitHub Desktop.
Save eyelove/f6804769bd1ac7137ecff03507d519ff to your computer and use it in GitHub Desktop.
이미지 리사이징 람다 함수
'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);
};
@eyelove
Copy link
Author

eyelove commented Jun 23, 2020

s3 파일을 리자이징 하는 방식에서 원격지 파일을 다운받아 리자이즈 되도록 기능 개선

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment