Metadata-Version: 2.4
Name: unfake
Version: 1.0.0
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: End Users/Desktop
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Rust
Classifier: Topic :: Multimedia :: Graphics
Classifier: Topic :: Multimedia :: Graphics :: Graphics Conversion
Classifier: Operating System :: OS Independent
Requires-Dist: opencv-python>=4.5.0
Requires-Dist: pillow>=9.0.0
Requires-Dist: numpy>=1.20.0
Requires-Dist: pytest>=7.0 ; extra == 'dev'
Requires-Dist: black>=22.0 ; extra == 'dev'
Requires-Dist: mypy>=0.990 ; extra == 'dev'
Requires-Dist: ruff>=0.0.261 ; extra == 'dev'
Requires-Dist: pytest>=7.0 ; extra == 'test'
Requires-Dist: pytest-asyncio>=0.20.0 ; extra == 'test'
Requires-Dist: pytest-cov>=4.0 ; extra == 'test'
Requires-Dist: sphinx>=5.0 ; extra == 'docs'
Requires-Dist: sphinx-rtd-theme>=1.0 ; extra == 'docs'
Provides-Extra: dev
Provides-Extra: test
Provides-Extra: docs
Summary: High-performance tool for improving AI-generated pixel art
Keywords: pixel-art,image-processing,quantization,ai-art,optimization,rust-python
Author-email: Benjamin Paine <painebenjamin@gmail.com>
License: MIT
Requires-Python: >=3.8
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
Project-URL: Homepage, https://github.com/painebenjamin/unfake.py
Project-URL: Repository, https://github.com/painebenjamin/unfake.py
Project-URL: Bug Tracker, https://github.com/painebenjamin/unfake.py/issues

# unfake

Improve AI-generated pixel art through scale detection, color quantization, and smart downscaling. Features Rust acceleration for critical operations.

Based on the excellent work by:
- **Eugeniy Smirnov** ([jenissimo/unfake.js](https://github.com/jenissimo/unfake.js)) - Original JavaScript implementation
- **Igor Bezkrovnyi** ([ibezkrovnyi/image-quantization](https://github.com/ibezkrovnyi/image-quantization)) - Image quantization algorithms

## Features

- **Automatic Scale Detection**: Detects the inherent scale of pixel art using both runs-based and edge-aware methods
- **Advanced Color Quantization**: Wu color quantization algorithm with Rust acceleration
- **Smart Downscaling**: Multiple methods including dominant color, median, mode, and content-adaptive
- **Image Cleanup**: Alpha binarization, morphological operations, and jaggy edge removal
- **Grid Snapping**: Automatic alignment to pixel grid for clean results
- **Flexible API**: Both synchronous and asynchronous interfaces

## Installation

### From PyPI (recommended)

```bash
pip install unfake
```

### From Source

```bash
# Clone the repository
git clone https://github.com/yourusername/unfake.git
cd unfake

# Install with pip (includes Rust compilation)
pip install .

# Or for development
pip install -e .
```

### Requirements

- Python 3.8+
- Rust toolchain (for building from source)
- OpenCV Python bindings
- Pillow
- NumPy

## Usage

### Command Line

```bash
# Basic usage with auto-detection
unfake input.png

# Specify output file
unfake input.png -o output.png

# Control color palette size
unfake input.png -c 16                    # Maximum 16 colors
unfake input.png --auto-colors            # Auto-detect optimal color count

# Force specific scale
unfake input.png --scale 4                # Force 4x downscaling

# Choose downscaling method
unfake input.png -m dominant              # Dominant color (default, best for pixel art)
unfake input.png -m median                # Median color
unfake input.png -m content-adaptive      # High quality but slower

# Enable cleanup operations
unfake input.png --cleanup morph,jaggy    # Morphological + jaggy edge cleanup

# Use fixed color palette
unfake input.png --palette palette.txt    # File with hex colors, one per line

# Adjust processing parameters
unfake input.png --alpha-threshold 200    # Higher threshold for alpha binarization
unfake input.png --threshold 0.1          # Dominant color threshold (0.0-1.0)
unfake input.png --no-snap                # Disable grid snapping

# Verbose output
unfake input.png -v                       # Show detailed processing info
```

### Python API

```python
import unfake

# Basic processing with defaults
result = unfake.process_image_sync(
    "input.png",
    max_colors=32,                       # Maximum colors in output
    detect_method="auto",                # Scale detection: "auto", "runs", "edge"
    downscale_method="dominant",         # Method: "dominant", "median", "mode", "mean", "content-adaptive"
    cleanup={"morph": False, "jaggy": False},
    snap_grid=True                       # Align to pixel grid
)

# Access results
processed_image = result['image']        # PIL Image
palette = result['palette']              # List of hex colors
manifest = result['manifest']            # Processing metadata

# Auto-detect optimal colors
result = unfake.process_image_sync(
    "input.png",
    max_colors=None,                     # Auto-detect
    auto_color_detect=True
)

# Use fixed palette
fixed_colors = ['#000000', '#ffffff', '#ff0000', '#00ff00', '#0000ff']
result = unfake.process_image_sync(
    "input.png",
    fixed_palette=fixed_colors
)
```

#### Asynchronous API

```python
import asyncio
import unfake

async def process_image_async():
    result = await unfake.process_image(
        "input.png",
        max_colors=16,
        detect_method="runs",
        downscale_method="median",
        cleanup={"morph": True, "jaggy": False},
        snap_grid=True
    )
    result["image"].save("output.png")

asyncio.run(process_image_async())
```

### Processing Options

#### Scale Detection Methods
- **`auto`** (default): Tries runs-based first, falls back to edge-aware
- **`runs`**: Analyzes color run lengths (fast, works well for clean pixel art)
- **`edge`**: Uses edge detection (slower but handles anti-aliased images)

#### Downscaling Methods
- **`dominant`** (default): Uses most frequent color in each block (best for pixel art)
- **`median`**: Median color value (good for photos)
- **`mode`**: Most common color (similar to dominant)
- **`mean`**: Average color (can create new colors)
- **`content-adaptive`**: Advanced algorithm based on [Kopf & Lischinski 2011](https://johanneskopf.de/publications/downscaling/)

#### Cleanup Options
- **`morph`**: Morphological operations to remove noise
- **`jaggy`**: Removes isolated diagonal pixels

## Performance
Example processing times for a 1024x1024 image:
- Pure Python: ~115 seconds
- With Rust Acceleration: ~5 seconds

## Algorithm Details

### Scale Detection
The tool uses two methods to detect the inherent scale of pixel art:

1. **Runs-based**: Analyzes horizontal and vertical color runs to find the GCD
2. **Edge-aware**: Uses Sobel edge detection to find regular grid patterns

### Color Quantization
Implements the Wu color quantization algorithm (1992) which:
- Builds a 3D color histogram
- Recursively subdivides color space
- Minimizes variance within each partition
- Produces high-quality palettes

### Downscaling
The dominant color method:
- Divides image into scale×scale blocks
- Finds most frequent color in each block
- Falls back to mean if no color is dominant
- Preserves original palette colors

## Credits

This Python/Rust implementation is based on:

- **[unfake.js](https://github.com/jenissimo/unfake.js)** by Eugeniy Smirnov - The original JavaScript implementation that inspired this project
- **[image-quantization](https://github.com/ibezkrovnyi/image-quantization)** by Igor Bezkrovnyi - TypeScript implementation of various color quantization algorithms

Additional references:
- Wu, Xiaolin. "Efficient Statistical Computations for Optimal Color Quantization" (1992)
- Kopf, Johannes and Dani Lischinski. "Depixelizing Pixel Art" (2011)

## License

MIT License 

