https://github.com/tpyo/shrinkray
Lightning-fast image resizing & optimization for the web 🦀
https://github.com/tpyo/shrinkray
avif images jpeg libvips resize-images rust vips webp
Last synced: 26 days ago
JSON representation
Lightning-fast image resizing & optimization for the web 🦀
- Host: GitHub
- URL: https://github.com/tpyo/shrinkray
- Owner: tpyo
- License: mit
- Created: 2025-07-21T17:03:20.000Z (6 months ago)
- Default Branch: main
- Last Pushed: 2025-12-12T09:55:28.000Z (30 days ago)
- Last Synced: 2025-12-13T22:17:21.780Z (28 days ago)
- Topics: avif, images, jpeg, libvips, resize-images, rust, vips, webp
- Language: Rust
- Homepage:
- Size: 2.71 MB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# shrinkray
[](https://crates.io/crates/shrinkray)
[](https://github.com/tpyo/shrinkray/actions/workflows/main-image.yml)
[](https://github.com/tpyo/shrinkray/actions/workflows/tag-image.yml)
[](https://opensource.org/licenses/MIT)
[](https://codecov.io/github/tpyo/shrinkray)
Shrinkray is a high-performance image processing toolkit for Rust, consisting of:
- **[shrinkray](crates/lib)** - A fast image processing library powered by libvips
- **[shrinkray-server](crates/server)** - A lightweight image proxy server for on-the-fly transformations
## Library
Use the [shrinkray library](crates/lib) to integrate image processing directly into your Rust applications:
```rust
use shrinkray::ImageProcessor;
use shrinkray::options::{Format, Fit};
let result = ImageProcessor::new(&image_bytes)
.resize(800, 600)
.quality(85)
.format(Format::Webp)
.fit(Fit::Crop)
.process()?;
```
See the [library documentation](crates/lib) for full API details and examples.
## Server
The [shrinkray-server](crates/server) provides an HTTP service for on-the-fly image transformations:
### Features
- On-the-fly resizing, cropping and format conversion
- Configurable routing for file, HTTP or S3 backends
- Optional HMAC signatures to secure image URLs
- Prometheus metrics and OpenTelemetry tracing
### Use Cases
- Offload image resizing logic from your app server
- Serve responsive images without storing multiple variants
- Optimize external images at request time
- Use as a backend to a CDN for on-demand image transformation
### Inspiration
Shrinkray draws inspiration from other great image processing services, including:
- [dali](https://github.com/olxgroup-oss/dali) – a flexible image server
- [imgproxy](https://github.com/imgproxy/imgproxy) – a high-performance Golang image proxy
- [imgix](https://www.imgix.com) – a commercial image optimization platform
## Running the Server
### Kubernetes Deployment
Download and edit the Kubernetes [config file](https://github.com/tpyo/shrinkray/blob/main/kubernetes/config.yaml):
```bash
curl -O https://raw.githubusercontent.com/tpyo/shrinkray/refs/heads/main/kubernetes/config.yaml
```
Apply the Kubernetes manifests:
```bash
kubectl apply -f config.yaml
kubectl apply -f https://raw.githubusercontent.com/tpyo/shrinkray/refs/heads/main/kubernetes/deployment.yaml
```
### Local Development
Run `docker-compose up` to start a development instance listening on http://localhost:9000.
Grafana is available at http://localhost:3000.
### Example URL parameters
#### Resize with crop fit
http://localhost:9000/samples/02.jpg?w=400&h=400&dpr=2&fit=crop
- Resizes to 800×800 at double device pixel ratio (for retina screens)
- Fits by cropping to fill the dimensions
#### Resize with clip fit
http://localhost:9000/samples/04.jpg?w=1024&h=768
- Fits within 1024×768 without cropping
#### Resize to aspect ratio
http://localhost:9000/samples/03.jpg?ar=4:3&w=400
- Resizes to 400x300 with cropping
#### Trim whitespace
http://localhost:9000/samples/trim.jpg?trim=auto
- Trim colour can be set with `trim=colour` and `trim-colour=ffffff`
#### Rotatation
http://localhost:9000/samples/01.jpg?rot=180
#### Monochrome filter
http://localhost:9000/samples/08.jpg?monochrome=100
#### Duotone filter
http://localhost:9000/samples/08.jpg?duotone=003263,ffa600
#### Duotone filter with opacity
http://localhost:9000/samples/08.jpg?duotone=003263,ffa600&duotone-alpha=50
- Applies duotone effect at 50% opacity, blending with original image
#### Color tint
http://localhost:9000/samples/08.jpg?tint=ff0000
- Applies a red color tint to the image
#### Blur
http://localhost:9000/samples/08.jpg?blur=100
## Parameters
| Parameter | Description |
| --------------- | -------------------------------------------------------- |
| `w` | Width in pixels |
| `h` | Height in pixels |
| `bg` | Background colour used when padding or flattening |
| `ar` | Aspect ratio (e.g. `16:9`) |
| `q` | Output quality (default: `75`) |
| `dpr` | Device pixel ratio multiplier |
| `rot` | Rotation in degrees (`90`, `180` or `270`) |
| `fit` | Resizing mode (`clip`, `crop`, `max`) (default: `clip`) |
| `fm` | Output format (`jpeg`, `webp`, `png`, `avif`) |
| `dl` | Download filename for the response |
| `lossless` | Enable lossless encoding when available |
| `trim` | Trim borders automatically (`auto`, `colour`) |
| `trim-colour` | Set the trim colour for the `trim` parameter |
| `sharpen` | Adjust sharpness (0-100) |
| `blur` | Apply a blur (0-100) |
| `tint` | Apply a colour tint (e.g; `ff0000`) |
| `kodachrome` | Filter application (0-100) |
| `vintage` | Filter application (0-100) |
| `polaroid` | Filter application (0-100) |
| `technicolor` | Filter application (0-100) |
| `sepia` | Filter application (0-100) |
| `monochrome` | Filter application (0-100) |
| `duotone` | Duotone (`shadow`,`highlight` - e.g; `003263,ffa600`) |
| `duotone-alpha` | Duotone opacity/alpha (1-100) (default: `100`) |
| `sig` | HMAC signature used by `sign()` for request verification |
## Management service
- http://localhost:9001/metrics - Prometheus metrics endpoint
- http://localhost:9001/healthz - Health endpoint
## Prometheus Metrics
Shrinkray exports the following Prometheus metrics:
### Counters
| Metric | Description |
| ----------------------------------- | ------------------------------- |
| `shrinkray_http_response_200_count` | Count of successful responses |
| `shrinkray_http_response_401_count` | Count of unauthorized responses |
| `shrinkray_http_response_404_count` | Count of not found responses |
| `shrinkray_http_response_500_count` | Count of internal server errors |
### Histograms
| Metric | Labels | Description |
| ----------------------------------- | --------- | ------------------------------------- |
| `shrinkray_fetch_duration_seconds` | `backend` | Duration of image fetching operations |
| `shrinkray_output_duration_seconds` | `format` | Duration of image encoding operations |
Both histogram metrics use buckets: `0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1.0, 2.5, 5.0, 10.0` seconds.