Fast, friendly image processing for web apps and SaaS
Project description
nitro-image
Fast, friendly image processing for Python web apps and SaaS.
from nitro_img import Image
Image("photo.jpg").resize(800).webp(quality=80).save("photo.webp")
Install
pip install nitro-image
Optional extras:
pip install nitro-image[url] # Load images from URLs (httpx)
pip install nitro-image[avif] # AVIF format support
pip install nitro-image[blur] # BlurHash generation
pip install nitro-image[all] # Everything
Claude Code Skill
Add NitroImage as a skill in Claude Code for AI-assisted image manipulation:
npx skills add nitrosh/nitro-image
Why nitro-image?
With Pillow alone:
from PIL import Image
img = Image.open("photo.jpg")
img = img.convert("RGB")
width, height = img.size
new_height = int(height * (800 / width))
img = img.resize((800, new_height), Image.LANCZOS)
img.save("photo.webp", "WEBP", quality=80)
With nitro-image:
from nitro_img import Image
Image("photo.jpg").resize(800).webp(quality=80).save("photo.webp")
nitro-image wraps Pillow with a chainable API and lazy execution pipeline. Operations queue up and only run when you call an output method like .save() or .to_bytes().
Features
Resize and crop
Image("photo.jpg").resize(800).save("resized.jpg")
Image("photo.jpg").thumbnail(200).save("thumb.jpg")
Image("photo.jpg").cover(400, 400).save("square.jpg")
Image("photo.jpg").contain(400, 400).save("contained.jpg")
Image("photo.jpg").crop(100, 100, 500, 400).save("cropped.jpg")
Format conversion
Image("photo.jpg").webp(quality=80).save("photo.webp")
Image("photo.jpg").png().save("photo.png")
Image("photo.jpg").jpeg(quality=90).save("photo.jpg")
Image("photo.jpg").auto_format().save("photo.webp") # picks best format
Adjustments and effects
Image("photo.jpg").brightness(1.2).contrast(1.1).save("enhanced.jpg")
Image("photo.jpg").sharpen(1.5).save("sharp.jpg")
Image("photo.jpg").blur(2.0).save("blurred.jpg")
Image("photo.jpg").grayscale().save("gray.jpg")
Image("photo.jpg").sepia().save("sepia.jpg")
Image("photo.jpg").rounded_corners(20).png().save("rounded.png")
Watermark and text overlay
Image("photo.jpg").watermark("logo.png", position="bottom-right", opacity=0.5).save("watermarked.jpg")
Image("photo.jpg").text_overlay("Sample", font_size=48).save("labeled.jpg")
Responsive images
widths = Image("photo.jpg").responsive([400, 800, 1200, 1600])
# Returns {400: bytes, 800: bytes, 1200: bytes, 1600: bytes}
Image("photo.jpg").save_responsive("output/{width}w.webp", [400, 800, 1200])
# Saves output/400w.webp, output/800w.webp, output/1200w.webp
Placeholders
Image("photo.jpg").lqip() # Low-quality base64 data URI
Image("photo.jpg").dominant_color() # "#3a6b8c"
Image("photo.jpg").color_palette(5) # ["#3a6b8c", "#d4a574", ...]
Image("photo.jpg").svg_placeholder() # SVG with dominant color
Image("photo.jpg").blurhash() # "LKO2:N%2Tw=w]~RBVZRi..."
Optimization
Image("photo.jpg").optimize(target_kb=200).save("optimized.jpg")
Presets
from nitro_img import Image
Image("photo.jpg").preset.thumbnail() # 300px thumbnail
Image("photo.jpg").preset.avatar() # 128px circle crop
Image("photo.jpg").preset.og_image() # 1200x630 social card
Image("photo.jpg").preset.banner() # 1920x400 banner
Image.preset.avatar_placeholder("SN") # Initials avatar image
Batch processing
from nitro_img import BatchImage
BatchImage("photos/*.jpg").resize(800).webp().save("output/{name}.webp")
BatchImage("photos/*.jpg").resize(800).jpeg().save("output/{name}.jpg", parallel=True)
Web framework responses
# Django
return Image("photo.jpg").resize(400).webp().to_django_response()
# Flask
return Image("photo.jpg").resize(400).webp().to_flask_response()
# FastAPI
return Image("photo.jpg").resize(400).webp().to_fastapi_response()
Loading from anywhere
Image("photo.jpg") # File path
Image.from_bytes(raw_bytes) # Bytes
Image.from_base64(b64_string) # Base64 string
Image.from_url("https://example.com/img") # URL (requires httpx)
Image.from_file(file_object) # File-like object
Output options
img = Image("photo.jpg").resize(400).webp()
img.save("output.webp") # Save to file
img.to_bytes() # Get raw bytes
img.to_base64() # Base64 encoded string
img.to_data_uri() # data:image/webp;base64,...
img.to_response() # {"body": bytes, "content_type": str, "content_length": int}
Chain everything
All operations are chainable and lazily evaluated:
(
Image("photo.jpg")
.resize(800)
.brightness(1.1)
.contrast(1.05)
.sharpen(1.2)
.sepia()
.rounded_corners(10)
.png(optimize=True)
.save("final.png")
)
Configuration
from nitro_img import config
config.update(
jpeg_quality=85,
webp_quality=80,
png_optimize=True,
max_width=4096,
max_height=4096,
)
Requirements
- Python 3.10+
- Pillow 10.0+
Ecosystem
- nitro-ui - Programmatic HTML generation
- nitro-datastore - Data loading with dot notation access
- nitro-dispatch - Plugin system
- nitro-validate - Data validation
- nitro-image - Friendly image processing
License
This project is licensed under the BSD 3-Clause License. See the LICENSE file for details.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file nitro_image-1.0.0.tar.gz.
File metadata
- Download URL: nitro_image-1.0.0.tar.gz
- Upload date:
- Size: 34.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bcdef4ab2647ae1c4d1ceefe7e03afbc3ee62b241c265fbca0fb0d1cee8221fa
|
|
| MD5 |
a6c45dbb000f13ea72c604c3f2690fd2
|
|
| BLAKE2b-256 |
8585dfaa74c6283fd636ca18fda91229775bcd2b50911965ba6a9c4e349e7df6
|
File details
Details for the file nitro_image-1.0.0-py3-none-any.whl.
File metadata
- Download URL: nitro_image-1.0.0-py3-none-any.whl
- Upload date:
- Size: 28.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b9a800d5f25fc334afbece814bdfdc367b158e7bc3ad41a652fbd95363686d71
|
|
| MD5 |
70bdda22345cb117aedf7786fc9d1fed
|
|
| BLAKE2b-256 |
98874a33f203ea7bc1a2c691e87a360e925602005865e2e899dfe71a44847e98
|