agentbrush 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- agentbrush-0.1.0/.gitignore +16 -0
- agentbrush-0.1.0/CHANGELOG.md +48 -0
- agentbrush-0.1.0/LICENSE +21 -0
- agentbrush-0.1.0/PKG-INFO +251 -0
- agentbrush-0.1.0/README.md +220 -0
- agentbrush-0.1.0/docs/architecture.md +119 -0
- agentbrush-0.1.0/docs/examples/mug_pipeline.md +204 -0
- agentbrush-0.1.0/docs/examples/sticker_pipeline.md +169 -0
- agentbrush-0.1.0/docs/examples/tshirt_pipeline.md +167 -0
- agentbrush-0.1.0/fonts/DejaVuSansMono-Bold.ttf +0 -0
- agentbrush-0.1.0/fonts/DejaVuSansMono.ttf +0 -0
- agentbrush-0.1.0/fonts/JetBrainsMono-Bold.ttf +0 -0
- agentbrush-0.1.0/fonts/JetBrainsMono-Regular.ttf +0 -0
- agentbrush-0.1.0/fonts/OFL.txt +100 -0
- agentbrush-0.1.0/fonts/SpaceMono-Bold.ttf +0 -0
- agentbrush-0.1.0/fonts/SpaceMono-Regular.ttf +0 -0
- agentbrush-0.1.0/pyproject.toml +48 -0
- agentbrush-0.1.0/skill/agent-brush/SKILL.md +165 -0
- agentbrush-0.1.0/skill/agent-brush/references/product-specs.md +121 -0
- agentbrush-0.1.0/skill/agent-brush/references/troubleshooting.md +114 -0
- agentbrush-0.1.0/skill/agent-brush/scripts/add_text.py +87 -0
- agentbrush-0.1.0/skill/agent-brush/scripts/border_cleanup.py +42 -0
- agentbrush-0.1.0/skill/agent-brush/scripts/composite.py +83 -0
- agentbrush-0.1.0/skill/agent-brush/scripts/convert.py +44 -0
- agentbrush-0.1.0/skill/agent-brush/scripts/generate.py +43 -0
- agentbrush-0.1.0/skill/agent-brush/scripts/greenscreen.py +43 -0
- agentbrush-0.1.0/skill/agent-brush/scripts/remove_bg.py +45 -0
- agentbrush-0.1.0/skill/agent-brush/scripts/resize.py +45 -0
- agentbrush-0.1.0/skill/agent-brush/scripts/validate.py +50 -0
- agentbrush-0.1.0/src/agentbrush/__init__.py +38 -0
- agentbrush-0.1.0/src/agentbrush/__main__.py +4 -0
- agentbrush-0.1.0/src/agentbrush/background/__init__.py +3 -0
- agentbrush-0.1.0/src/agentbrush/background/cli.py +51 -0
- agentbrush-0.1.0/src/agentbrush/background/ops.py +77 -0
- agentbrush-0.1.0/src/agentbrush/border/__init__.py +3 -0
- agentbrush-0.1.0/src/agentbrush/border/cli.py +50 -0
- agentbrush-0.1.0/src/agentbrush/border/ops.py +150 -0
- agentbrush-0.1.0/src/agentbrush/cli.py +65 -0
- agentbrush-0.1.0/src/agentbrush/composite/__init__.py +3 -0
- agentbrush-0.1.0/src/agentbrush/composite/cli.py +169 -0
- agentbrush-0.1.0/src/agentbrush/composite/ops.py +129 -0
- agentbrush-0.1.0/src/agentbrush/convert/__init__.py +3 -0
- agentbrush-0.1.0/src/agentbrush/convert/cli.py +44 -0
- agentbrush-0.1.0/src/agentbrush/convert/ops.py +104 -0
- agentbrush-0.1.0/src/agentbrush/core/__init__.py +17 -0
- agentbrush-0.1.0/src/agentbrush/core/alpha.py +65 -0
- agentbrush-0.1.0/src/agentbrush/core/color.py +70 -0
- agentbrush-0.1.0/src/agentbrush/core/connectivity.py +102 -0
- agentbrush-0.1.0/src/agentbrush/core/flood_fill.py +82 -0
- agentbrush-0.1.0/src/agentbrush/core/fonts.py +121 -0
- agentbrush-0.1.0/src/agentbrush/core/geometry.py +84 -0
- agentbrush-0.1.0/src/agentbrush/core/result.py +63 -0
- agentbrush-0.1.0/src/agentbrush/generate/__init__.py +3 -0
- agentbrush-0.1.0/src/agentbrush/generate/cli.py +40 -0
- agentbrush-0.1.0/src/agentbrush/generate/ops.py +179 -0
- agentbrush-0.1.0/src/agentbrush/greenscreen/__init__.py +3 -0
- agentbrush-0.1.0/src/agentbrush/greenscreen/cli.py +50 -0
- agentbrush-0.1.0/src/agentbrush/greenscreen/ops.py +132 -0
- agentbrush-0.1.0/src/agentbrush/resize/__init__.py +3 -0
- agentbrush-0.1.0/src/agentbrush/resize/cli.py +42 -0
- agentbrush-0.1.0/src/agentbrush/resize/ops.py +101 -0
- agentbrush-0.1.0/src/agentbrush/text/__init__.py +3 -0
- agentbrush-0.1.0/src/agentbrush/text/cli.py +70 -0
- agentbrush-0.1.0/src/agentbrush/text/ops.py +173 -0
- agentbrush-0.1.0/src/agentbrush/validate/__init__.py +3 -0
- agentbrush-0.1.0/src/agentbrush/validate/cli.py +50 -0
- agentbrush-0.1.0/src/agentbrush/validate/ops.py +379 -0
- agentbrush-0.1.0/tests/conftest.py +104 -0
- agentbrush-0.1.0/tests/test_background.py +79 -0
- agentbrush-0.1.0/tests/test_border.py +72 -0
- agentbrush-0.1.0/tests/test_cli.py +304 -0
- agentbrush-0.1.0/tests/test_composite.py +122 -0
- agentbrush-0.1.0/tests/test_convert.py +81 -0
- agentbrush-0.1.0/tests/test_core_connectivity.py +57 -0
- agentbrush-0.1.0/tests/test_core_flood_fill.py +92 -0
- agentbrush-0.1.0/tests/test_core_fonts.py +32 -0
- agentbrush-0.1.0/tests/test_core_geometry.py +67 -0
- agentbrush-0.1.0/tests/test_generate.py +87 -0
- agentbrush-0.1.0/tests/test_greenscreen.py +61 -0
- agentbrush-0.1.0/tests/test_resize.py +107 -0
- agentbrush-0.1.0/tests/test_text.py +117 -0
- agentbrush-0.1.0/tests/test_validate.py +189 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.1 (2026-03-11)
|
|
4
|
+
|
|
5
|
+
### CLI
|
|
6
|
+
- Added `paste-centered` subcommand to `agentbrush composite` — center artwork on a new canvas with `--canvas WxH`, `--fit`, `--bg-color` options
|
|
7
|
+
- Fixed README composite syntax: removed spurious `overlay` subcommand prefix
|
|
8
|
+
|
|
9
|
+
### Docs
|
|
10
|
+
- Fixed `text` CLI examples in SKILL.md and README — removed nonexistent `add`/`render` subcommands, correct syntax is `agentbrush text <input> <output> <text>` (use `new:WxH` as input for blank canvas)
|
|
11
|
+
- Fixed `--font mono-bold` → `--font mono --bold` (CLI uses separate flag)
|
|
12
|
+
- Fixed README standalone requirements: Python >= 3.10 + Pillow >= 12.1 (was "pip install Pillow")
|
|
13
|
+
|
|
14
|
+
### Tests
|
|
15
|
+
- 126 tests (up from 122)
|
|
16
|
+
|
|
17
|
+
## 0.1.0 (2026-03-11)
|
|
18
|
+
|
|
19
|
+
Initial release.
|
|
20
|
+
|
|
21
|
+
### Core Library
|
|
22
|
+
- `agentbrush.core`: flood fill, color matching, alpha ops, geometry, connectivity, fonts, Result dataclass
|
|
23
|
+
- Edge-based flood fill (BFS from edges only) — never threshold-based removal
|
|
24
|
+
- Cross-platform font discovery with bundled Space Mono, JetBrains Mono, DejaVu Sans Mono
|
|
25
|
+
|
|
26
|
+
### Modules
|
|
27
|
+
- `background`: Solid-color background removal via edge-based flood fill
|
|
28
|
+
- `greenscreen`: Multi-pass green screen pipeline (flood fill + color sweep + post-upscale sweep)
|
|
29
|
+
- `border`: White border erosion + green halo cleanup + alpha edge smoothing
|
|
30
|
+
- `text`: Pillow text rendering with textbbox y-offset correction and getmetrics() line height
|
|
31
|
+
- `composite`: Alpha compositing with overlay positioning and centered paste
|
|
32
|
+
- `resize`: Scale, fit, pad modes with LANCZOS resampling
|
|
33
|
+
- `validate`: Design QA — dimensions, aspect ratio, transparency, sticker layout/complexity detection
|
|
34
|
+
- `convert`: Format conversion (PNG, JPEG, WEBP, BMP, TIFF) with RGBA->RGB alpha flattening
|
|
35
|
+
- `generate`: AI image generation via OpenAI GPT Image and Pollinations (optional dependency)
|
|
36
|
+
|
|
37
|
+
### CLI
|
|
38
|
+
- `agentbrush <command>` dispatcher with 9 subcommands
|
|
39
|
+
- Uniform exit codes: 0=success, 1=validation fail, 2=input error
|
|
40
|
+
|
|
41
|
+
### Agent Skills Package
|
|
42
|
+
- `skill/agent-brush/SKILL.md` — Agent Skills standard entrypoint
|
|
43
|
+
- `skill/agent-brush/references/` — product specs, troubleshooting guide
|
|
44
|
+
- `skill/agent-brush/scripts/` — standalone wrappers (work without pip install)
|
|
45
|
+
|
|
46
|
+
### Documentation
|
|
47
|
+
- Pipeline guides: sticker, t-shirt, mug
|
|
48
|
+
- 122 tests (all synthetic fixtures)
|
agentbrush-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 ultrathink.art
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: agentbrush
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Image editing toolkit for AI agents. Photoshop for Claude Code, Codex, Cursor, and friends.
|
|
5
|
+
Project-URL: Homepage, https://github.com/ultrathink-art/agentbrush
|
|
6
|
+
Project-URL: Repository, https://github.com/ultrathink-art/agentbrush
|
|
7
|
+
Project-URL: Issues, https://github.com/ultrathink-art/agentbrush/issues
|
|
8
|
+
Author-email: Ultrathink <ceo@ultrathink.art>
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: ai-agents,background-removal,greenscreen,image-editing,pillow
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Topic :: Multimedia :: Graphics
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Requires-Dist: pillow>=12.1
|
|
23
|
+
Provides-Extra: all
|
|
24
|
+
Requires-Dist: openai>=1.0; extra == 'all'
|
|
25
|
+
Provides-Extra: dev
|
|
26
|
+
Requires-Dist: pytest-cov; extra == 'dev'
|
|
27
|
+
Requires-Dist: pytest>=7.0; extra == 'dev'
|
|
28
|
+
Provides-Extra: generate
|
|
29
|
+
Requires-Dist: openai>=1.0; extra == 'generate'
|
|
30
|
+
Description-Content-Type: text/markdown
|
|
31
|
+
|
|
32
|
+
# AgentBrush
|
|
33
|
+
|
|
34
|
+
[](https://pypi.org/project/agentbrush/)
|
|
35
|
+
[](https://python.org)
|
|
36
|
+
[](LICENSE)
|
|
37
|
+
[](https://agentskills.io)
|
|
38
|
+
[](#testing)
|
|
39
|
+
|
|
40
|
+
Image editing toolkit for AI agents. Photoshop for Claude Code, Codex, Cursor, and friends.
|
|
41
|
+
|
|
42
|
+
Built from 134 production sessions of print-on-demand image processing. Battle-tested algorithms for background removal, green screen processing, border cleanup, text rendering, compositing, validation, and more.
|
|
43
|
+
|
|
44
|
+
## Install
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
pip install agentbrush
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
With AI image generation support:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
pip install agentbrush[generate]
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Quick Start
|
|
57
|
+
|
|
58
|
+
### Python API
|
|
59
|
+
|
|
60
|
+
```python
|
|
61
|
+
from agentbrush import remove_background, remove_greenscreen, cleanup_border
|
|
62
|
+
|
|
63
|
+
# Remove black background (edge-based flood fill, safe for artwork)
|
|
64
|
+
result = remove_background("input.png", "output.png", color="black", threshold=25)
|
|
65
|
+
print(result.summary())
|
|
66
|
+
# [OK] output.png
|
|
67
|
+
# Size: 1024x1024px
|
|
68
|
+
# Transparent: 72.3% Opaque: 27.7%
|
|
69
|
+
# pixels_removed: 758432
|
|
70
|
+
|
|
71
|
+
# Remove green screen (multi-pass: flood fill + color sweep)
|
|
72
|
+
result = remove_greenscreen("input.png", "output.png", halo_passes=20)
|
|
73
|
+
|
|
74
|
+
# Clean up white sticker border from AI-generated art
|
|
75
|
+
result = cleanup_border("input.png", "output.png", passes=15, threshold=185)
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Every function returns a `Result` object:
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
result.success # True if no errors
|
|
82
|
+
result.width # Output width in px
|
|
83
|
+
result.height # Output height in px
|
|
84
|
+
result.transparent_pct # Percentage of transparent pixels
|
|
85
|
+
result.warnings # Non-fatal issues
|
|
86
|
+
result.errors # Fatal issues
|
|
87
|
+
result.metadata # Operation-specific data
|
|
88
|
+
result.summary() # Human-readable string
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### CLI
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
# Background removal
|
|
95
|
+
agentbrush remove-bg input.png output.png --color black --threshold 25 --smooth
|
|
96
|
+
|
|
97
|
+
# Green screen removal
|
|
98
|
+
agentbrush greenscreen input.png output.png --upscale 3 --halo-passes 20
|
|
99
|
+
|
|
100
|
+
# Border cleanup
|
|
101
|
+
agentbrush border-cleanup input.png output.png --passes 15 --green-halo-passes 20
|
|
102
|
+
|
|
103
|
+
# Text rendering
|
|
104
|
+
agentbrush text input.png output.png "HELLO" --font mono --bold --size 72
|
|
105
|
+
agentbrush text new:1664x1664 output.png "BUG\nFEATURE" --bold --center
|
|
106
|
+
|
|
107
|
+
# Compositing
|
|
108
|
+
agentbrush composite base.png art.png output.png --position 100,200
|
|
109
|
+
agentbrush composite paste-centered output.png --overlay art.png --canvas 4500x5400 --fit
|
|
110
|
+
|
|
111
|
+
# Resize
|
|
112
|
+
agentbrush resize input.png output.png --width 4500 --height 5400
|
|
113
|
+
agentbrush resize input.png output.png --scale 3.0
|
|
114
|
+
agentbrush resize input.png output.png --width 2700 --height 1050 --fit --pad
|
|
115
|
+
|
|
116
|
+
# Validate design against product specs
|
|
117
|
+
agentbrush validate check design.png --type sticker
|
|
118
|
+
agentbrush validate compare source.png processed.png --max-loss 10
|
|
119
|
+
|
|
120
|
+
# Format conversion
|
|
121
|
+
agentbrush convert input.png output.jpg --quality 95
|
|
122
|
+
|
|
123
|
+
# AI image generation (requires openai package)
|
|
124
|
+
agentbrush generate --provider openai --prompt "cat coding" --output cat.png
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Exit codes: `0` = success, `1` = validation failure, `2` = input error.
|
|
128
|
+
|
|
129
|
+
## Agent Skills
|
|
130
|
+
|
|
131
|
+
AgentBrush ships as an [Agent Skills](https://agentskills.io) package. Copy `skill/agent-brush/` into your project's `.claude/skills/` directory:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
cp -r skill/agent-brush/ .claude/skills/agent-brush/
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Claude Code (and other compatible tools) will automatically discover the skill and use it when processing images. The skill includes:
|
|
138
|
+
|
|
139
|
+
- **SKILL.md** — instructions and quick reference for the agent
|
|
140
|
+
- **references/** — product specs, troubleshooting guides
|
|
141
|
+
- **scripts/** — standalone wrappers that work without `pip install`
|
|
142
|
+
|
|
143
|
+
## Usage Without Install
|
|
144
|
+
|
|
145
|
+
The standalone scripts work directly from a git clone — no `pip install` needed:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
git clone https://github.com/ultrathink-art/agentbrush.git
|
|
149
|
+
cd agentbrush
|
|
150
|
+
|
|
151
|
+
# Run scripts directly (auto-detects src/ directory)
|
|
152
|
+
python skill/agent-brush/scripts/remove_bg.py input.png output.png --color black
|
|
153
|
+
python skill/agent-brush/scripts/validate.py check design.png --type sticker
|
|
154
|
+
python skill/agent-brush/scripts/greenscreen.py input.png output.png --upscale 3
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Requirements: **Python >= 3.10** and **Pillow >= 12.1** (`pip install 'Pillow>=12.1'`). Older versions fail at runtime (`get_flattened_data` API requires Pillow 12.1+, type union syntax requires Python 3.10+).
|
|
158
|
+
|
|
159
|
+
## Modules
|
|
160
|
+
|
|
161
|
+
| Module | Description | Key function |
|
|
162
|
+
|--------|-------------|-------------|
|
|
163
|
+
| `background` | Edge-based flood fill bg removal | `remove_background()` |
|
|
164
|
+
| `greenscreen` | Multi-pass green screen pipeline | `remove_greenscreen()` |
|
|
165
|
+
| `border` | White border erosion + green halo | `cleanup_border()` |
|
|
166
|
+
| `text` | Pillow text rendering (accurate) | `add_text()`, `render_text()` |
|
|
167
|
+
| `composite` | Image layering + centering | `composite()`, `paste_centered()` |
|
|
168
|
+
| `resize` | Resize with fit/pad/scale modes | `resize_image()` |
|
|
169
|
+
| `validate` | Design QA against product specs | `validate_design()`, `compare_images()` |
|
|
170
|
+
| `convert` | Format conversion (PNG/JPEG/WEBP) | `convert_image()` |
|
|
171
|
+
| `generate` | AI image generation (optional) | `generate_image()` |
|
|
172
|
+
|
|
173
|
+
## Core Primitives
|
|
174
|
+
|
|
175
|
+
Low-level functions available for custom pipelines:
|
|
176
|
+
|
|
177
|
+
```python
|
|
178
|
+
from agentbrush.core import (
|
|
179
|
+
flood_fill_from_edges, # BFS flood fill (4-conn or 8-conn)
|
|
180
|
+
is_near_color, # Color distance matching
|
|
181
|
+
parse_color, # Parse "black", "white", "R,G,B" strings
|
|
182
|
+
smooth_edges, # 1px edge feathering
|
|
183
|
+
smooth_alpha_edges, # Gaussian alpha blur (edges only)
|
|
184
|
+
find_artwork_bounds, # Opaque pixel bounding box
|
|
185
|
+
crop_to_content, # Crop to content with padding
|
|
186
|
+
find_opaque_centroid, # Center of mass for opaque region
|
|
187
|
+
ensure_single_shape, # Remove floating elements (8-connected BFS)
|
|
188
|
+
count_components, # Connected component count
|
|
189
|
+
find_font, # Cross-platform font discovery
|
|
190
|
+
)
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## Product Presets
|
|
194
|
+
|
|
195
|
+
Built-in dimensions for print-on-demand products:
|
|
196
|
+
|
|
197
|
+
| Product | Width | Height | Transparent | Notes |
|
|
198
|
+
|---------|-------|--------|-------------|-------|
|
|
199
|
+
| T-shirt | 4500 | 5400 | Required | Apparel |
|
|
200
|
+
| Hoodie | 4500 | 5400 | Required | Apparel |
|
|
201
|
+
| Hat | 1890 | 765 | Required | Wide horizontal |
|
|
202
|
+
| Mug (11oz) | 2700 | 1050 | Recommended | Wrap-around |
|
|
203
|
+
| Sticker | 1664 | 1664 | Required | Die-cut, single shape |
|
|
204
|
+
| Desk mat | 9200 | 4500 | No | Large format |
|
|
205
|
+
| Poster | 5400 | 7200 | No | Portrait |
|
|
206
|
+
|
|
207
|
+
## Why Edge-Based Flood Fill?
|
|
208
|
+
|
|
209
|
+
Threshold-based removal (`magick -fuzz -transparent black`) scans every pixel and removes anything "close enough" to the target color — including internal outlines, dark shadows, and fine details inside the artwork.
|
|
210
|
+
|
|
211
|
+
AgentBrush starts flood fill from image edges only. Interior pixels that happen to match the background color are never touched because flood fill can't reach them without crossing through the artwork.
|
|
212
|
+
|
|
213
|
+
```
|
|
214
|
+
Threshold-based: Edge-based flood fill:
|
|
215
|
+
removes ALL dark pixels removes ONLY edge-connected dark pixels
|
|
216
|
+
+-----------------+ +-----------------+
|
|
217
|
+
| | | |
|
|
218
|
+
| ######### | | ######### |
|
|
219
|
+
| # # | <- loses | #*********# | <- preserved!
|
|
220
|
+
| # # | detail | #*********# |
|
|
221
|
+
| ######### | | ######### |
|
|
222
|
+
| | | |
|
|
223
|
+
+-----------------+ +-----------------+
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
## Examples
|
|
227
|
+
|
|
228
|
+
Full pipeline guides with code:
|
|
229
|
+
|
|
230
|
+
- [Sticker Pipeline](docs/examples/sticker_pipeline.md) — AI art -> green screen -> border cleanup -> validate die-cut
|
|
231
|
+
- [T-Shirt Pipeline](docs/examples/tshirt_pipeline.md) — artwork -> transparent bg -> resize to 4500x5400
|
|
232
|
+
- [Mug Pipeline](docs/examples/mug_pipeline.md) — sticker adaptation -> wrap format -> multi-sticker composition
|
|
233
|
+
|
|
234
|
+
## Testing
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
pip install -e ".[dev]"
|
|
238
|
+
pytest tests/ -v
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
All tests use synthetic Pillow-generated fixtures (no production images). 126 tests covering all modules.
|
|
242
|
+
|
|
243
|
+
## Dependencies
|
|
244
|
+
|
|
245
|
+
- **Required**: `Pillow >= 12.1`
|
|
246
|
+
- **Optional**: `openai >= 1.0` (for `generate` command)
|
|
247
|
+
- **Dev**: `pytest >= 7.0`, `pytest-cov`
|
|
248
|
+
|
|
249
|
+
## License
|
|
250
|
+
|
|
251
|
+
MIT
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
# AgentBrush
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/agentbrush/)
|
|
4
|
+
[](https://python.org)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
[](https://agentskills.io)
|
|
7
|
+
[](#testing)
|
|
8
|
+
|
|
9
|
+
Image editing toolkit for AI agents. Photoshop for Claude Code, Codex, Cursor, and friends.
|
|
10
|
+
|
|
11
|
+
Built from 134 production sessions of print-on-demand image processing. Battle-tested algorithms for background removal, green screen processing, border cleanup, text rendering, compositing, validation, and more.
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pip install agentbrush
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
With AI image generation support:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pip install agentbrush[generate]
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Quick Start
|
|
26
|
+
|
|
27
|
+
### Python API
|
|
28
|
+
|
|
29
|
+
```python
|
|
30
|
+
from agentbrush import remove_background, remove_greenscreen, cleanup_border
|
|
31
|
+
|
|
32
|
+
# Remove black background (edge-based flood fill, safe for artwork)
|
|
33
|
+
result = remove_background("input.png", "output.png", color="black", threshold=25)
|
|
34
|
+
print(result.summary())
|
|
35
|
+
# [OK] output.png
|
|
36
|
+
# Size: 1024x1024px
|
|
37
|
+
# Transparent: 72.3% Opaque: 27.7%
|
|
38
|
+
# pixels_removed: 758432
|
|
39
|
+
|
|
40
|
+
# Remove green screen (multi-pass: flood fill + color sweep)
|
|
41
|
+
result = remove_greenscreen("input.png", "output.png", halo_passes=20)
|
|
42
|
+
|
|
43
|
+
# Clean up white sticker border from AI-generated art
|
|
44
|
+
result = cleanup_border("input.png", "output.png", passes=15, threshold=185)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Every function returns a `Result` object:
|
|
48
|
+
|
|
49
|
+
```python
|
|
50
|
+
result.success # True if no errors
|
|
51
|
+
result.width # Output width in px
|
|
52
|
+
result.height # Output height in px
|
|
53
|
+
result.transparent_pct # Percentage of transparent pixels
|
|
54
|
+
result.warnings # Non-fatal issues
|
|
55
|
+
result.errors # Fatal issues
|
|
56
|
+
result.metadata # Operation-specific data
|
|
57
|
+
result.summary() # Human-readable string
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### CLI
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
# Background removal
|
|
64
|
+
agentbrush remove-bg input.png output.png --color black --threshold 25 --smooth
|
|
65
|
+
|
|
66
|
+
# Green screen removal
|
|
67
|
+
agentbrush greenscreen input.png output.png --upscale 3 --halo-passes 20
|
|
68
|
+
|
|
69
|
+
# Border cleanup
|
|
70
|
+
agentbrush border-cleanup input.png output.png --passes 15 --green-halo-passes 20
|
|
71
|
+
|
|
72
|
+
# Text rendering
|
|
73
|
+
agentbrush text input.png output.png "HELLO" --font mono --bold --size 72
|
|
74
|
+
agentbrush text new:1664x1664 output.png "BUG\nFEATURE" --bold --center
|
|
75
|
+
|
|
76
|
+
# Compositing
|
|
77
|
+
agentbrush composite base.png art.png output.png --position 100,200
|
|
78
|
+
agentbrush composite paste-centered output.png --overlay art.png --canvas 4500x5400 --fit
|
|
79
|
+
|
|
80
|
+
# Resize
|
|
81
|
+
agentbrush resize input.png output.png --width 4500 --height 5400
|
|
82
|
+
agentbrush resize input.png output.png --scale 3.0
|
|
83
|
+
agentbrush resize input.png output.png --width 2700 --height 1050 --fit --pad
|
|
84
|
+
|
|
85
|
+
# Validate design against product specs
|
|
86
|
+
agentbrush validate check design.png --type sticker
|
|
87
|
+
agentbrush validate compare source.png processed.png --max-loss 10
|
|
88
|
+
|
|
89
|
+
# Format conversion
|
|
90
|
+
agentbrush convert input.png output.jpg --quality 95
|
|
91
|
+
|
|
92
|
+
# AI image generation (requires openai package)
|
|
93
|
+
agentbrush generate --provider openai --prompt "cat coding" --output cat.png
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Exit codes: `0` = success, `1` = validation failure, `2` = input error.
|
|
97
|
+
|
|
98
|
+
## Agent Skills
|
|
99
|
+
|
|
100
|
+
AgentBrush ships as an [Agent Skills](https://agentskills.io) package. Copy `skill/agent-brush/` into your project's `.claude/skills/` directory:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
cp -r skill/agent-brush/ .claude/skills/agent-brush/
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Claude Code (and other compatible tools) will automatically discover the skill and use it when processing images. The skill includes:
|
|
107
|
+
|
|
108
|
+
- **SKILL.md** — instructions and quick reference for the agent
|
|
109
|
+
- **references/** — product specs, troubleshooting guides
|
|
110
|
+
- **scripts/** — standalone wrappers that work without `pip install`
|
|
111
|
+
|
|
112
|
+
## Usage Without Install
|
|
113
|
+
|
|
114
|
+
The standalone scripts work directly from a git clone — no `pip install` needed:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
git clone https://github.com/ultrathink-art/agentbrush.git
|
|
118
|
+
cd agentbrush
|
|
119
|
+
|
|
120
|
+
# Run scripts directly (auto-detects src/ directory)
|
|
121
|
+
python skill/agent-brush/scripts/remove_bg.py input.png output.png --color black
|
|
122
|
+
python skill/agent-brush/scripts/validate.py check design.png --type sticker
|
|
123
|
+
python skill/agent-brush/scripts/greenscreen.py input.png output.png --upscale 3
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Requirements: **Python >= 3.10** and **Pillow >= 12.1** (`pip install 'Pillow>=12.1'`). Older versions fail at runtime (`get_flattened_data` API requires Pillow 12.1+, type union syntax requires Python 3.10+).
|
|
127
|
+
|
|
128
|
+
## Modules
|
|
129
|
+
|
|
130
|
+
| Module | Description | Key function |
|
|
131
|
+
|--------|-------------|-------------|
|
|
132
|
+
| `background` | Edge-based flood fill bg removal | `remove_background()` |
|
|
133
|
+
| `greenscreen` | Multi-pass green screen pipeline | `remove_greenscreen()` |
|
|
134
|
+
| `border` | White border erosion + green halo | `cleanup_border()` |
|
|
135
|
+
| `text` | Pillow text rendering (accurate) | `add_text()`, `render_text()` |
|
|
136
|
+
| `composite` | Image layering + centering | `composite()`, `paste_centered()` |
|
|
137
|
+
| `resize` | Resize with fit/pad/scale modes | `resize_image()` |
|
|
138
|
+
| `validate` | Design QA against product specs | `validate_design()`, `compare_images()` |
|
|
139
|
+
| `convert` | Format conversion (PNG/JPEG/WEBP) | `convert_image()` |
|
|
140
|
+
| `generate` | AI image generation (optional) | `generate_image()` |
|
|
141
|
+
|
|
142
|
+
## Core Primitives
|
|
143
|
+
|
|
144
|
+
Low-level functions available for custom pipelines:
|
|
145
|
+
|
|
146
|
+
```python
|
|
147
|
+
from agentbrush.core import (
|
|
148
|
+
flood_fill_from_edges, # BFS flood fill (4-conn or 8-conn)
|
|
149
|
+
is_near_color, # Color distance matching
|
|
150
|
+
parse_color, # Parse "black", "white", "R,G,B" strings
|
|
151
|
+
smooth_edges, # 1px edge feathering
|
|
152
|
+
smooth_alpha_edges, # Gaussian alpha blur (edges only)
|
|
153
|
+
find_artwork_bounds, # Opaque pixel bounding box
|
|
154
|
+
crop_to_content, # Crop to content with padding
|
|
155
|
+
find_opaque_centroid, # Center of mass for opaque region
|
|
156
|
+
ensure_single_shape, # Remove floating elements (8-connected BFS)
|
|
157
|
+
count_components, # Connected component count
|
|
158
|
+
find_font, # Cross-platform font discovery
|
|
159
|
+
)
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Product Presets
|
|
163
|
+
|
|
164
|
+
Built-in dimensions for print-on-demand products:
|
|
165
|
+
|
|
166
|
+
| Product | Width | Height | Transparent | Notes |
|
|
167
|
+
|---------|-------|--------|-------------|-------|
|
|
168
|
+
| T-shirt | 4500 | 5400 | Required | Apparel |
|
|
169
|
+
| Hoodie | 4500 | 5400 | Required | Apparel |
|
|
170
|
+
| Hat | 1890 | 765 | Required | Wide horizontal |
|
|
171
|
+
| Mug (11oz) | 2700 | 1050 | Recommended | Wrap-around |
|
|
172
|
+
| Sticker | 1664 | 1664 | Required | Die-cut, single shape |
|
|
173
|
+
| Desk mat | 9200 | 4500 | No | Large format |
|
|
174
|
+
| Poster | 5400 | 7200 | No | Portrait |
|
|
175
|
+
|
|
176
|
+
## Why Edge-Based Flood Fill?
|
|
177
|
+
|
|
178
|
+
Threshold-based removal (`magick -fuzz -transparent black`) scans every pixel and removes anything "close enough" to the target color — including internal outlines, dark shadows, and fine details inside the artwork.
|
|
179
|
+
|
|
180
|
+
AgentBrush starts flood fill from image edges only. Interior pixels that happen to match the background color are never touched because flood fill can't reach them without crossing through the artwork.
|
|
181
|
+
|
|
182
|
+
```
|
|
183
|
+
Threshold-based: Edge-based flood fill:
|
|
184
|
+
removes ALL dark pixels removes ONLY edge-connected dark pixels
|
|
185
|
+
+-----------------+ +-----------------+
|
|
186
|
+
| | | |
|
|
187
|
+
| ######### | | ######### |
|
|
188
|
+
| # # | <- loses | #*********# | <- preserved!
|
|
189
|
+
| # # | detail | #*********# |
|
|
190
|
+
| ######### | | ######### |
|
|
191
|
+
| | | |
|
|
192
|
+
+-----------------+ +-----------------+
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## Examples
|
|
196
|
+
|
|
197
|
+
Full pipeline guides with code:
|
|
198
|
+
|
|
199
|
+
- [Sticker Pipeline](docs/examples/sticker_pipeline.md) — AI art -> green screen -> border cleanup -> validate die-cut
|
|
200
|
+
- [T-Shirt Pipeline](docs/examples/tshirt_pipeline.md) — artwork -> transparent bg -> resize to 4500x5400
|
|
201
|
+
- [Mug Pipeline](docs/examples/mug_pipeline.md) — sticker adaptation -> wrap format -> multi-sticker composition
|
|
202
|
+
|
|
203
|
+
## Testing
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
pip install -e ".[dev]"
|
|
207
|
+
pytest tests/ -v
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
All tests use synthetic Pillow-generated fixtures (no production images). 126 tests covering all modules.
|
|
211
|
+
|
|
212
|
+
## Dependencies
|
|
213
|
+
|
|
214
|
+
- **Required**: `Pillow >= 12.1`
|
|
215
|
+
- **Optional**: `openai >= 1.0` (for `generate` command)
|
|
216
|
+
- **Dev**: `pytest >= 7.0`, `pytest-cov`
|
|
217
|
+
|
|
218
|
+
## License
|
|
219
|
+
|
|
220
|
+
MIT
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
## Design Principles
|
|
4
|
+
|
|
5
|
+
1. **Edge-based flood fill only** — never threshold-based pixel removal
|
|
6
|
+
2. **Uniform Result type** — every operation returns `Result` with the same fields
|
|
7
|
+
3. **CLI mirrors API** — every Python function has a CLI subcommand
|
|
8
|
+
4. **Cross-platform** — no hardcoded OS paths; bundled fonts as fallback
|
|
9
|
+
5. **Minimal dependencies** — only Pillow required; OpenAI optional
|
|
10
|
+
6. **Standalone scripts** — work from git clone without pip install
|
|
11
|
+
|
|
12
|
+
## Directory Layout
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
agentbrush/
|
|
16
|
+
├── src/agentbrush/ # Python package (pip installable)
|
|
17
|
+
│ ├── __init__.py # Public API re-exports
|
|
18
|
+
│ ├── __main__.py # python -m agentbrush
|
|
19
|
+
│ ├── cli.py # Top-level argparse dispatcher
|
|
20
|
+
│ ├── core/ # Shared primitives
|
|
21
|
+
│ │ ├── flood_fill.py # BFS flood fill (4/8-connectivity)
|
|
22
|
+
│ │ ├── color.py # Color matching, parsing
|
|
23
|
+
│ │ ├── alpha.py # Alpha channel ops, edge smoothing
|
|
24
|
+
│ │ ├── geometry.py # Bounds, crop, centroid
|
|
25
|
+
│ │ ├── connectivity.py # Die-cut single shape (8-connected BFS)
|
|
26
|
+
│ │ ├── fonts.py # Cross-platform font discovery
|
|
27
|
+
│ │ └── result.py # Uniform Result dataclass
|
|
28
|
+
│ └── <module>/ # Each module has:
|
|
29
|
+
│ ├── __init__.py # Re-export from ops
|
|
30
|
+
│ ├── cli.py # argparse subcommand registration
|
|
31
|
+
│ └── ops.py # Core logic + public function
|
|
32
|
+
├── skill/agent-brush/ # Agent Skills package
|
|
33
|
+
│ ├── SKILL.md # Agent instructions + quick reference
|
|
34
|
+
│ ├── references/ # Product specs, troubleshooting
|
|
35
|
+
│ └── scripts/ # Standalone wrappers
|
|
36
|
+
├── fonts/ # Bundled OFL fonts
|
|
37
|
+
├── tests/ # pytest suite (synthetic fixtures)
|
|
38
|
+
└── docs/examples/ # Pipeline guides
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Module Pattern
|
|
42
|
+
|
|
43
|
+
Every operation module follows the same structure:
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
module/
|
|
47
|
+
├── __init__.py # from .ops import main_function
|
|
48
|
+
├── cli.py # add_parser(subparsers) + run(args) -> exit_code
|
|
49
|
+
└── ops.py # main_function(...) -> Result
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**ops.py** contains the core logic. It:
|
|
53
|
+
- Accepts `Union[str, Path]` for file paths
|
|
54
|
+
- Returns `Result` with stats
|
|
55
|
+
- Sets `Result.errors` on failure (never raises exceptions to callers)
|
|
56
|
+
- Prints nothing (caller prints `result.summary()`)
|
|
57
|
+
|
|
58
|
+
**cli.py** registers an argparse subparser and converts CLI args to function calls.
|
|
59
|
+
|
|
60
|
+
**__init__.py** re-exports the main function for `from agentbrush.module import func`.
|
|
61
|
+
|
|
62
|
+
## Result Dataclass
|
|
63
|
+
|
|
64
|
+
All operations return `Result`:
|
|
65
|
+
|
|
66
|
+
```python
|
|
67
|
+
@dataclass
|
|
68
|
+
class Result:
|
|
69
|
+
output_path: Optional[Path]
|
|
70
|
+
width: int
|
|
71
|
+
height: int
|
|
72
|
+
transparent_pct: float # 0-100
|
|
73
|
+
opaque_pct: float # 0-100
|
|
74
|
+
warnings: list[str] # Non-fatal issues
|
|
75
|
+
errors: list[str] # Fatal issues
|
|
76
|
+
metadata: dict[str, Any] # Operation-specific data
|
|
77
|
+
|
|
78
|
+
@property
|
|
79
|
+
def success(self) -> bool:
|
|
80
|
+
return len(self.errors) == 0
|
|
81
|
+
|
|
82
|
+
def summary(self) -> str:
|
|
83
|
+
"""Human-readable string for stdout."""
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Flood Fill Algorithm
|
|
87
|
+
|
|
88
|
+
The core differentiator. BFS from all 4 edges simultaneously:
|
|
89
|
+
|
|
90
|
+
1. Seed queue with all border pixels matching target color
|
|
91
|
+
2. BFS expands to adjacent matching pixels (4-connectivity default)
|
|
92
|
+
3. Set matched pixels to transparent (alpha=0)
|
|
93
|
+
4. Interior pixels matching the color are never reached
|
|
94
|
+
|
|
95
|
+
This preserves internal outlines and details that threshold-based removal destroys.
|
|
96
|
+
|
|
97
|
+
## Font Discovery
|
|
98
|
+
|
|
99
|
+
Search order:
|
|
100
|
+
1. Bundled fonts in `fonts/` directory (Space Mono, JetBrains Mono, DejaVu)
|
|
101
|
+
2. System directories (macOS, Linux, Windows platform-specific paths)
|
|
102
|
+
3. Pillow default fallback
|
|
103
|
+
|
|
104
|
+
Name aliases map friendly names to filenames: `mono` -> `SpaceMono-Regular.ttf`, `jetbrains-bold` -> `JetBrainsMono-Bold.ttf`, etc.
|
|
105
|
+
|
|
106
|
+
## Standalone Script Pattern
|
|
107
|
+
|
|
108
|
+
Each script in `skill/agent-brush/scripts/` uses this auto-detection:
|
|
109
|
+
|
|
110
|
+
```python
|
|
111
|
+
_script_dir = os.path.dirname(os.path.abspath(__file__))
|
|
112
|
+
_src_dir = os.path.join(_script_dir, "..", "..", "..", "src")
|
|
113
|
+
if os.path.isdir(_src_dir):
|
|
114
|
+
sys.path.insert(0, _src_dir)
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
This makes scripts work both:
|
|
118
|
+
- **Standalone**: `python scripts/remove_bg.py` (finds `src/` relative to script)
|
|
119
|
+
- **Installed**: `python scripts/remove_bg.py` (imports from site-packages)
|