Metadata-Version: 2.4
Name: ideamaxfx
Version: 0.1.0
Summary: Post-production effects, animated build-up, and visual toolkit for data visualizations
Author-email: IDEAMAX <info@ideamax.eu>
License: MIT
Project-URL: Homepage, https://github.com/devideamax/ideamaxfx
Project-URL: Documentation, https://ideamaxfx.readthedocs.io
Project-URL: Repository, https://github.com/devideamax/ideamaxfx
Project-URL: Changelog, https://github.com/devideamax/ideamaxfx/blob/main/CHANGELOG.md
Keywords: visualization,data-viz,effects,animation,charts,post-production,pillow
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: Topic :: Scientific/Engineering :: Visualization
Classifier: Topic :: Multimedia :: Graphics
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
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 :: Python :: 3.13
Classifier: Typing :: Typed
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: Pillow>=10.0
Requires-Dist: numpy>=1.24
Requires-Dist: imageio>=2.31
Provides-Extra: matplotlib
Requires-Dist: matplotlib>=3.7; extra == "matplotlib"
Provides-Extra: full
Requires-Dist: matplotlib>=3.7; extra == "full"
Requires-Dist: scipy>=1.10; extra == "full"
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov; extra == "dev"
Requires-Dist: ruff; extra == "dev"
Requires-Dist: mypy; extra == "dev"
Dynamic: license-file

# ideamaxfx

**Post-production effects, animated chart build-up, and visual toolkit for Python.**

[![Python 3.9+](https://img.shields.io/badge/python-3.9%2B-blue)](https://www.python.org/downloads/)
[![MIT License](https://img.shields.io/badge/license-MIT-green)](LICENSE)
[![Tests](https://img.shields.io/badge/tests-341%20passed-brightgreen)]()
[![Coverage](https://img.shields.io/badge/coverage-91%25-brightgreen)]()
[![Code style: ruff](https://img.shields.io/badge/code%20style-ruff-000000)](https://github.com/astral-sh/ruff)

---

## What It Does

- **Post-Production Effects Pipeline** -- Chainable API for cinematic finishing: grain, glow, scanlines, vignette, chromatic aberration, bloom, halftone, duotone, glass card, pattern overlays, and blend modes. Every method returns `self` so you can build complex multi-effect stacks in a single expression.

- **Animated Chart Build-Up** -- Generate GIF/APNG sequences where chart elements appear progressively with easing: bar, line, radar, scatter, pie, counter, heatmap, network, and morph transitions. Ships with 15 built-in easing functions and automatic GIF size optimization via gifsicle.

- **Visual Toolkit** -- Text effects (neon, gradient, outline, shadow, emboss), layout components (stat cards, progress bars, badges), color utilities, image composition, texture generators, and watermark tools. Pure Pillow core with optional matplotlib/scipy for advanced use cases.

---

## Installation

```bash
pip install ideamaxfx
```

Include optional dependencies for chart rendering and advanced interpolation:

```bash
pip install ideamaxfx[full]   # includes matplotlib + scipy
```

---

## Quick Start

### Effects Pipeline

```python
from ideamaxfx import EffectsPipeline
from PIL import Image

img = Image.open("chart.png")
result = (EffectsPipeline(img)
          .grain(0.06)
          .glow(color=(0, 245, 212))
          .scanlines(spacing=4)
          .vignette(0.3)
          .export("finished.png"))
```

### Animated Bar Chart

```python
from ideamaxfx.animate import bar_grow, export_gif

frames = bar_grow(
    labels=['Goals', 'Assists', 'Saves'],
    values=[68, 72, 45],
    colors=['#d4213d', '#006633', '#0056a0'],
    easing='ease_out_elastic'
)
export_gif(frames, 'animated.gif', max_kb=500)
```

### Text Effects

```python
from ideamaxfx.text import neon_text, gradient_text
from ideamaxfx.utils import load_font

font = load_font(size=48)
img = neon_text(canvas, 20, 20, "ELITE", font=font, color=(0, 245, 212))
```

---

## Modules

| Module | Description | Key Functions |
|--------|-------------|---------------|
| `effects` | Post-production effects | `grain`, `glow`, `glow_border`, `halftone`, `scanlines`, `glass_card`, `duotone`, `vignette`, `chromatic_aberration`, `bloom`, `blue_noise`, `pattern_overlay`, `blend`, `EffectsPipeline` |
| `animate` | Animated build-up | `bar_grow`, `line_draw`, `radar_sweep`, `scatter_fade`, `counter_roll`, `pie_fill`, `heatmap_reveal`, `network_build`, `morph`, `stagger_delays`, `compose_animations`, `export_gif`, `export_apng` |
| `text` | Text effects | `gradient_text`, `neon_text`, `outline_text`, `shadow_text`, `emboss_text` |
| `color` | Color utilities | `hex_to_rgb`, `rgb_to_hex`, `rgb_to_hsl`, `hsl_to_rgb`, `interpolate_colors`, `complementary`, `triadic`, `analogous`, `extract_palette`, `contrast_ratio`, `wcag_check` |
| `layout` | UI components | `stat_card`, `progress_bar`, `badge`, `legend_block`, `divider`, `callout` |
| `compose` | Image composition | `rounded_corners`, `drop_shadow`, `mirror_reflection`, `tilt_shift`, `pixelate`, `color_overlay` |
| `texture` | Pattern generators | `perlin_noise`, `grid_pattern`, `stripe_pattern`, `dot_pattern` |
| `watermark` | Branding tools | `text_watermark`, `image_watermark`, `footer_bar` |
| `utils` | Helpers | `load_font`, `mpl_to_pil`, `numpy_to_pil`, `pil_to_numpy` |

---

## Effects Pipeline API

`EffectsPipeline` wraps a PIL `Image` and returns `self` from every effect method, enabling fluent call chains. Call `.export(path)` to save the result to disk, or access the `.image` property to get the current frame without writing a file. The pipeline operates on an internal copy, so the original image is never mutated.

```python
pipeline = EffectsPipeline(img)
```

| Method | Parameters | Description |
|--------|-----------|-------------|
| `.grain(intensity, monochrome)` | `intensity: float = 0.06`, `monochrome: bool = True` | Film grain noise overlay |
| `.glow(color, radius, intensity)` | `color: (R,G,B) = (0,245,212)`, `radius: int = 20`, `intensity: float = 0.5` | Bright-area glow with RGB tint |
| `.halftone(dot_size, spacing, angle)` | `dot_size: int = 6`, `spacing: int = 8`, `angle: float = 45.0` | Halftone dot pattern conversion |
| `.scanlines(spacing, opacity, color)` | `spacing: int = 4`, `opacity: float = 0.3`, `color: (R,G,B) = (0,0,0)` | CRT scanline overlay |
| `.glass(x, y, w, h, blur, tint, radius)` | `x, y, w, h: int`, `blur: int = 15`, `tint: (R,G,B,A) = (20,25,40,160)`, `radius: int = 12` | Glassmorphism card region |
| `.duotone(dark, light)` | `dark: (R,G,B) = (10,10,40)`, `light: (R,G,B) = (255,200,50)` | Two-tone color mapping |
| `.vignette(strength, radius)` | `strength: float = 0.3`, `radius: float = 1.0` | Edge darkening |
| `.chromatic(offset, direction)` | `offset: int = 5`, `direction: str = "horizontal"` | Channel-shift chromatic aberration |
| `.bloom(threshold, radius, intensity)` | `threshold: int = 200`, `radius: int = 15`, `intensity: float = 0.4` | Bloom glow on bright regions |
| `.export(path, quality)` | `path: str`, `quality: int = 95` | Save to disk, returns `Image` |
| `.image` | property | Current image copy (no save) |

### Example: full chain

```python
from ideamaxfx import EffectsPipeline
from PIL import Image

result = (EffectsPipeline(Image.open("input.png"))
          .grain(0.04)
          .bloom(threshold=180, radius=20, intensity=0.5)
          .chromatic(offset=3)
          .scanlines(spacing=3, opacity=0.2)
          .vignette(0.35)
          .export("cinematic.png"))
```

---

## Animation Export

The `animate` module produces a list of PIL `Image` frames. Use `export_gif` or `export_apng` to save them.

```python
from ideamaxfx.animate import export_gif, export_apng

# GIF with automatic optimization
export_gif(frames, "output.gif", fps=15, max_colors=128, max_kb=500)

# Lossless APNG
export_apng(frames, "output.png", fps=15)
```

**`export_gif` parameters:**

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `frames` | `list[Image]` | required | PIL Image frame sequence |
| `output_path` | `str` | required | Destination file path |
| `fps` | `int` | `15` | Frames per second |
| `max_colors` | `int` | `128` | Maximum palette colors |
| `max_kb` | `int` | `500` | Target max file size in KB |
| `lossy` | `int` | `40` | gifsicle lossy level (0-200) |
| `optimize` | `bool` | `True` | Use gifsicle if available |

When gifsicle is installed, `export_gif` runs a two-pass optimization: first at the requested settings, then a more aggressive pass if the file exceeds `max_kb`. Without gifsicle it falls back to Pillow's built-in GIF writer with adaptive palette quantization.

**`export_apng` parameters:**

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `frames` | `list[Image]` | required | PIL Image frame sequence |
| `output_path` | `str` | required | Destination file path |
| `fps` | `int` | `15` | Frames per second |

---

## Easing Functions

All 15 easing functions accept `t` in the range `[0.0, 1.0]` and return the eased value. Pass the function name as a string to any `easing` parameter in the `animate` module, or call `get_easing(name)` to retrieve the callable directly.

| Name | Description |
|------|-------------|
| `linear` | Constant speed, no acceleration |
| `ease_in_quad` | Quadratic ease-in (accelerating) |
| `ease_out_quad` | Quadratic ease-out (decelerating) |
| `ease_in_out_quad` | Quadratic ease-in then ease-out |
| `ease_in_cubic` | Cubic ease-in |
| `ease_out_cubic` | Cubic ease-out |
| `ease_in_out_cubic` | Cubic ease-in then ease-out |
| `ease_in_quart` | Quartic ease-in |
| `ease_out_quart` | Quartic ease-out |
| `ease_in_out_quart` | Quartic ease-in then ease-out |
| `ease_out_elastic` | Spring overshoot with oscillation |
| `ease_out_bounce` | Bouncing ball decay |
| `ease_out_back` | Slight overshoot past target |
| `ease_in_expo` | Exponential ease-in |
| `ease_out_expo` | Exponential ease-out |

Use by name:

```python
from ideamaxfx.animate import bar_grow

frames = bar_grow(labels=["A", "B"], values=[80, 60], easing="ease_out_bounce")
```

Or retrieve the function directly:

```python
from ideamaxfx.animate import get_easing

fn = get_easing("ease_out_elastic")
value = fn(0.5)  # returns eased float in 0.0-1.0
```

---

## Standalone Effects

Each effect is also available as a standalone function that takes a PIL `Image` and returns a new `Image`. Use these when you need a single effect without the pipeline wrapper.

```python
from ideamaxfx.effects import grain, vignette, bloom

img = grain(img, intensity=0.05)
img = bloom(img, threshold=190, radius=12, intensity=0.3)
img = vignette(img, strength=0.25)
img.save("output.png")
```

Additional standalone functions not exposed on the pipeline:

| Function | Module | Description |
|----------|--------|-------------|
| `glow_border(img, color, width, radius)` | `effects` | Glowing border around image edges |
| `blue_noise(width, height)` | `effects` | Generate blue noise dither pattern |
| `pattern_overlay(img, pattern, opacity)` | `effects` | Tile a pattern over an image |
| `blend(base, overlay, mode, opacity)` | `effects` | Photoshop-style blend modes |

---

## Color Utilities

The `color` module provides conversion, harmony, palette extraction, and accessibility checking.

```python
from ideamaxfx.color import hex_to_rgb, complementary, contrast_ratio, wcag_check

rgb = hex_to_rgb("#d4213d")                    # (212, 33, 61)
comp = complementary(rgb)                       # complementary hue
ratio = contrast_ratio((255, 255, 255), rgb)    # WCAG contrast ratio
passes = wcag_check((255, 255, 255), rgb)       # AA/AAA compliance dict
```

---

## Requirements

**Core** (installed automatically):

| Package | Version |
|---------|---------|
| Python | >= 3.9 |
| Pillow | >= 10.0 |
| numpy | >= 1.24 |
| imageio | >= 2.31 |

**Optional** (install via `pip install ideamaxfx[full]`):

| Package | Version | Purpose |
|---------|---------|---------|
| matplotlib | >= 3.7 | Chart rendering backends |
| scipy | >= 1.10 | Advanced interpolation and filters |

**Optional system tool:**

| Tool | Purpose |
|------|---------|
| [gifsicle](https://www.lcdf.org/gifsicle/) | GIF optimization (auto-detected at export time) |

---

## Development

```bash
git clone https://github.com/devideamax/ideamaxfx.git
cd ideamaxfx
pip install -e ".[dev]"
pytest tests/
ruff check src/
```

The `[dev]` extra installs `pytest`, `pytest-cov`, `ruff`, and `mypy`.

Run the type checker:

```bash
mypy src/
```

---

## Contributing

1. Fork the repository.
2. Create a feature branch from `main`.
3. Add tests for new functionality.
4. Ensure `pytest tests/` and `ruff check src/` pass.
5. Open a pull request.

---

## License

MIT License. Copyright (c) 2026 IDEAMAX.

See [LICENSE](LICENSE) for the full text.

---

## Links

- **GitHub:** [github.com/devideamax/ideamaxfx](https://github.com/devideamax/ideamaxfx)
- **Changelog:** [CHANGELOG.md](./CHANGELOG.md)
