Blazing Fast Image Processing for Python, Powered by Rust
196x faster image loading, 8.5x faster saving. Rust-powered performance without the complexity.
Built with Rust's memory safety guarantees. No segfaults, no memory leaks, just reliable performance.
Familiar API. Most Pillow code works with minimal changes. Easy migration path.
Pre-built wheels for Linux, Windows, macOS, and Android. No compilation needed!
Vectorized operations using AVX2/SSE4. Maximum performance from modern CPUs.
Full type hints for IDE autocomplete. Catch errors before runtime with mypy support.
pip install imgrs
Supports Python 3.8-3.12 on Linux, Windows, macOS, and Android
from imgrs import Image
# Open image (196x faster than Pillow!)
img = Image.open("photo.jpg")
# Resize (1.5x faster than Pillow!)
resized = img.resize((800, 600))
# Save (8.5x faster than Pillow!)
resized.save("output.png")
from imgrs import Image
img = Image.open("photo.jpg")
# Chain filters
result = (img
.blur(5.0)
.brightness(10)
.contrast(1.2)
.sharpen(1.5))
result.save("enhanced.jpg")
from imgrs import Image
# Create canvas
img = Image.new("RGB", (400, 300), (255, 255, 255))
# Draw shapes
img = img.draw_rectangle(50, 50, 100, 100, (255, 0, 0, 255))
img = img.draw_circle(200, 150, 50, (0, 255, 0, 255))
img.save("shapes.png")
from imgrs import Image
img = Image.open("logo.png")
# Add drop shadow
shadowed = img.drop_shadow(
offset_x=10,
offset_y=10,
blur_radius=15.0,
shadow_color=(0, 0, 0, 128)
)
shadowed.save("logo_shadow.png")
| Operation | Pillow | imgrs | Winner |
|---|---|---|---|
| Open Image | 0.49ms | 0.00ms | imgrs 196x ⚡ |
| Save PNG | 134.11ms | 15.75ms | imgrs 8.5x ⚡ |
| Resize | 16.33ms | 10.59ms | imgrs 1.5x ⚡ |
| Convert Grayscale | 3.06ms | 5.10ms | Pillow 1.7x |
| Rotate 90° | 4.83ms | 9.11ms | Pillow 1.9x |
Faster Image Opening
Faster Image Saving
Average Speedup
from imgrs import Image
from pathlib import Path
def create_thumbnails(input_dir, size=(150, 150)):
for img_path in Path(input_dir).glob("*.jpg"):
img = Image.open(img_path)
thumb = img.resize(size, resample="LANCZOS")
thumb.save(f"thumbs/{img_path.name}")
create_thumbnails("photos/")
from imgrs import Image
def enhance_photo(img):
return (img
.resize((1920, 1080), resample="LANCZOS")
.brightness(10)
.contrast(1.2)
.saturate(1.1)
.sharpen(1.5))
img = Image.open("photo.jpg")
enhanced = enhance_photo(img)
enhanced.save("enhanced.jpg")
from imgrs import Image
img = Image.open("photo.jpg")
# Semi-transparent watermark
watermark = (255, 255, 255, 128)
img = img.draw_text(
"© 2025",
10,
img.height - 30,
watermark,
scale=2
)
img.save("watermarked.jpg")
from imgrs import Image
from pathlib import Path
# Convert all JPEGs to WebP
for jpg in Path("photos/").glob("*.jpg"):
img = Image.open(jpg)
# Resize if too large
if img.width > 1920:
img = img.resize((1920, 1080))
webp = jpg.with_suffix(".webp")
img.save(webp, format="WEBP")
print(f"✅ {webp.name}")