{"id":34250019,"url":"https://github.com/tpyo/shrinkray","last_synced_at":"2026-02-19T10:10:52.788Z","repository":{"id":305732183,"uuid":"1023770072","full_name":"tpyo/shrinkray","owner":"tpyo","description":"Lightning-fast image resizing \u0026 optimization for the web 🦀","archived":false,"fork":false,"pushed_at":"2025-12-12T09:55:28.000Z","size":2838,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-12-13T22:17:21.780Z","etag":null,"topics":["avif","images","jpeg","libvips","resize-images","rust","vips","webp"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tpyo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-07-21T17:03:20.000Z","updated_at":"2025-12-12T09:55:25.000Z","dependencies_parsed_at":"2025-08-05T20:13:24.395Z","dependency_job_id":"30b4df5a-544c-46ee-84ad-ef1e1d42f9e8","html_url":"https://github.com/tpyo/shrinkray","commit_stats":null,"previous_names":["tpyo/shrinkray"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/tpyo/shrinkray","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tpyo%2Fshrinkray","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tpyo%2Fshrinkray/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tpyo%2Fshrinkray/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tpyo%2Fshrinkray/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tpyo","download_url":"https://codeload.github.com/tpyo/shrinkray/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tpyo%2Fshrinkray/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":27761673,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-12-16T02:00:10.477Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["avif","images","jpeg","libvips","resize-images","rust","vips","webp"],"created_at":"2025-12-16T09:08:51.350Z","updated_at":"2026-02-19T10:10:52.781Z","avatar_url":"https://github.com/tpyo.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# shrinkray\n\n[![crates.io](https://img.shields.io/crates/v/shrinkray.svg)](https://crates.io/crates/shrinkray)\n[![docs.rs](https://img.shields.io/docsrs/shrinkray)](https://docs.rs/shrinkray/latest/shrinkray/)\n[![Main image](https://github.com/tpyo/shrinkray/actions/workflows/main-image.yml/badge.svg)](https://github.com/tpyo/shrinkray/actions/workflows/main-image.yml)\n[![Release image](https://github.com/tpyo/shrinkray/actions/workflows/tag-image.yml/badge.svg)](https://github.com/tpyo/shrinkray/actions/workflows/tag-image.yml)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![codecov](https://codecov.io/github/tpyo/shrinkray/graph/badge.svg?token=BXFB15WSLA)](https://codecov.io/github/tpyo/shrinkray)\n\nShrinkray is a high-performance image processing toolkit for Rust, consisting of:\n\n- **[shrinkray](crates/lib)** - A fast image processing library powered by libvips\n- **[shrinkray-server](crates/server)** - A lightweight image proxy server for on-the-fly transformations\n\n## Requirements\n\n- **libvips 8.17.0 or higher** (for older 8.16.x libvips versions use shrinkray 1.0.1)\n- libaom (for AVIF support via libheif)\n- libheif\n- libjpeg\n- libpng\n- libwebp\n\nFor more information on installing the required dependencies, see the [Ubuntu](https://github.com/tpyo/shrinkray/blob/main/docker/Dockerfile.base-slim-bookworm) and [Alpine](https://github.com/tpyo/shrinkray/blob/main/docker/Dockerfile.base-alpine) base images.\n\n## Library\n\nUse the [shrinkray library](crates/lib) to integrate image processing directly into your Rust applications:\n\n```rust\nuse shrinkray::ImageProcessor;\nuse shrinkray::options::{Format, Fit};\n\nlet result = ImageProcessor::new(\u0026image_bytes)\n    .resize(800, 600)\n    .quality(85)\n    .format(Format::Webp)\n    .fit(Fit::Crop)\n    .process()?;\n```\n\nSee the [library documentation](crates/lib) for full API details and examples.\n\n## Server\n\nThe [shrinkray-server](crates/server) provides an HTTP service for on-the-fly image transformations:\n\n### Features\n\n- On-the-fly resizing, cropping and format conversion\n- Configurable routing for file, HTTP or S3 backends\n- Optional HMAC signatures to secure image URLs\n- Prometheus metrics and OpenTelemetry tracing\n\n### Use Cases\n\n- Offload image resizing logic from your app server\n- Serve responsive images without storing multiple variants\n- Optimise external images at request time\n- Use as a backend to a CDN for on-demand image transformation\n\n### Inspiration\n\nShrinkray draws inspiration from other great image processing services, including:\n\n- [dali](https://github.com/olxgroup-oss/dali) – a flexible image server\n- [imgproxy](https://github.com/imgproxy/imgproxy) – a high-performance Golang image proxy\n- [imgix](https://www.imgix.com) – a commercial image optimisation platform\n\n## Running the Server\n\n### Docker Standalone\n\nRun the Docker image standalone with your own configuration:\n\n```bash\ndocker run -p 9000:9000 -p 9001:9001 -v $(pwd)/config/config.json:/opt/shrinkray/etc/config.json ghcr.io/tpyo/shrinkray/server:latest /opt/shrinkray/etc/config.json\n```\n\nThis mounts your local `config/config.json` file to the expected location in the container and starts a server listening on http://localhost:9000.\n\n**Available image variants:**\n- `ghcr.io/tpyo/shrinkray/server:latest` - Debian slim-bookworm based image\n- `ghcr.io/tpyo/shrinkray/server:latest-alpine` - Alpine Linux based image (smaller size)\n\n### Kubernetes Deployment\n\nDownload and edit the Kubernetes [config file](https://github.com/tpyo/shrinkray/blob/main/kubernetes/config.yaml):\n\n```bash\ncurl -O https://raw.githubusercontent.com/tpyo/shrinkray/refs/heads/main/kubernetes/config.yaml\n```\n\nApply the Kubernetes manifests:\n\n```bash\nkubectl apply -f config.yaml\nkubectl apply -f https://raw.githubusercontent.com/tpyo/shrinkray/refs/heads/main/kubernetes/deployment.yaml\n```\n\n### Local Development\n\nRun `docker-compose up` to start a development instance listening on http://localhost:9000.\n\nGrafana is available at http://localhost:3000.\n\n### Example URL parameters\n\n#### Resize with crop fit\n\nhttp://localhost:9000/samples/02.jpg?w=400\u0026h=400\u0026dpr=2\u0026fit=crop\n\n- Resizes to 800×800 at double device pixel ratio (for retina screens)\n- Fits by cropping to fill the dimensions\n\n#### Resize with clip fit\n\nhttp://localhost:9000/samples/04.jpg?w=1024\u0026h=768\n\n- Fits within 1024×768 without cropping\n\n#### Resize to aspect ratio\n\nhttp://localhost:9000/samples/03.jpg?ar=4:3\u0026w=400\n\n- Resizes to 400x300 with cropping\n\n#### Trim whitespace\n\nhttp://localhost:9000/samples/trim.jpg?trim=auto\n\n- Trim colour can be set with `trim=colour` and `trim-colour=ffffff`\n\n#### Rotatation\n\nhttp://localhost:9000/samples/01.jpg?rot=180\n\n#### Monochrome filter\n\nhttp://localhost:9000/samples/08.jpg?monochrome=100\n\n#### Duotone filter\n\nhttp://localhost:9000/samples/08.jpg?duotone=003263,ffa600\n\n#### Duotone filter with opacity\n\nhttp://localhost:9000/samples/08.jpg?duotone=003263,ffa600\u0026duotone-alpha=50\n\n- Applies duotone effect at 50% opacity, blending with original image\n\n#### Color tint\n\nhttp://localhost:9000/samples/08.jpg?tint=ff0000\n\n- Applies a red color tint to the image\n\n#### Blur\n\nhttp://localhost:9000/samples/08.jpg?blur=100\n\n## Parameters\n\n| Parameter       | Description                                              |\n| --------------- | -------------------------------------------------------- |\n| `w`             | Width in pixels                                          |\n| `h`             | Height in pixels                                         |\n| `bg`            | Background colour used when padding or flattening        |\n| `ar`            | Aspect ratio (e.g. `16:9`)                               |\n| `q`             | Output quality (default: `75`)                           |\n| `dpr`           | Device pixel ratio multiplier                            |\n| `rot`           | Rotation in degrees (`90`, `180` or `270`)               |\n| `fit`           | Resizing mode (`clip`, `crop`, `max`) (default: `clip`)  |\n| `fm`            | Output format (`jpeg`, `webp`, `png`, `avif`)            |\n| `dl`            | Download filename for the response                       |\n| `lossless`      | Enable lossless encoding when available                  |\n| `trim`          | Trim borders automatically (`auto`, `colour`)            |\n| `trim-colour`   | Set the trim colour for the `trim` parameter             |\n| `sharpen`       | Adjust sharpness (0-100)                                 |\n| `blur`          | Apply a blur (0-100)                                     |\n| `tint`          | Apply a colour tint (e.g; `ff0000`)                      |\n| `kodachrome`    | Filter application (0-100)                               |\n| `vintage`       | Filter application (0-100)                               |\n| `polaroid`      | Filter application (0-100)                               |\n| `technicolor`   | Filter application (0-100)                               |\n| `sepia`         | Filter application (0-100)                               |\n| `monochrome`    | Filter application (0-100)                               |\n| `duotone`       | Duotone (`shadow`,`highlight` - e.g; `003263,ffa600`)    |\n| `duotone-alpha` | Duotone opacity/alpha (1-100) (default: `100`)           |\n| `sig`           | HMAC signature used by `sign()` for request verification |\n\n## Management service\n\n- http://localhost:9001/metrics - Prometheus metrics endpoint\n- http://localhost:9001/healthz - Health endpoint\n\n## Prometheus Metrics\n\nShrinkray exports the following Prometheus metrics:\n\n### Counters\n\n| Metric                              | Description                     |\n| ----------------------------------- | ------------------------------- |\n| `shrinkray_http_response_200_count` | Count of successful responses   |\n| `shrinkray_http_response_401_count` | Count of unauthorized responses |\n| `shrinkray_http_response_404_count` | Count of not found responses    |\n| `shrinkray_http_response_500_count` | Count of internal server errors |\n\n### Histograms\n\n| Metric                              | Labels    | Description                           |\n| ----------------------------------- | --------- | ------------------------------------- |\n| `shrinkray_fetch_duration_seconds`  | `backend` | Duration of image fetching operations |\n| `shrinkray_output_duration_seconds` | `format`  | Duration of image encoding operations |\n\nBoth 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.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftpyo%2Fshrinkray","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftpyo%2Fshrinkray","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftpyo%2Fshrinkray/lists"}