pixopt 1.0.5__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.
Files changed (51) hide show
  1. pixopt-1.0.5/.github/workflows/bump-version.yml +143 -0
  2. pixopt-1.0.5/.github/workflows/ci.yml +58 -0
  3. pixopt-1.0.5/.github/workflows/docs.yml +51 -0
  4. pixopt-1.0.5/.gitignore +48 -0
  5. pixopt-1.0.5/.readthedocs.yaml +16 -0
  6. pixopt-1.0.5/CHANGELOG.md +23 -0
  7. pixopt-1.0.5/CONTRIBUTING.md +38 -0
  8. pixopt-1.0.5/LICENSE +21 -0
  9. pixopt-1.0.5/MANIFEST.in +7 -0
  10. pixopt-1.0.5/PKG-INFO +304 -0
  11. pixopt-1.0.5/README.md +265 -0
  12. pixopt-1.0.5/docs/api.md +45 -0
  13. pixopt-1.0.5/docs/changelog.md +19 -0
  14. pixopt-1.0.5/docs/cli.md +144 -0
  15. pixopt-1.0.5/docs/contributing.md +27 -0
  16. pixopt-1.0.5/docs/index.md +59 -0
  17. pixopt-1.0.5/docs/installation.md +35 -0
  18. pixopt-1.0.5/docs/library.md +156 -0
  19. pixopt-1.0.5/mkdocs.yml +75 -0
  20. pixopt-1.0.5/pyproject.toml +94 -0
  21. pixopt-1.0.5/requirements-dev.txt +5 -0
  22. pixopt-1.0.5/requirements.txt +5 -0
  23. pixopt-1.0.5/setup.py +61 -0
  24. pixopt-1.0.5/src/pixopt/__init__.py +19 -0
  25. pixopt-1.0.5/src/pixopt/adaptive_quality.py +103 -0
  26. pixopt-1.0.5/src/pixopt/cli/__init__.py +17 -0
  27. pixopt-1.0.5/src/pixopt/cli/app.py +14 -0
  28. pixopt-1.0.5/src/pixopt/cli/commands/__init__.py +14 -0
  29. pixopt-1.0.5/src/pixopt/cli/commands/batch.py +90 -0
  30. pixopt-1.0.5/src/pixopt/cli/commands/compare.py +94 -0
  31. pixopt-1.0.5/src/pixopt/cli/commands/convert.py +110 -0
  32. pixopt-1.0.5/src/pixopt/cli/commands/favicon.py +52 -0
  33. pixopt-1.0.5/src/pixopt/cli/commands/info.py +44 -0
  34. pixopt-1.0.5/src/pixopt/cli/commands/optimize.py +159 -0
  35. pixopt-1.0.5/src/pixopt/cli/commands/placeholder.py +56 -0
  36. pixopt-1.0.5/src/pixopt/cli/commands/srcset.py +132 -0
  37. pixopt-1.0.5/src/pixopt/cli/options.py +123 -0
  38. pixopt-1.0.5/src/pixopt/cli/output.py +73 -0
  39. pixopt-1.0.5/src/pixopt/constants.py +45 -0
  40. pixopt-1.0.5/src/pixopt/format_resolver.py +35 -0
  41. pixopt-1.0.5/src/pixopt/html_comparison.py +200 -0
  42. pixopt-1.0.5/src/pixopt/image_ops.py +133 -0
  43. pixopt-1.0.5/src/pixopt/models.py +57 -0
  44. pixopt-1.0.5/src/pixopt/optimizer.py +474 -0
  45. pixopt-1.0.5/src/pixopt/placeholder.py +132 -0
  46. pixopt-1.0.5/src/pixopt/smart_format.py +101 -0
  47. pixopt-1.0.5/src/pixopt/srcset_generator.py +102 -0
  48. pixopt-1.0.5/src/pixopt/svg_optimizer.py +81 -0
  49. pixopt-1.0.5/src/pixopt/utils.py +22 -0
  50. pixopt-1.0.5/tests/__init__.py +0 -0
  51. pixopt-1.0.5/tests/test_core.py +358 -0
@@ -0,0 +1,143 @@
1
+ name: Bump Version and Publish
2
+
3
+ on:
4
+ push:
5
+ branches: [main, master]
6
+
7
+ permissions:
8
+ contents: write
9
+ id-token: write
10
+
11
+ jobs:
12
+ test:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - name: Checkout
16
+ uses: actions/checkout@v4
17
+ with:
18
+ fetch-depth: 0
19
+ token: ${{ secrets.PAT }}
20
+
21
+ - name: Set up Python
22
+ uses: actions/setup-python@v5
23
+ with:
24
+ python-version: "3.12"
25
+
26
+ - name: Install dependencies
27
+ run: |
28
+ python -m pip install --upgrade pip
29
+ pip install -e ".[dev]"
30
+
31
+ - name: Run tests
32
+ run: pytest tests/ -v --tb=short
33
+
34
+ - name: Run ruff
35
+ run: ruff check src tests
36
+
37
+ - name: Run mypy
38
+ run: mypy src
39
+
40
+ bump:
41
+ needs: test
42
+ runs-on: ubuntu-latest
43
+ outputs:
44
+ tag: ${{ steps.version.outputs.tag }}
45
+ steps:
46
+ - name: Checkout
47
+ uses: actions/checkout@v4
48
+ with:
49
+ fetch-depth: 0
50
+ token: ${{ secrets.PAT }}
51
+
52
+ - name: Set up Python
53
+ uses: actions/setup-python@v5
54
+ with:
55
+ python-version: "3.12"
56
+
57
+ - name: Install dependencies
58
+ run: |
59
+ python -m pip install --upgrade pip
60
+ pip install python-semantic-release build
61
+
62
+ - name: Configure Git
63
+ run: |
64
+ git config --global user.name "github-actions"
65
+ git config --global user.email "actions@github.com"
66
+
67
+ - name: Bump version and create tag
68
+ id: version
69
+ env:
70
+ GH_TOKEN: ${{ secrets.PAT }}
71
+ run: |
72
+ set -x
73
+ echo "Running semantic-release version..."
74
+ if semantic-release version; then
75
+ echo "Version bump succeeded"
76
+ git log --oneline -5
77
+ git tag -l
78
+ git remote -v
79
+ git push origin main --tags
80
+ echo "tag=$(git describe --tags --abbrev=0)" >> "$GITHUB_OUTPUT"
81
+ else
82
+ echo "No version bump needed or failed"
83
+ git log --oneline -5
84
+ git tag -l
85
+ echo "tag=" >> "$GITHUB_OUTPUT"
86
+ fi
87
+
88
+ build:
89
+ needs: bump
90
+ if: needs.bump.outputs.tag != ''
91
+ runs-on: ubuntu-latest
92
+ steps:
93
+ - name: Checkout
94
+ uses: actions/checkout@v4
95
+ with:
96
+ ref: ${{ needs.bump.outputs.tag }}
97
+ fetch-depth: 0
98
+
99
+ - name: Set up Python
100
+ uses: actions/setup-python@v5
101
+ with:
102
+ python-version: "3.12"
103
+
104
+ - name: Install build dependencies
105
+ run: |
106
+ python -m pip install --upgrade pip
107
+ pip install build
108
+
109
+ - name: Build distribution
110
+ run: python -m build
111
+
112
+ - name: Upload artifacts
113
+ uses: actions/upload-artifact@v4
114
+ with:
115
+ name: dist
116
+ path: dist/
117
+
118
+ publish-pypi:
119
+ needs: build
120
+ if: needs.bump.outputs.tag != ''
121
+ runs-on: ubuntu-latest
122
+ environment:
123
+ name: pypi
124
+ url: https://pypi.org/p/pixopt
125
+ permissions:
126
+ id-token: write
127
+ steps:
128
+ - name: Download artifacts
129
+ uses: actions/download-artifact@v4
130
+ with:
131
+ name: dist
132
+ path: dist/
133
+
134
+ - name: Publish to PyPI (Trusted Publishing)
135
+ id: trusted-publish
136
+ uses: pypa/gh-action-pypi-publish@release/v1
137
+ continue-on-error: true
138
+
139
+ - name: Publish to PyPI (Token fallback)
140
+ if: steps.trusted-publish.outcome == 'failure'
141
+ uses: pypa/gh-action-pypi-publish@release/v1
142
+ with:
143
+ password: ${{ secrets.PYPI_TOKEN }}
@@ -0,0 +1,58 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main, master]
6
+ pull_request:
7
+ branches: [main, master]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ${{ matrix.os }}
12
+ strategy:
13
+ fail-fast: false
14
+ matrix:
15
+ os: [ubuntu-latest, windows-latest]
16
+ python-version: ["3.10", "3.11", "3.12"]
17
+
18
+ steps:
19
+ - name: Checkout
20
+ uses: actions/checkout@v4
21
+
22
+ - name: Set up Python ${{ matrix.python-version }}
23
+ uses: actions/setup-python@v5
24
+ with:
25
+ python-version: ${{ matrix.python-version }}
26
+
27
+ - name: Install dependencies
28
+ run: |
29
+ python -m pip install --upgrade pip
30
+ pip install -e ".[dev]"
31
+
32
+ - name: Run tests
33
+ run: pytest tests/ -v --tb=short
34
+
35
+ - name: Run ruff
36
+ run: ruff check src tests
37
+
38
+ - name: Run mypy
39
+ run: mypy src
40
+
41
+ build-docs:
42
+ runs-on: ubuntu-latest
43
+ steps:
44
+ - name: Checkout
45
+ uses: actions/checkout@v4
46
+
47
+ - name: Set up Python
48
+ uses: actions/setup-python@v5
49
+ with:
50
+ python-version: "3.12"
51
+
52
+ - name: Install docs dependencies
53
+ run: |
54
+ python -m pip install --upgrade pip
55
+ pip install -e ".[docs]"
56
+
57
+ - name: Build docs
58
+ run: mkdocs build --strict
@@ -0,0 +1,51 @@
1
+ name: Docs
2
+
3
+ on:
4
+ push:
5
+ branches: [main, master]
6
+ workflow_dispatch:
7
+
8
+ permissions:
9
+ contents: read
10
+ pages: write
11
+ id-token: write
12
+
13
+ concurrency:
14
+ group: pages
15
+ cancel-in-progress: false
16
+
17
+ jobs:
18
+ build:
19
+ runs-on: ubuntu-latest
20
+ steps:
21
+ - name: Checkout
22
+ uses: actions/checkout@v4
23
+
24
+ - name: Set up Python
25
+ uses: actions/setup-python@v5
26
+ with:
27
+ python-version: "3.12"
28
+
29
+ - name: Install dependencies
30
+ run: |
31
+ python -m pip install --upgrade pip
32
+ pip install -e ".[docs]"
33
+
34
+ - name: Build docs
35
+ run: mkdocs build --strict
36
+
37
+ - name: Upload artifact
38
+ uses: actions/upload-pages-artifact@v3
39
+ with:
40
+ path: site/
41
+
42
+ deploy:
43
+ needs: build
44
+ runs-on: ubuntu-latest
45
+ environment:
46
+ name: github-pages
47
+ url: ${{ steps.deployment.outputs.page_url }}
48
+ steps:
49
+ - name: Deploy to GitHub Pages
50
+ id: deployment
51
+ uses: actions/deploy-pages@v4
@@ -0,0 +1,48 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *$py.class
4
+ *.so
5
+ .Python
6
+ build/
7
+ develop-eggs/
8
+ dist/
9
+ downloads/
10
+ eggs/
11
+ .eggs/
12
+ lib/
13
+ lib64/
14
+ parts/
15
+ sdist/
16
+ var/
17
+ wheels/
18
+ pip-wheel-metadata/
19
+ share/python-wheels/
20
+ *.egg-info/
21
+ .installed.cfg
22
+ *.egg
23
+ MANIFEST
24
+ .env
25
+ .venv
26
+ env/
27
+ venv/
28
+ ENV/
29
+ env.bak/
30
+ venv.bak/
31
+ .mypy_cache/
32
+ .dmypy.json
33
+ dmypy.json
34
+ .pytest_cache/
35
+ .coverage
36
+ htmlcov/
37
+ *.log
38
+ .DS_Store
39
+ Thumbs.db
40
+ *.jpg
41
+ *.jpeg
42
+ *.png
43
+ *.webp
44
+ *.avif
45
+ *.bmp
46
+ *.gif
47
+ *.tiff
48
+ !tests/fixtures/
@@ -0,0 +1,16 @@
1
+ version: 2
2
+
3
+ build:
4
+ os: ubuntu-24.04
5
+ tools:
6
+ python: "3.12"
7
+
8
+ python:
9
+ install:
10
+ - method: pip
11
+ path: .
12
+ extra_requirements:
13
+ - docs
14
+
15
+ mkdocs:
16
+ configuration: mkdocs.yml
@@ -0,0 +1,23 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ### Added
11
+
12
+ - Lossless compression mode for PNG/WEBP (`--lossless`).
13
+ - Interactive HTML before/after comparison slider (`pixopt compare`).
14
+ - Adaptive quality via binary search for target file size (`--target-size`).
15
+ - Responsive srcset image generation with HTML snippet output (`pixopt srcset`).
16
+ - Lazy-loading placeholders: dominant color, LQIP data URI, and blurhash (`pixopt placeholder`).
17
+ - Smart format detection: auto-select WEBP/JPEG/PNG based on image content (`--smart-format`).
18
+ - Backup originals before processing (`--backup`).
19
+ - Skip files below a minimum size threshold (`--min-size`).
20
+ - Animated GIF to animated WEBP conversion.
21
+ - Pure-Python SVG minification.
22
+ - HEIC/HEIF support via `pillow-heif`.
23
+ - GitHub Actions workflows for CI, release (PyPI), and documentation.
@@ -0,0 +1,38 @@
1
+ # Contributing
2
+
3
+ Thanks for your interest in contributing!
4
+
5
+ ## Development setup
6
+
7
+ 1. Clone the repository:
8
+ ```bash
9
+ git clone https://github.com/MathiasPaulenko/pixopt.git
10
+ cd pixopt
11
+ ```
12
+
13
+ 2. Create a virtual environment and install dependencies:
14
+ ```bash
15
+ python -m venv .venv
16
+ source .venv/bin/activate # Windows: .venv\Scripts\activate
17
+ pip install -e ".[dev]"
18
+ ```
19
+
20
+ ## Running tests
21
+
22
+ ```bash
23
+ pytest tests/ -v
24
+ ```
25
+
26
+ ## Code style
27
+
28
+ - Follow PEP 8.
29
+ - Use type hints where possible.
30
+ - Keep docstrings concise and descriptive.
31
+
32
+ ## Pull requests
33
+
34
+ 1. Fork the repository.
35
+ 2. Create a feature branch.
36
+ 3. Make your changes with tests.
37
+ 4. Ensure `pytest` passes.
38
+ 5. Submit a pull request with a clear description.
pixopt-1.0.5/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 ImgOptimizer contributors
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,7 @@
1
+ include README.md
2
+ include CHANGELOG.md
3
+ include LICENSE
4
+ recursive-include src *.py
5
+ recursive-exclude tests *
6
+ recursive-exclude .pytest_cache *
7
+ recursive-exclude __pycache__ *
pixopt-1.0.5/PKG-INFO ADDED
@@ -0,0 +1,304 @@
1
+ Metadata-Version: 2.4
2
+ Name: pixopt
3
+ Version: 1.0.5
4
+ Summary: Fast Python image optimizer. Resize, compress, convert, and generate responsive assets.
5
+ Project-URL: Homepage, https://github.com/MathiasPaulenko/pixopt
6
+ Project-URL: Repository, https://github.com/MathiasPaulenko/pixopt
7
+ Project-URL: Issues, https://github.com/MathiasPaulenko/pixopt/issues
8
+ Author-email: Mathias Paulenko Echeverz <mathias.paulenko@outlook.com>
9
+ License: MIT
10
+ License-File: LICENSE
11
+ Keywords: cli,compression,image,jpeg,optimization,png,webp
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Topic :: Multimedia :: Graphics
21
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
+ Requires-Python: >=3.9
23
+ Requires-Dist: piexif>=1.1.3
24
+ Requires-Dist: pillow-heif>=1.0.0
25
+ Requires-Dist: pillow>=10.0.0
26
+ Requires-Dist: rich>=13.0.0
27
+ Requires-Dist: typer>=0.12.0
28
+ Provides-Extra: dev
29
+ Requires-Dist: mypy>=1.10.0; extra == 'dev'
30
+ Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
31
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
32
+ Requires-Dist: python-semantic-release>=9.0.0; extra == 'dev'
33
+ Requires-Dist: ruff>=0.4.0; extra == 'dev'
34
+ Provides-Extra: docs
35
+ Requires-Dist: mkdocs-material>=9.5.0; extra == 'docs'
36
+ Requires-Dist: mkdocs>=1.6.0; extra == 'docs'
37
+ Requires-Dist: mkdocstrings[python]>=0.25.0; extra == 'docs'
38
+ Description-Content-Type: text/markdown
39
+
40
+ # pixopt
41
+
42
+ A powerful, easy-to-use Python library and CLI tool for optimizing images for web and storage.
43
+
44
+ ## Features
45
+
46
+ - **Size reduction** – resize images to maximum width/height while keeping aspect ratio
47
+ - **Format conversion** – convert between JPEG, PNG, WEBP, AVIF, GIF, HEIC/HEIF and SVG
48
+ - **Animated GIF → WEBP** – convert animated GIFs to much lighter animated WEBP
49
+ - **SVG minification** – pure-Python SVG cleanup (no Node.js tools needed)
50
+ - **HEIC/HEIF import** – open iPhone photos directly thanks to `pillow-heif`
51
+ - **Lossless mode** – lossless PNG/WEBP compression for UI assets that need pixel-perfect fidelity
52
+ - **Adaptive quality** – binary-search quality to hit a target file size automatically
53
+ - **Visual comparison** – generate interactive HTML before/after sliders
54
+ - **Responsive srcset** – generate multiple width variants and HTML `<img srcset="...">` snippets
55
+ - **Lazy-loading placeholders** – extract dominant color, generate LQIP data URIs, or blurhash strings
56
+ - **Smart format detection** – auto-detect the most efficient format (photo → WEBP, graphic → PNG, transparent → WEBP)
57
+ - **Backup originals** – copy originals to a backup directory before processing
58
+ - **Min-size filter** – skip files already below a size threshold
59
+ - **Metadata stripping** – remove EXIF and other metadata to save space
60
+ - **Quality tuning** – adjustable compression quality (1-100)
61
+ - **Progressive JPEG** – enable progressive encoding for better web delivery
62
+ - **Batch processing** – optimize single files, directories, or multiple files at once
63
+ - **CLI with Typer** – intuitive command-line interface with beautiful output
64
+
65
+ ## Installation
66
+
67
+ ```bash
68
+ pip install pixopt
69
+ ```
70
+
71
+ ## CLI Usage
72
+
73
+ ### Optimize a single image
74
+
75
+ ```bash
76
+ pixopt optimize photo.jpg photo_optimized.jpg --quality 80 --width 1200
77
+ ```
78
+
79
+ ### Optimize all images in a directory
80
+
81
+ ```bash
82
+ pixopt optimize ./images ./optimized --recursive --quality 85 --format webp
83
+ ```
84
+
85
+ ### Batch optimize specific files
86
+
87
+ ```bash
88
+ pixopt batch photo1.jpg photo2.png photo3.bmp -o ./optimized --width 800
89
+ ```
90
+
91
+ ### Convert image format / extension
92
+
93
+ ```bash
94
+ pixopt convert photo.png photo.webp -f webp
95
+ pixopt convert ./images ./webp_images -r -f webp
96
+ ```
97
+
98
+ ### Generate favicon (.ico)
99
+
100
+ ```bash
101
+ pixopt favicon logo.png favicon.ico
102
+ pixopt favicon logo.png --size 16 --size 32 --size 48
103
+ ```
104
+
105
+ ### Convert animated GIF to animated WEBP
106
+
107
+ ```bash
108
+ pixopt convert animation.gif animation.webp -f webp
109
+ ```
110
+
111
+ ### Optimize SVG
112
+
113
+ ```bash
114
+ pixopt convert icon.svg icon.min.svg
115
+ ```
116
+
117
+ ### Convert HEIC (iPhone) to JPEG
118
+
119
+ ```bash
120
+ pixopt convert photo.heic photo.jpg
121
+ ```
122
+
123
+ ### Lossless PNG/WEBP for UI assets
124
+
125
+ ```bash
126
+ pixopt convert icon.png icon.webp --lossless -f webp
127
+ ```
128
+
129
+ ### Adaptive quality (target file size)
130
+
131
+ ```bash
132
+ pixopt optimize photo.jpg --target-size 50
133
+ ```
134
+
135
+ ### Generate visual comparison HTML
136
+
137
+ ```bash
138
+ pixopt compare photo.jpg comparison.html --open
139
+ ```
140
+
141
+ ### Generate responsive srcset images
142
+
143
+ ```bash
144
+ pixopt srcset hero.jpg --sizes 320,640,1024,1920 --output-dir ./responsive/
145
+ pixopt srcset hero.jpg --sizes 320,640,1024,1920 -f webp --html snippet.html
146
+ ```
147
+
148
+ ### Generate lazy-loading placeholders
149
+
150
+ ```bash
151
+ pixopt placeholder photo.jpg --type color
152
+ pixopt placeholder photo.jpg --type lqip
153
+ pixopt placeholder photo.jpg --type blurhash -o blurhash.txt
154
+ ```
155
+
156
+ ### Smart format detection
157
+
158
+ ```bash
159
+ pixopt optimize photo.jpg --smart-format
160
+ pixopt convert graphic.png output --smart-format
161
+ ```
162
+
163
+ ### Backup originals before processing
164
+
165
+ ```bash
166
+ pixopt optimize ./images --backup ./originals --recursive
167
+ ```
168
+
169
+ ### Skip already-optimized files
170
+
171
+ ```bash
172
+ pixopt optimize ./images --min-size 10 --recursive
173
+ ```
174
+
175
+ ### Inspect image info without optimizing
176
+
177
+ ```bash
178
+ pixopt info photo.jpg
179
+ ```
180
+
181
+ ### Available options
182
+
183
+ | Option | Description |
184
+ |--------|-------------|
185
+ | `-q, --quality` | JPEG/WEBP quality (1-100, default: 85) |
186
+ | `-w, --width` | Maximum width in pixels |
187
+ | `-h, --height` | Maximum height in pixels |
188
+ | `-f, --format` | Output format: auto, jpeg, png, webp, avif, original |
189
+ | `-s, --strip` | Remove metadata (default: True) |
190
+ | `--progressive` | Progressive JPEG encoding (default: True) |
191
+ | `-r, --recursive` | Process directories recursively |
192
+ | `--overwrite` | Overwrite source files |
193
+ | `--lossless` | Lossless PNG/WEBP compression |
194
+ | `--target-size` | Target file size in KB (adaptive quality) |
195
+ | `--smart-format` | Auto-detect the most efficient output format |
196
+ | `--backup` | Backup originals to this directory |
197
+ | `--min-size` | Skip files already smaller than this threshold (KB) |
198
+
199
+ ## Library Usage
200
+
201
+ ```python
202
+ from pixopt import optimize_image
203
+ from pixopt.models import OutputFormat
204
+
205
+ # Optimize a single image
206
+ result = optimize_image(
207
+ "photo.jpg",
208
+ "photo_optimized.webp",
209
+ max_width=1200,
210
+ quality=80,
211
+ strip_metadata=True,
212
+ output_format=OutputFormat.WEBP,
213
+ )
214
+
215
+ print(f"Saved {result.savings_percent:.1f}% ({result.human_savings})")
216
+ ```
217
+
218
+ ### Placeholders for lazy loading
219
+
220
+ ```python
221
+ from pixopt.placeholder import generate_placeholder
222
+
223
+ color = generate_placeholder("photo.jpg", placeholder_type="color")
224
+ lqip = generate_placeholder("photo.jpg", placeholder_type="lqip")
225
+ blurhash = generate_placeholder("photo.jpg", placeholder_type="blurhash")
226
+ ```
227
+
228
+ ### Smart format detection
229
+
230
+ ```python
231
+ from pixopt.smart_format import detect_optimal_format
232
+
233
+ fmt = detect_optimal_format("photo.jpg")
234
+ # Returns OutputFormat.WEBP for photos, PNG for graphics, WEBP for transparent images
235
+ ```
236
+
237
+ ### Responsive srcset generation
238
+
239
+ ```python
240
+ from pixopt.srcset_generator import generate_srcset_images
241
+
242
+ variants = generate_srcset_images(
243
+ "hero.jpg",
244
+ "./responsive",
245
+ widths=[320, 640, 1024, 1920],
246
+ output_format="WEBP",
247
+ quality=80,
248
+ )
249
+ for v in variants:
250
+ print(f"{v.width}px -> {v.size_bytes} bytes")
251
+ ```
252
+
253
+ ### Batch / directory processing
254
+
255
+ ```python
256
+ from pixopt import optimize_directory
257
+
258
+ results = optimize_directory(
259
+ "./images",
260
+ "./optimized",
261
+ recursive=True,
262
+ max_width=800,
263
+ quality=75,
264
+ output_format=OutputFormat.WEBP,
265
+ )
266
+
267
+ for r in results:
268
+ if r.success:
269
+ print(f"{r.source_path.name}: {r.savings_percent:.1f}% saved")
270
+ ```
271
+
272
+ ## Development
273
+
274
+ Install in development mode:
275
+
276
+ ```bash
277
+ git clone https://github.com/MathiasPaulenko/pixopt.git
278
+ cd pixopt
279
+ pip install -e ".[dev]"
280
+ ```
281
+
282
+ Run tests:
283
+
284
+ ```bash
285
+ pytest
286
+ ```
287
+
288
+ Run linter:
289
+
290
+ ```bash
291
+ ruff check src tests
292
+ mypy src
293
+ ```
294
+
295
+ Build documentation locally:
296
+
297
+ ```bash
298
+ pip install -e ".[docs]"
299
+ mkdocs serve
300
+ ```
301
+
302
+ ## License
303
+
304
+ MIT