Dynamically crop, resize and cache images, all on the CDN
The scenario:
- You need to display images optimized for the layout of your website.
- Perhaps these images get uploaded by your users, or they come from an external image provider.
- You don't want to send images larger than what is neccesary, because you are considerate of users who may be accessing your site from slower connections such as mobiles.
- Maybe you don't know what the size of all the source images are, but you still want them to fit neatly into your design.
- Or, maybe you want to allow your users to change how their profile images are cropped, to move and scale within fixed dimensions, without having to upload again.
I've used and built such services in the past. I thought it would be a straightforward yet useful thing to build with Rust and WASM) on Cloudflare workers.
Rust has great native crates that do not need to pull in shared libraries or call out to other processes.
With workers we are able to cache the source and resulting images directly on the CDN.
This software is currently used only for demonstration purposes and you should be aware of the limitations before using it for real.
- Follow instructions to install 🤠wrangler.
- Add your account id and zone id to the
wrangler.toml
- Run
$ wrangler publish
You should see something like:
🥳 Successfully published your script.
🥳 Successfully made your script available at image-worker...workers.dev
✨ Success! Your worker was successfully published. ✨
You will be able to call the worker at the domain provided,e.g. http://image-worker...workers.dev.
The URL path should be formatted as an image filename with a file extension signifying the target image format. Supported output formats are PNG (.png
) and JPEG (.jpg
or .jpeg
).
The query parameters should include a combination of:
- origin: the full URL to the source image (required)
- mode: one of fill, fit and limit (required, see modes for examples)
- width, height: the desired dimensions (both required when mode is fill or limit, either one or both for fit)
- dx, dy: the relative position when the image is cropped, numbers between -1.0 (left/top) and 1.0 (right/bottom) (default: 0.0, center)
- scale: a positive rational number to scale the source image by (default: 1.0)
- bg: a color in hex triplet format (default: transparent)
The source image is cropped in order to ensure that the full width and height is filled. The source image can be positioned using relative center offset dx and dy.
Examples:
URL | Image |
---|---|
https://.../image.png? mode=fill& width=180& height=200& origin=https://.../test_pattern.png |
|
https://.../image.jpg? mode=fill& width=180& height=200& origin=https://.../Apollo_17.jpeg |
The output image is exactly sized according to the given width and height, with no cropping of the source image. The source image can be positioned using relative center offset dx and dy.
Examples:
The source image is scaled to fit within the given width and height.
Examples:
- Cloudflare workers are limited in the amount of CPU time they are allowed to take per request (between 5ms for free and 50ms for business/enterprise accounts). This means that large images (> 1000 pixels in width or height), sometimes run out of processing time.
To run pure Rust tests:
$ cargo test
And for a headless browser smoke test using Chrome:
$ wasm-pack test --headless --chrome
Apache 2.0