Skip to content

Resizing Images and Adding Watermarks with AWS Lambda

Resizing Images and Adding Watermarks with AWS Lambda 2024

In this article, we’ll explore how to create an AWS Lambda function that automatically resizes images, adds a watermark, and converts the images to a specified format. This functionality can be particularly useful for blog posts, thumbnails for videos, and any other automated image processing tasks.

Watch the Video

To see this process in action, check out my YouTube channel, where I explain how this Lambda function works.

Resizing Images and Adding Watermarks with AWS Lambda

Prerequisites

Before we dive in, ensure you have the following:

  • An AWS account
  • Basic knowledge of AWS Lambda, S3 and IAM
  • An EC2 instance set up with Amazon Linux 2023 to build the Pillow layer – optional
  • S3 bucket for uploading images
  • IAM role with the necessary permissions for your Lambda function

Overview of the Process

To create an AWS Lambda function that automatically resizes images, adds a watermark, and converts the images to a specified format we will follow these main steps:

  1. Build a Lambda layer with the Pillow library, which allows us to manipulate images – optional
  2. Add code to resize images, add watermark and convert.
  3. Configure the function to trigger on S3 events when new images are uploaded.

1. Creating the Lambda Layer with Pillow

Pillow is not included by default in AWS Lambda, so we need to create a layer for it. There are two ways to do this:

– Option 1 – Use an existing ARN for the Pillow layer if available.
– Option 2 – Create your own layer following the steps below.

Steps to Create the Pillow Layer

Log in to your EC2 instance running Amazon Linux 2023 and execute the following commands:

# 1. Install essential build dependencies for compiling Python
sudo dnf install -y gcc openssl-devel bzip2-devel libffi-devel make zlib-devel

# 2. Download Python 3.12 source code
wget https://www.python.org/ftp/python/3.12.0/Python-3.12.0.tgz

# 3. Extract the downloaded Python tarball
tar xzf Python-3.12.0.tgz
cd Python-3.12.0

# 4. Configure and compile Python with zlib support enabled for AWS Lambda compatibility
./configure --enable-optimizations --with-zlib
make
sudo make altinstall

# 5. Download `get-pip.py` to manually install `pip` for Python 3.12
cd ~
curl -O https://bootstrap.pypa.io/get-pip.py

# 6. Install `pip` for Python 3.12
sudo /usr/local/bin/python3.12 get-pip.py

# Verify `pip` installation
/usr/local/bin/python3.12 -m pip --version

# 7. Create a virtual environment with Python 3.12
/usr/local/bin/python3.12 -m venv pillow-layer-env

# 8. Activate the virtual environment
source pillow-layer-env/bin/activate

# 9. Install Pillow in the virtual environment
pip install Pillow

# 10. Create the folder structure for AWS Lambda layer
mkdir -p python/lib/python3.12/site-packages

# 11. Copy the installed packages to the Lambda layer structure
cp -r pillow-layer-env/lib/python3.12/site-packages/* python/lib/python3.12/site-packages/

# 12. Compress the `python` folder into a ZIP file for Lambda layer deployment
zip -r pillow-layer.zip python

# You can now upload `pillow-layer.zip` to AWS Lambda as a layer

Uploading the Layer to AWS Lambda

Now that we have our pillow-layer.zip file, you can upload it to AWS Lambda:

  1. Go to the AWS Lambda console.
  2. Click on Layers in the left-hand menu.
  3. Click Create Layer.
  4. Upload your pillow-layer.zip file.
  5. Choose the Python version that matches your Lambda function.

Option 1: Adding the Layer through the AWS Lambda Console

  1. Go to the AWS Lambda console.
  2. Select the Lambda function to which you want to add the layer.
  3. Scroll down to the Layers section and click on Add a layer.
  4. Choose Custom layers from the options.
  5. From the Layer name dropdown, select the pillow-layer you created.
  6. Ensure you’ve selected the correct layer version and Python version that matches your Lambda function.
  7. Click Add to apply the layer to your Lambda function.

Option 2: Adding the Layer Using an ARN

  1. Go to the AWS Lambda console.
  2. Select the Lambda function to which you want to add the layer.
  3. In the Layers section, click on Add a layer.
  4. Select Specify an ARN.
  5. Paste the ARN of your layer in the text field. The ARN format typically looks like:
    codearn:aws:lambda:<region>:<account-id>:layer:<layer-name>:<version>
  6. Click Add to apply the layer to your Lambda function.

2. Example Code for the Lambda Function

Below is the code you’ll need to create the Lambda function that resizes images, adds a watermark, and saves the output with the specified format. You can modify this code according to your specific requirements.

import boto3
from PIL import Image, ImageDraw, ImageFont
import io
import os

s3 = boto3.client('s3')

def lambda_handler(event, context):
# Define output format (e.g., 'WEBP', 'JPEG', 'PNG'...)
output_format = 'WEBP'

bucket_name = event['Records'][0]['s3']['bucket']['name']
object_key = event['Records'][0]['s3']['object']['key']
print(bucket_name)
print(object_key)


if object_key.startswith('input/'):
s3_response = s3.get_object(Bucket=bucket_name, Key=object_key)
image_content = s3_response['Body'].read()

img = Image.open(io.BytesIO(image_content))

# Set watermark text
watermark_text = "https://lepczynski.it"

file_extension = os.path.splitext(object_key)[1].lower()
if file_extension != f'.{output_format.lower()}':
img = img.convert('RGB')

# Resize image to HD resolution (1280x720)
img = img.resize((1280, 720))

draw = ImageDraw.Draw(img)
font = ImageFont.load_default()

text_bbox = draw.textbbox((0, 0), watermark_text, font=font)
text_width = text_bbox[2] - text_bbox[0]
text_height = text_bbox[3] - text_bbox[1]

watermark_position = (img.width - text_width - 10, img.height - text_height - 10)

draw.text(watermark_position, watermark_text, font=font, fill=(255, 255, 255, 128)) # White with transparency

buffer = io.BytesIO()
img.save(buffer, output_format)
buffer.seek(0)

output_key = object_key.replace('input/', 'output/').rsplit('.', 1)[0] + f'.{output_format.lower()}'

s3.put_object(Bucket=bucket_name, Key=output_key, Body=buffer, ContentType=f'image/{output_format.lower()}')

return {
'statusCode': 200,
'body': f'Image successfully processed and saved as {output_key}'
}
else:
return {
'statusCode': 400,
'body': 'File not in the input folder.'
}

3. Setting Up an S3 Trigger for Your Lambda Function

To make your Lambda function automatically process images as soon as they are uploaded to an S3 bucket, you need to set up an S3 trigger. This trigger will invoke your Lambda function whenever a new object is created in the specified bucket. Here’s how to do it:

  1. In the Configuration tab, find the Triggers section, and Click on Add Trigger.
  2. In the Trigger configuration dropdown, select S3.
  3. Choose the S3 bucket you want to monitor for new uploads.
  4. For the Event type, select PUT. This will trigger the Lambda function only when a new object is created (uploaded) to the S3 bucket, avoiding unnecessary invocations for object deletions or other events.
  5. If you want to filter which files trigger the Lambda function, you can specify a prefix e.g., input/ like me or a suffix e.g., .jpg or .png. This way, only files that match the criteria will invoke the function.
  6. The console will automatically add the necessary permissions for the S3 bucket to invoke your Lambda function. Ensure that the IAM role associated with your Lambda function has permissions to read from the S3 bucket.
  7. Finally, click the Add button to create the trigger.

If you are interested in adding triggers to lambda functions, you can check out my other articles where I focus more on this topic. Take a look at this article How to automatically copy data from AWS S3 – Lambda events, or use the search function.

Testing

After setting up the S3 trigger, you can test it by uploading an image to your specified S3 bucket. Once the image is uploaded, your Lambda function should automatically be invoked, processing the image as per the code you have written.

Monitoring and Logs

You can monitor the execution of your Lambda function by checking the Monitor tab in the Lambda console. Additionally, you can view logs in Amazon CloudWatch to troubleshoot any issues that arise during execution.

you can view logs in Amazon CloudWatch to troubleshoot any issues

Remember to adjust the Lambda function permissions so that it can read from and write to your S3 bucket. You can also modify the watermark text, size, and position to fit your needs.

Conclusion

Now you have a powerful AWS Lambda function that automatically resizes images, adds a watermark, and converts them to the desired format. This setup can greatly improve your workflow, especially when creating thumbnails for YouTube videos or processing images for your blog, social media, or whatever you want.

If the article was helpful to you, I would be very happy if you leave a comment under this article or the video on YouTube. Remember that you can also subscribe to my YouTube channel to stay up to date with the content I create.

How to automatically copy data from AWS S3 – Lambda events
CDN and 2 ways to have a static website in AWS

Leave a Reply

Your email address will not be published. Required fields are marked *