Skip to content

bubaley/pixiq

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

21 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🎨 Pixiq - Smart Image Compression

Intelligently compress images while preserving visual quality

Python Version License Tests

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

πŸ›‘οΈ 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 types
  • ValueError - Parameter values out of range
  • OSError - 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:

  1. 🎯 Quality Search - Binary search over quality range (1-100) to find optimal compression
  2. πŸ“Š PSNR Analysis - Calculate Peak Signal-to-Noise Ratio between original and compressed images
  3. 🧠 Perceptual Mapping - Convert PSNR to perceptual quality using empirical formula
  4. πŸŽͺ Best Match Selection - Choose quality with minimum error from target perceptual quality
  5. πŸ”— 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.

  1. Fork the repository
  2. Create a feature branch
  3. Add tests for new functionality
  4. Ensure all tests pass
  5. 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

⭐ Star us on GitHub β€’ πŸ› Report Issues β€’ πŸ’¬ Join Discussions

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •  

Languages