Git Product home page Git Product logo

image-resizer's Introduction

Image Resizer for Image Download via CloudFront

Introduction

CloudFront with Lambda@Edge

This is a simple image resizer for image download via CloudFront. It is implemented as a Lambda@Edge function. Specifically, this Lambda@Edge function is triggered by the Origin Request and Origin Response events. When the function is triggered, it checks the requested image size and resizes the image to the requested size. The resized image is then returned to the user.

Image Resizing Process

Origin Request Process

For backward compatibility, the Lambda function is triggered by the Origin Request event for some specific cases. If the requested URI is like /path/to/file_L.jpg, the postfix of the file name _L is used to resize the image. Let's call the postfix as resizing hint. There are four types of resizing hints:

  • _t wants to resize the image width to 100 px
  • _s wants to resize the image width to 200 px
  • _m wants to resize the image width to 300 px
  • _l wants to resize the image width to 400 px

The specific width of each postfix should be rechecked and updated if necessary.

After parsing the resizing hint from the requested URI, the Lambda function modifies the URI without the resizing hint and adjust query string to have the matched width. w parameter in query string is the requested width for resizing.

This could be achieved by triggering the Lambda function by the Viewer Request event. This would be more efficient in terms of cache hit ratio in CloudFront. But, the Lambda function platform for Viewer Request event is restricted only to Javascript, and the function will be executed for all image requests, which means higher cost. As a trade-off, the Lambda function triggered by Origin Request might have lower cache hit ratio, but the execution count would be much less. As a result, I chose to process this business logic in Origin Request event stage.

Origin Response Process

From the request via CloudFront, there are some parameters that are used to resize the image. The parameters are as follows:

  • S3 bucket name set in CloudFront distribution
  • Path of an object in S3 bucket
  • Requested image size (width and height) in the query string
    • width: w (default is None)
    • height: h (default is None)
  • Requested quality of the image in the query string
    • quality: q (default is 80)

After parsing the parameters from the request, the Lambda function loads the image object from S3 bucket. From the object, the function reads the image data as follows:

  • Image format from Content-Type, e.g. image/jpeg
  • Image data as BytesIO stream

After that, the Lambda function resizes the image to the requested size. Here are specific rules for resizing the image:

  • If width and height are both specified, the image is resized to the requested size
    • The maximum width is 2000 px and the maximum height is 5000 px defined in image.py
  • If width is specified but not height, the image is resized to the requested width keeping the aspect ratio
    • But, if the requested width is larger than the original width, the image is returned as is
  • If height is specified but not width, the image is resized to the requested height keeping the aspect ratio
    • But, if the requested height is larger than the original height, the image is returned as is
  • If neither width nor height is specified, the image is returned as is
  • If the image format is JPEG, the image is compressed to the requested quality

Basically, the image format is kept as is. Here are the supported image formats defined at ImageFormat enum in image.py:

  • JPEG
  • PNG
  • GIF
  • WEBP
  • TIFF

If the object doesn't have the supported image format (or the object is not image), the Lambda function returns Origin Response as is.

Development

Prerequisites

Local Setup

brew install [email protected]
brew install poetry

# Install dependencies manually via Poetry
# or open the project in Pycharm and let it install the dependencies 
poetry install

Test

pytest --cov

Deployment

Should be automated in the future, but for now, it is a manual process.

  • Create artifact.zip file in the deploy directory by running ./build.sh
  • Upload the artifact.zip file to the Lambda function in the AWS console
  • Deploy the Lambda function as a Lambda@Edge function

Reference

Concept

Implementation

Deployment

image-resizer's People

Contributors

peppydays avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.