Created
September 23, 2020 09:09
-
-
Save apotox/eb30bd770776114b81c2558fb612486e to your computer and use it in GitHub Desktop.
insert a watermark to any jpeg image pushed to an S3 bucket
This file contains 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
// dependencies | |
const AWS = require("aws-sdk"); | |
const util = require("util"); | |
const sharp = require("sharp"); | |
// get reference to S3 client | |
const s3 = new AWS.S3(); | |
exports.compressImage = async (event, context) => { | |
// Read options from the event parameter. | |
console.log( | |
"Reading options from event:\n", | |
util.inspect(event, { depth: 5 }) | |
); | |
const srcBucket = event.Records[0].s3.bucket.name; | |
// Object key may have spaces or unicode non-ASCII characters. | |
const srcKey = decodeURIComponent( | |
event.Records[0].s3.object.key.replace(/\+/g, " ") | |
); | |
//this lambda function will rename the image file by adding | |
//a custom prefix "resized" to avoid triggering a "loop" of events | |
//when it saved into the same bucket! | |
if(srcKey.indexOf("resized") > -1) return; | |
const dstKey = "resized-" + srcKey; // concatinate the prefix "resized" | |
// Infer the image type from the file suffix. | |
const typeMatch = srcKey.match(/\.([^.]*)$/); | |
if (!typeMatch) { | |
console.log("Could not determine the image type."); | |
return; | |
} | |
// Check that the image type is supported | |
const imageType = typeMatch[1].toLowerCase(); | |
if (imageType != "jpeg" && imageType != "jpg") { | |
console.log(`Unsupported image type: ${imageType}`); | |
return; | |
} | |
// Download the image from the S3 source bucket. | |
try { | |
const params = { | |
Bucket: srcBucket, | |
Key: srcKey, | |
}; | |
var origimage = await s3.getObject(params).promise(); | |
} catch (error) { | |
console.log(error); | |
return; | |
} | |
// set thumbnail width. Resize will set the height automatically to maintain aspect ratio. | |
const width = 480; | |
try { | |
//using SVG as a text Watermark | |
//you can define an envirenment variable called WATERMARK_TEXT | |
//the font-familly files must be added to the lambda function fonts by | |
//defining another env variable contains the font dir path like "FONTCONFIG_PATH":"./MyFont" | |
const textedSVG = Buffer.from(`<svg | |
xmlns="http://www.w3.org/2000/svg" | |
xml:lang="en" | |
height="40" | |
width="200"> | |
<text | |
font-family="MyFont" | |
font-style="italic" | |
x="0" y="20" font-size="16" fill="#fff"> | |
${process.env.WATERMARK_TEXT} | |
</text></svg>`); | |
let imgDst = sharp(origimage.Body); | |
var buffer = await imgDst | |
.composite([ | |
{ | |
input: textedSVG, | |
gravity: "southeast", | |
}, | |
]) | |
// Use the Sharp module to resize the image and save in a buffer. | |
.resize(width) | |
.jpeg({ quality: 70 }) //decrease the image quality | |
.toBuffer(); | |
} catch (error) { | |
console.log("add watermark to the resized image!", error); | |
return; | |
} | |
// Upload the thumbnail image to the destination bucket | |
try { | |
const destparams = { | |
Bucket: srcBucket, | |
Key: dstKey, | |
Body: buffer, | |
ContentType: "image/jpeg", | |
}; | |
const putResult = await s3.putObject(destparams).promise(); | |
} catch (error) { | |
console.log("putObject",error); | |
return; | |
} | |
//finally! | |
console.log( | |
"Successfully resized " + | |
srcBucket + | |
"/" + | |
srcKey + | |
" and uploaded with" + | |
dstKey | |
); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
read more here