Metadata-Version: 2.4
Name: photoworkbench
Version: 0.1.0
Summary: Photo Workbench CLI and GUI utilities.
Author: Your Name
License: MIT License
        
        Copyright (c) 2026 Julian Schweigert
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
        
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: Pillow>=9.0.0
Requires-Dist: numpy>=1.20.0
Requires-Dist: appdirs>=1.4.4
Requires-Dist: wxPython>=4.2.0
Dynamic: license-file

# Python Photo Workbench

<div align="center">
  <img src="./assets/photoworkbench.png" alt="MainApp" height="350">
  <img src="./assets/preview.png" alt="Preview" height="350">
</div>

PhotoWorkbench adds realistic borders, paper texture, soft edges, drop shadow, LUT color grading, and film grain to photos. It is a CLI-first tool with optional GUI application, presets and resource folders stored in your user config directory.

## Features

- Clean border layouts or polaroid-style frames
- Soft feathered edges and configurable drop shadow
- Paper texture with adjustable noise and blend strength
- Optional LUT color grading via .cube files
- Optional film grain with tunable parameters
- Preset support via JSON configuration files

## Install

```bash
pip install photoworkbench
```

## GUI Application

The pip package installs two launch modes:

- CLI mode: `photoworkbench` (same options as `pwb.py`)
- GUI mode: `photoworkbench-gui`

Start the GUI with:

```bash
photoworkbench-gui
```

## Example: Polaroid Frame

```bash
python src/photoworkbench/pwb.py input.jpg output.jpg \
  --border-size 100 \
  --border-color "245,242,235" \
  --polaroid \
  --polaroid-bottom-factor 1.8 \
  --soft-edges \
  --feather-radius 8 \
  --shadow \
  --shadow-offset 15 \
  --shadow-blur 12 \
  --texture \
  --texture-strength 0.15 \
  --noise-strength 20
```

## Example: LUT + Film Grain

```bash
python src/photoworkbench/pwb.py input.jpg output.jpg \
  --enable-lut \
  --lut-path "look.cube" \
  --lut-strength 0.85 \
  --enable-filmgrain \
  --filmgrain-scale 1.0 \
  --filmgrain-src-gamma 1.0 \
  --filmgrain-grain-power 0.7 \
  --filmgrain-highs 0.2 \
  --filmgrain-shadows 0.2 \
  --filmgrain-type 1 \
  --filmgrain-grain-sat 0.5 \
  --filmgrain-sharpen 1 \
  --filmgrain-seed 42
```

## Presets and Resource Paths

PhotoWorkbench looks for user presets and LUTs in the app config directory:

- Presets: `~/.config/photoworkbench/presets/`
- LUTs: `~/.config/photoworkbench/luts/`

You can pass an absolute path, a path relative to the current working directory, or just a filename that exists in the resource folder.

### Preset Format

Preset files are JSON and can contain any CLI option names. Example `my-border.json`:

```json
{
  "border_size": 120,
  "border_color": "245,242,235",
  "enable_shadow": true,
  "enable_soft_edges": true,
  "enable_texture": true,
  "feather_radius": 8,
  "shadow_offset": 12,
  "shadow_blur": 10,
  "texture_strength": 0.12,
  "noise_strength": 18
}
```

Use it with:

```bash
python src/photoworkbench/pwb.py input.jpg output.jpg --preset-path my-border.json
```

## CLI Reference

```text
usage: pwb.py [-h] [--preset-path PRESET_PATH] [--border-size BORDER_SIZE]
              [--border-size-percent BORDER_SIZE_PERCENT]
              [--border-color BORDER_COLOR] [--polaroid] [--enable-border]
              [--polaroid-bottom-factor POLAROID_BOTTOM_FACTOR] [--shadow]
              [--soft-edges] [--texture] [--enable-lut]
              [--lut-path LUT_PATH] [--lut-strength LUT_STRENGTH]
              [--enable-filmgrain] [--filmgrain-scale FILMGRAIN_SCALE]
              [--filmgrain-src-gamma FILMGRAIN_SRC_GAMMA]
              [--filmgrain-grain-power FILMGRAIN_GRAIN_POWER]
              [--filmgrain-highs FILMGRAIN_HIGHS]
              [--filmgrain-shadows FILMGRAIN_SHADOWS]
              [--filmgrain-type FILMGRAIN_TYPE]
              [--filmgrain-grain-sat FILMGRAIN_GRAIN_SAT]
              [--filmgrain-gray-scale] [--filmgrain-sharpen FILMGRAIN_SHARPEN]
              [--filmgrain-seed FILMGRAIN_SEED] [--feather-radius FEATHER_RADIUS]
              [--shadow-offset SHADOW_OFFSET] [--shadow-blur SHADOW_BLUR]
              [--texture-strength TEXTURE_STRENGTH]
              [--noise-strength NOISE_STRENGTH]
              input output
```

### Layout

- `--border-size` sets the border size in pixels for all sides.
- `--border-size-percent` uses a percentage of the image short side (overrides pixel size).
- `--border-color` takes `R,G,B` values, for example `"255,255,255"`.
- `--polaroid` enables a thicker bottom border.
- `--polaroid-bottom-factor` scales the bottom border height.
- `--enable-border` disables border generation.

### Styling

- `--soft-edges` disables feathered edges.
- `--feather-radius` controls the feather size in pixels.
- `--shadow` disables the drop shadow.
- `--shadow-offset` sets the shadow offset in pixels.
- `--shadow-blur` sets the shadow blur radius.
- `--texture` disables paper texture.
- `--texture-strength` blends texture with the background (0 to 1).
- `--noise-strength` controls texture noise intensity.
- Defaults: shadow, soft edges, and texture are off in the CLI; enable them in presets by setting `enable_shadow`, `enable_soft_edges`, and `enable_texture` to `true`.

### Color and Grain

- `--enable-lut` enables LUT color grading.
- `--lut-path` points to a `.cube` file.
- `--lut-strength` blends LUT results (0 to 1).
- `--enable-filmgrain` enables film grain processing.
- `--filmgrain-scale`, `--filmgrain-src-gamma`, `--filmgrain-grain-power` tune the base grain.
- `--filmgrain-highs`, `--filmgrain-shadows` tune highlights/shadows grain influence.
- `--filmgrain-type` selects a grain type preset.
- `--filmgrain-grain-sat` controls grain color saturation.
- `--filmgrain-gray-scale` forces monochrome grain.
- `--filmgrain-sharpen` applies sharpening passes.
- `--filmgrain-seed` sets a deterministic grain seed.

## Notes

The filmgrain algorithm is the work of "larspontoppidan" (https://github.com/larspontoppidan/filmgrainer).

- EXIF orientation is normalized so portrait images stay upright.
- EXIF metadata is preserved when available.

## Dependencies

- Pillow
- appdirs
- lut-tools
- filmgrainer

Install with your preferred Python packaging workflow, then run the CLI examples above.
