Skip to content

Instantly share code, notes, and snippets.

@mango7j
Created October 7, 2019 06:16
Show Gist options
  • Save mango7j/3d6ff7246b6aa755181c885a5657144c to your computer and use it in GitHub Desktop.
Save mango7j/3d6ff7246b6aa755181c885a5657144c to your computer and use it in GitHub Desktop.
resize-image lambda@edge function
'use strict';
const querystring = require('querystring');
const AWS = require('aws-sdk');
const S3 = new AWS.S3({
signatureVersion: 'v4',
});
const Sharp = require('sharp');
const BUCKET = 'bucket';
const BUCKET_DEV = 'bucket_dev';
// original image path: /{id}/{filename}
// resized image path: /{width}x{height}/{id}/{filename}
const parse = path => {
let key = path.substring(1);
let match = key.match(/(\d*)x(\d*)\/(.*)/);
if (!match) {
return null;
}
let width = parseInt(match[1], 10);
let height = parseInt(match[2], 10);
let originalKey = match[3];
let ext = originalKey.substring(originalKey.lastIndexOf('.') + 1)
let format = ext == 'jpg' ? 'jpeg' : ext;
return {
key, format, originalKey,
width: width ? width : 0,
height: height ? height : 0,
}
}
const resize = async (srcBuff, w, h, format) => {
// TODO resize options
return await Sharp(srcBuff)
.resize(w)
.toFormat(format)
.toBuffer();
}
exports.handler = async (event, context) => {
let response = event.Records[0].cf.response;
//console.log(`event: ${JSON.stringify(event.Records[0].cf)}`);
// check if image is not present
if (response.status == 404) {
let request = event.Records[0].cf.request;
let path = request.uri;
// parse data
let data = parse(path);
// if there is no dimension attribute, just pass the response TODO
if (!data || (data.width == 0 && data.height == 0)) {
return response;
}
try {
// get the source image file
let srcImage = await S3.getObject({
Bucket: BUCKET_DEV,
Key: data.originalKey
}).promise();
// resize
let resized = await resize(
srcImage.Body, data.width, data.height, data.format);
// save the resized object to S3 bucket
await S3.putObject({
Body: resized,
Bucket: BUCKET_DEV,
ContentType: 'image/' + data.format,
CacheControl: 'max-age=31536000',
Key: data.key,
StorageClass: 'STANDARD'
}).promise();
// generate a binary response with resized image
response.status = 200;
response.body = resized.toString('base64');
response.bodyEncoding = 'base64';
response.headers['content-type'] = [{ key: 'Content-Type', value: 'image/' + data.format }];
return response;
} catch (err) {
console.log('error occurs while resizing image.', err);
}
}
else {
// allow the response to pass through
return response;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment