Metadata-Version: 2.5
Name: burst-align
Version: 0.1.0
Summary: Stabilize a photo burst using border features only, and turn it into a GIF.
License-Expression: MIT
Keywords: alignment,burst,gif,opencv,photography,stabilization
Classifier: Environment :: Console
Classifier: Intended Audience :: End Users/Desktop
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Multimedia :: Graphics
Requires-Python: >=3.10
Requires-Dist: numpy>=1.26
Requires-Dist: opencv-python-headless>=4.9
Description-Content-Type: text/markdown

# burst-align

Stabilizes a burst of photos so the background locks still while the subject keeps
moving, then optionally encodes the result as a GIF. It picks features only from a
region you choose — by default a border band, excluding the middle of the frame —
so a moving subject in the centre can't drag the alignment off. It aligns to the
middle frame, crops every frame to the area they all share, and hands the result to
ffmpeg. Needs `ffmpeg` on your PATH for GIF output; everything else installs itself.

## Install

Nothing to install — `uvx` fetches and runs it:

```bash
uvx burst-align '*.jpg' -o aligned --gif out.gif
```

Pin a version with `uvx burst-align@0.1.0`, or install it as a persistent command
with `uv tool install burst-align`.

## Examples

Run from the directory holding your photos. Quote the pattern so the shell hands
it over intact.

```bash
# Align a burst and write a GIF
uvx burst-align '*.jpg' -o aligned --gif out.gif

# Check what region is being used for alignment before committing
uvx burst-align '*.jpg' -o aligned --save-mask

# Pick which depth plane locks: use only the right 40% of the frame
uvx burst-align '*.jpg' -o aligned --keep 0.6,0,1,1 --gif out.gif

# Boomerang the loop so the wrap from last frame to first isn't jarring
uvx burst-align '*.jpg' -o aligned --pingpong --gif out.gif

# Smaller, slower GIF; ignore only the middle 40%; shift-only (no rotate/scale)
uvx burst-align '*.jpg' -o aligned \
  --exclude 0.4 --model translation --gif out.gif --fps 6 --gif-width 480
```

Add `-h` for the rest of the options.

## Choosing a region

`--keep` and `--exclude` **intersect** — `--keep` narrows the area, then
`--exclude` punches the centre out of whatever is left. Neither overrides the
other.

The default `--exclude 0.55` assumes the moving subject is centre-frame. When the
movement is at the edges instead, that default aims features straight at the
motion and does worse than no masking at all; reach for `--keep` to box in
something genuinely static.

Watch the `features in border region:` line. It should be at or near
`--max-corners` (2000). OpenCV's corner threshold is relative to the strongest
corner *within the mask*, so a mask change can quietly collapse the count — and a
low count means a weak solve, not a faster one.

## Development

Run straight from a checkout, no install:

```bash
uv run align_burst.py '*.jpg' -o aligned --gif out.gif
```

## Releasing

The version is derived from the git tag by `hatch-vcs`, so there is no version
number to bump anywhere. Tag and push:

```bash
git tag v0.2.0
git push --tags
```

`.github/workflows/publish.yml` builds and uploads to PyPI via Trusted
Publishing — no API token is stored in the repo.
