🎨 Pixiq - Smart Image Compression
Intelligently compress images while preserving visual quality
Compress smarter, not harder. Let AI choose the perfect quality for your images.
📦 Installation • 🚀 Quick Start • 📚 Documentation • ❓ Why Pixiq?
✨ Key Features
🎯 Smart Quality Selection - Automatically finds the optimal compression quality to match your target visual quality
🖼️ Multiple Formats - Supports JPEG, PNG, WEBP, and AVIF with format-specific optimizations
📏 Intelligent Resizing - Resize images while maintaining aspect ratio and quality
🔄 Thumbnail Generation - Create smaller versions of compressed images instantly
🎨 Alpha Channel Support - Handles transparent images correctly for each format
⚡ Performance Optimized - Fast compression with efficient memory usage
🧩 Tile-Based Quality Check - PSNR analysis performed on image tiles for fast quality assessment
🛡️ Robust Validation - Comprehensive input validation and error handling
🔍 Quality Metrics - Detailed compression statistics and iteration info
📦 Installation
From PyPI (Recommended)
Using uv (fastest):
uv add pixiq
# or
uv pip install pixiq
Using pip:
pip install pixiq
From Source
git clone https://github.com/yourusername/pixiq.git
cd pixiq
# Using uv
uv sync --dev
uv pip install -e .
# Using pip
pip install -e .
Requirements
- Python 3.9+
- PIL (Pillow) - Image processing
- NumPy - Array operations
- pillow-avif-plugin - AVIF format support
💡 Tip: uv is significantly faster than pip and provides better dependency management.
🚀 Quick Start
Try it now! Run the interactive demo:
python example.py
Basic Compression
from PIL import Image
from pixiq import Pixiq
# Open your image
image = Image.open('photo.jpg')
# Compress with target quality
result = Pixiq.compress(image, perceptual_quality=0.9)
print(f"✅ Compressed! Size: {result.file_size_kb:.1f} KB, Quality: {result.selected_quality}")
Advanced Usage
# Compress with custom settings
result = Pixiq.compress(
input=image,
perceptual_quality=0.85, # Target visual quality (0.0-1.0)
max_size=2000, # Resize if larger than 2000px
format='WEBP', # Force WEBP format
hash_type='sha1', # Use SHA1 instead of default SHA256
output='compressed.webp' # Save to file
)
# Access compression details
print(f"📊 Quality: {result.selected_quality}/100")
print(f"📏 Dimensions: {result.dimensions}")
print(f"💾 Size: {result.file_size_kb:.1f} KB")
print(f"🔐 Hash ({result.hash_type}): {result.hash}")
print(f"🎯 Achieved quality: {result.best_iteration['perceptual_quality']:.3f}")
Thumbnail Generation
# Create a thumbnail from compressed image
thumbnail = result.save_thumbnail(
max_size=500,
output='thumbnail.webp'
)
print(f"🖼️ Thumbnail: {thumbnail.dimensions}, {thumbnail.file_size_kb:.1f} KB")
📚 API Reference
Pixiq.compress() ⚡
The main method for intelligent image compression with automatic quality selection.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
input |
PIL Image | required | Input image to compress |
perceptual_quality |
float | 0.95 |
Target visual quality (0.0-1.0) |
tolerance |
float | 0.005 |
Quality tolerance for convergence |
max_quality |
int | None |
Maximum compression quality (1-100) |
min_quality |
int | None |
Minimum compression quality (1-100) |
max_size |
int | None |
Maximum dimension (resizes if larger) |
max_iter |
int | 5 |
Maximum binary search iterations |
format |
str | None |
Force format: 'JPEG', 'PNG', 'WEBP', 'AVIF' |
hash_type |
str | 'sha256' |
Hash algorithm: 'sha1', 'sha256', etc. |
output |
str/BytesIO | None |
Output file path or buffer |
Returns
CompressionResult - Object containing compressed image and metadata
Exceptions
TypeError- Invalid parameter typesValueError- Parameter values out of rangeOSError- File I/O errors
CompressionResult 📊
Container for compression results with convenient access methods.
Core Properties
| Property | Type | Description |
|---|---|---|
compressed |
PIL Image | The compressed image |
iterations_count |
int | Number of compression attempts |
iterations_info |
List[dict] | Detailed info for each iteration |
selected_quality |
int | Final compression quality (1-100) |
hash |
str | Hash of compressed image (SHA1/SHA256) |
hash_type |
str | Hash algorithm used ('sha1', 'sha256') |
file_size |
int | File size in bytes |
fmt |
str | Image format ('jpeg', 'webp', etc.) |
extra_save_args |
dict | Format-specific save parameters |
Computed Properties
| Property | Type | Description |
|---|---|---|
file_size_kb |
float | File size in kilobytes |
dimensions |
tuple[int, int] | Image dimensions (width, height) |
best_iteration |
dict | None | Info about best quality match |
Methods
save(output) 💾
Save compressed image to file or buffer.
result.save('output.webp')
result.save(io.BytesIO())
save_thumbnail(max_size, output=None) 🖼️
Create and save a resized version of the compressed image.
thumbnail = result.save_thumbnail(max_size=500, output='thumb.webp')
Returns: New CompressionResult with resized image
🎨 Supported Formats
| Format | Extension | Alpha Support | Optimization |
|---|---|---|---|
| JPEG | .jpg, .jpeg |
❌ | Progressive, optimized |
| PNG | .png |
✅ | Lossless compression |
| WEBP | .webp |
✅ | Method 6 (max compression) |
| AVIF | .avif |
✅ | Speed 6 (balanced) |
💡 Tip: Pixiq automatically detects format from file extension or uses JPEG as fallback
🧠 How It Works
Pixiq uses a smart binary search algorithm to find the optimal compression quality:
- 🎯 Quality Search - Binary search over quality range (1-100) to find optimal compression
- 📊 Tile-Based PSNR Analysis - Calculate Peak Signal-to-Noise Ratio on selected image tiles (not the entire image) for fast quality assessment. The algorithm automatically detects optimal tile size based on image type (UI vs photos) and selects tiles with the most color complexity for accurate quality measurement.
- 🧠 Perceptual Mapping - Convert PSNR to perceptual quality using empirical formula
- 🎪 Best Match Selection - Choose quality with minimum error from target perceptual quality
- 🔗 Efficient Hashing - Generate SHA1/SHA256 hash from compressed data without re-encoding
Algorithm Visualization
Target Quality: 0.85
┌─────────────────────────────────────┐
│ Quality 1 ────► Quality 100 │
│ ↓ ↓ ↓ │
│ PSNR: 25.3 PSNR: 35.7 PSNR: 42.1 │
│ Perceptual: 0.3 ────► 0.8 ────► 0.95 │
│ │ │ │ │
│ └──────────────┼──────────────┘ │
│ ▼ │
│ ✅ Best Match │
│ Quality: 67 │
│ Error: 0.0012 │
└─────────────────────────────────────┘
❓ Why Pixiq?
🔍 The Problem
Traditional image compression requires manual quality tuning:
# Old way - guesswork required
image.save('output.jpg', quality=85) # Is 85 good enough?
image.save('output.jpg', quality=75) # Too low quality?
image.save('output.jpg', quality=80) # Still guessing...
✅ The Solution
Pixiq automatically finds the perfect quality for your needs:
# New way - specify what you want
result = Pixiq.compress(image, perceptual_quality=0.9)
# Automatically finds quality=67 for 90% perceptual quality!
🚀 Performance Benefits
| Feature | Traditional | Pixiq |
|---|---|---|
| Quality Control | Manual guesswork | Precise target quality |
| File Size | Variable, unpredictable | Optimal for quality target |
| Time | Multiple manual attempts | Single API call |
| Consistency | Depends on user expertise | Consistent, reproducible |
| Formats | One quality per format | Optimized per format |
📈 Real-World Results
Original: photo.jpg (2.3 MB, 4000x3000)
Target: 85% perceptual quality
Format Quality Size Time
JPEG 78 245 KB 0.8s
WEBP 82 198 KB 0.7s
AVIF 75 156 KB 1.2s
🧪 Testing
Run the comprehensive test suite:
# Install development dependencies (using uv - recommended)
uv sync --dev
# Or using pip
pip install -e ".[dev]"
# Run tests
uv run pytest tests/
# Or using pytest directly
pytest tests/
# Or run manually
python -c "from tests.test_pixiq import *; test_basic_compression()"
💡 Tip: Using uv sync --dev is the fastest way to set up the development environment!
🤝 Contributing
We welcome contributions! Please see our Contributing Guide for details.
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
📄 License
MIT License - see LICENSE file for details.
🙏 Acknowledgments
- Built with Pillow for image processing
- Uses NumPy for efficient array operations
- Powered by uv for lightning-fast package management
- Inspired by modern image optimization techniques
Made with ❤️ for developers who care about image quality
Metadata
Release files for pixiq 0.5.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pixiq-0.5.0.tar.gz | 52.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pixiq-0.5.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 69.2 kB
Release files / pixiq-0.5.0.tar.gz
| Download URL | pixiq-0.5.0.tar.gz |
|---|---|
| Size | 52.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ab1280554831bd44954656808795c97938e5038a34b6eeb41f137f9752821749
|
|
BLAKE2b-256 checksum How to use checksums |
e24b57ddb432fe6b1f6bea60e42bdae83daf15914796202bb7d8136f9ea20b18
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / pixiq-0.5.0-py3-none-any.whl
| Download URL | pixiq-0.5.0-py3-none-any.whl |
|---|---|
| Size | 17.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d97f05c8d6e3165499d8929ce129773d342a105bfc0edc08e2e61ed32649befc
|
|
BLAKE2b-256 checksum How to use checksums |
cdaaa52d61e32ef1a9521a6f140aee50626b970861742bcbe8dfae34b00ec81a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|