Skip to content

Sharp

Unstable API

0.7.0

@project-lakechain/sharp-image-transform

TypeScript Icon

The Sharp middleware can be used to apply transformations to images at scale, such as resizing, cropping, rotating, and applying filters on images. It is based on the Sharp library which provides a very efficient way to apply transformations to images using libvips.


Sharp



đŸ–ŧī¸ Transforming Images

To use this middleware, you import it in your CDK stack and declare the transforms you want to apply on images. Developers can use the same API as the native Sharp API to declare the transforms to apply on images.

ℹī¸ The below example showcases how to resize input images to 200x200 pixels.

import { SharpImageTransform, sharp } from '@project-lakechain/sharp-image-transform';
import { CacheStorage } from '@project-lakechain/core';
class Stack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string) {
const cache = new CacheStorage(this, 'Cache');
// Create the Sharp image transform.
const transform = new SharpImageTransform.Builder()
.withScope(this)
.withIdentifier('Transform')
.withCacheStorage(cache)
.withSource(source)
.withSharpTransforms(
sharp().resize(200, 200) // 👈 Specify a transform
)
.build();
}
}


Chaining Transforms

The Sharp API transform actions can be chained to apply multiple transforms to an image.

ℹī¸ The below example resizes input images to a width of 500px, applies a grayscale filter, flips the image, and converts it to PNG.

const transform = new SharpImageTransform.Builder()
.withScope(this)
.withIdentifier('Transform')
.withCacheStorage(cache)
.withSource(source)
.withSharpTransforms(
sharp()
.resize(500)
.grayscale()
.flip()
.png()
)
.build();


🔗 External References

Some of the Sharp APIs, such as the composite API, can combine other images with the currently processed image. You can use a reference, part of the Lakechain DSL language, to pass an external image to these APIs.

ℹī¸ The below example applies an external image on S3 as a watermark to the currently processed image.

import { SharpImageTransform, sharp } from '@project-lakechain/sharp-image-transform';
import * as r from '@project-lakechain/core/dsl/vocabulary/reference';
// Sample bucket.
const bucket = new s3.Bucket(this, 'Bucket', {});
// Create the Sharp image transform.
const transform = new SharpImageTransform.Builder()
.withScope(this)
.withIdentifier('Transform')
.withCacheStorage(cache)
.withSource(source)
.withSharpTransforms(
sharp()
.composite([{
input: r.reference(
r.url(`s3://${bucket.bucketName}/watermark/watermark.png`)
)
}])
.png()
)
.build();
// Grant the middleware access to the watermark image.
bucket.grantRead(transform);


👾 Using Funclets

While static transforms are convenient and allow developers to describe transforms using the Sharp expressive API, there are use-cases that require developers to apply transforms in a more dynamic way, or generate multiple transforms based on the input image. This level of flexibility can be achieved by using Funclets instead of static transformations.

ℹī¸ Funclets allow you to specify a TypeScript function evaluated at runtime for each image in the cloud, and allows you to express in code the transformations you want to apply to the image.

Below is an example of how to specify a funclet that resizes input images to multiple sizes using TypeScript.

import { SharpImageTransform, SharpFunction, CloudEvent } from '@project-lakechain/sharp-image-transform';
// Resizes input images to different sizes.
const imageResize = new SharpImageTransform.Builder()
.withScope(this)
.withIdentifier('SharpTransform')
.withCacheStorage(cache)
.withSource(trigger)
.withSharpTransforms(async function*(event: CloudEvent, sharp: SharpFunction) {
// Load the image in memory.
const buffer = await event.data().document().data().asBuffer();
// Resize the image to the specified sizes.
for (const size of [100, 200, 300]) {
yield sharp(buffer).resize(size).png();
}
})
.build();


Inner Workings

The .withSharpTransforms method accepts a user-provided TypeScript generator function that can yield any number of Sharp transforms to apply to the image. Each yielded Sharp transform will be automatically be passed to the next middlewares in the pipeline.

ℹī¸ The generator function signature is as follows.

type SharpFunction = async function*(event: CloudEvent, sharp: SharpFunction): AsyncGenerator<SharpFunction, void, void>;


🏗ī¸ Architecture

The Sharp transform middleware runs within a Lambda compute leveraging a Lambda Layer containing the Sharp library for ARM64.

Architecture



🏷ī¸ Properties


Supported Inputs
Mime TypeDescription
image/jpegJPEG images.
image/pngPNG images.
image/tiffTIFF images.
image/webpWebP images.
image/avifAVIF images.
image/gifGIF images.
image/heicHEIC images.
image/heifHEIF images.
Supported Outputs

This middleware supports as outputs the same types as the supported inputs.

Supported Compute Types
TypeDescription
CPUThis middleware only supports CPU compute.


📖 Examples