Skip to content

Instantly share code, notes, and snippets.

@apotox
Created September 23, 2020 09:09
Show Gist options
  • Save apotox/eb30bd770776114b81c2558fb612486e to your computer and use it in GitHub Desktop.
Save apotox/eb30bd770776114b81c2558fb612486e to your computer and use it in GitHub Desktop.
insert a watermark to any jpeg image pushed to an S3 bucket
// 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
);
};
@apotox
Copy link
Author

apotox commented Apr 11, 2022

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