API Reference¶
Core optimization¶
optimize_image(source: Path | str, output: Path | str | None = None, *, max_width: int | None = None, max_height: int | None = None, quality: int = 85, strip_metadata: bool = True, output_format: OutputFormat = OutputFormat.AUTO, keep_aspect_ratio: bool = True, progressive: bool = True, optimize: bool = True, overwrite: bool = False, lossless: bool = False, backup_dir: Path | str | None = None, min_size_bytes: int | None = None) -> OptimizationResult
¶
Optimize a single image.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
Path | str
|
Path to the source image. |
required |
output
|
Path | str | None
|
Path for the optimized image. If None, overwrites source (if overwrite=True). |
None
|
max_width
|
int | None
|
Maximum width in pixels. None means no resize. |
None
|
max_height
|
int | None
|
Maximum height in pixels. None means no resize. |
None
|
quality
|
int
|
JPEG/WEBP quality (1-100). Higher is better quality, larger file. |
85
|
strip_metadata
|
bool
|
Remove EXIF and other metadata. |
True
|
output_format
|
OutputFormat
|
Target format. AUTO infers from output path or original. |
AUTO
|
keep_aspect_ratio
|
bool
|
Maintain aspect ratio when resizing. |
True
|
progressive
|
bool
|
Use progressive JPEG encoding. |
True
|
optimize
|
bool
|
Enable Pillow optimization flags. |
True
|
overwrite
|
bool
|
Allow overwriting the source file when output is None. |
False
|
lossless
|
bool
|
Use lossless compression for PNG/WEBP. Ignored for JPEG. |
False
|
backup_dir
|
Path | str | None
|
Directory to copy the original file into before processing. |
None
|
min_size_bytes
|
int | None
|
Skip files already smaller than this threshold (bytes). |
None
|
Returns:
| Type | Description |
|---|---|
OptimizationResult
|
OptimizationResult with details of the operation. |
Source code in src/pixopt/optimizer.py
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 | |
optimize_directory(source_dir: Path | str, output_dir: Path | str | None = None, *, recursive: bool = False, extensions: Iterable[str] | None = None, backup_dir: Path | str | None = None, min_size_bytes: int | None = None, **kwargs: object) -> list[OptimizationResult]
¶
Optimize all images in a directory.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source_dir
|
Path | str
|
Directory containing images. |
required |
output_dir
|
Path | str | None
|
Destination directory. If None, overwrites in-place. |
None
|
recursive
|
bool
|
Search subdirectories. |
False
|
extensions
|
Iterable[str] | None
|
File extensions to process. Defaults to common image types. |
None
|
backup_dir
|
Path | str | None
|
Directory to copy originals into before processing. |
None
|
min_size_bytes
|
int | None
|
Skip files already smaller than this threshold (bytes). |
None
|
**kwargs
|
object
|
Passed to optimize_image. |
{}
|
Returns:
| Type | Description |
|---|---|
list[OptimizationResult]
|
List of OptimizationResult for each processed file. |
Source code in src/pixopt/optimizer.py
change_extension(source: Path | str, output: Path | str | None = None, *, output_format: OutputFormat = OutputFormat.AUTO, backup_dir: Path | str | None = None, min_size_bytes: int | None = None, **kwargs: object) -> OptimizationResult
¶
Convert an image to a different file format / extension.
This is a thin wrapper around optimize_image focused on format conversion. All other optimization parameters are forwarded.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
Path | str
|
Path to the source image. |
required |
output
|
Path | str | None
|
Destination path. If None, overwrites source (requires overwrite=True). |
None
|
output_format
|
OutputFormat
|
Target format. Defaults to inferring from output path. |
AUTO
|
backup_dir
|
Path | str | None
|
Directory to copy originals into before processing. |
None
|
min_size_bytes
|
int | None
|
Skip files already smaller than this threshold (bytes). |
None
|
**kwargs
|
object
|
Passed to optimize_image. |
{}
|
Returns:
| Type | Description |
|---|---|
OptimizationResult
|
OptimizationResult with details of the conversion. |
Source code in src/pixopt/optimizer.py
convert_to_favicon(source: Path | str, output: Path | str | None = None, *, sizes: list[int] | None = None, background: tuple[int, int, int] = (255, 255, 255), keep_transparency: bool = True) -> OptimizationResult
¶
Convert an image to a multi-resolution ICO favicon.
Generates a .ico file containing multiple square resolutions suitable for browser tabs, bookmarks and high-DPI displays.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
Path | str
|
Path to the source image. |
required |
output
|
Path | str | None
|
Output .ico path. If None, uses source name with .ico extension. |
None
|
sizes
|
list[int] | None
|
List of square sizes to include. Default: [16, 32, 48, 64, 128, 256]. |
None
|
background
|
tuple[int, int, int]
|
RGB fill for transparent images when keep_transparency=False. |
(255, 255, 255)
|
keep_transparency
|
bool
|
Preserve alpha channel if present. |
True
|
Returns:
| Type | Description |
|---|---|
OptimizationResult
|
OptimizationResult with details of the operation. |
Source code in src/pixopt/optimizer.py
367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 | |
Models¶
OptimizationResult(source_path: Path, output_path: Path, original_size: int, optimized_size: int, savings_bytes: int, savings_percent: float, width: int, height: int, format: str, metadata_removed: bool, success: bool, error: str | None = None)
dataclass
¶
Result of an image optimization operation.
Attributes¶
source_path: Path
instance-attribute
¶
output_path: Path
instance-attribute
¶
original_size: int
instance-attribute
¶
optimized_size: int
instance-attribute
¶
savings_bytes: int
instance-attribute
¶
savings_percent: float
instance-attribute
¶
width: int
instance-attribute
¶
height: int
instance-attribute
¶
format: str
instance-attribute
¶
metadata_removed: bool
instance-attribute
¶
success: bool
instance-attribute
¶
error: str | None = None
class-attribute
instance-attribute
¶
human_original_size: str
property
¶
human_optimized_size: str
property
¶
human_savings: str
property
¶
OutputFormat
¶
Bases: str, Enum
Supported output formats.
Attributes¶
AUTO = 'auto'
class-attribute
instance-attribute
¶
JPEG = 'jpeg'
class-attribute
instance-attribute
¶
PNG = 'png'
class-attribute
instance-attribute
¶
WEBP = 'webp'
class-attribute
instance-attribute
¶
AVIF = 'avif'
class-attribute
instance-attribute
¶
ORIGINAL = 'original'
class-attribute
instance-attribute
¶
Placeholders¶
generate_placeholder(image_path: Path, *, placeholder_type: PlaceholderType = 'lqip', lqip_size: int = 32, lqip_quality: int = 20) -> str
¶
Generate a placeholder string for an image.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
image_path
|
Path
|
Path to the source image. |
required |
placeholder_type
|
PlaceholderType
|
One of 'color', 'lqip', 'blurhash'. |
'lqip'
|
lqip_size
|
int
|
Max thumbnail dimension for LQIP. |
32
|
lqip_quality
|
int
|
JPEG quality for LQIP. |
20
|
Returns:
| Type | Description |
|---|---|
str
|
A CSS color string, base64 data URI, or blurhash string. |
Source code in src/pixopt/placeholder.py
extract_dominant_color(img: Image.Image) -> str
¶
Return the dominant color of an image as a hex CSS string.
Uses a downsample + average approach for accuracy.
Source code in src/pixopt/placeholder.py
generate_lqip_datauri(img: Image.Image, *, size: int = 32, quality: int = 20) -> str
¶
Generate a tiny blurred placeholder image as a base64 data URI.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
img
|
Image
|
Source PIL Image. |
required |
size
|
int
|
Maximum dimension of the thumbnail (maintains aspect ratio). |
32
|
quality
|
int
|
JPEG quality for the tiny image (low = smaller). |
20
|
Returns:
| Type | Description |
|---|---|
str
|
A base64 data URI string like 'data:image/jpeg;base64,/9j/4AAQ...'. |
Source code in src/pixopt/placeholder.py
generate_blurhash(img: Image.Image, *, components_x: int = 4, components_y: int = 3) -> str
¶
Generate a simplified blurhash-like string from an image.
This is a pure-Python approximation that encodes average colors of a grid into a compact base-83 string. It is NOT the official BlurHash algorithm, but produces visually similar short placeholders.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
img
|
Image
|
Source PIL Image. |
required |
components_x
|
int
|
Number of horizontal grid cells. |
4
|
components_y
|
int
|
Number of vertical grid cells. |
3
|
Returns:
| Type | Description |
|---|---|
str
|
A short blurhash-like string. |
Source code in src/pixopt/placeholder.py
Smart format detection¶
detect_optimal_format(image_path: Path | str, *, allow_lossy: bool = True, allow_lossless: bool = True, allow_animation: bool = True) -> OutputFormat
¶
Analyze an image and return the most efficient output format.
Rules
- Transparent image → WEBP (or PNG if lossless only)
- Animated image → WEBP
- Photograph with many colors → WEBP (or JPEG if no WEBP)
- Graphic/UI with few colors → WEBP lossless or PNG
Source code in src/pixopt/smart_format.py
Srcset generation¶
generate_srcset_images(source: Path | str, output_dir: Path | str, widths: list[int], *, quality: int = 85, output_format: str = 'WEBP', strip_metadata: bool = True, progressive: bool = True, optimize: bool = True, lossless: bool = False) -> list[SrcsetImage]
¶
Generate resized variants of an image for responsive srcset.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
Path | str
|
Path to the source image. |
required |
output_dir
|
Path | str
|
Directory where variants will be saved. |
required |
widths
|
list[int]
|
List of target widths in pixels. Each variant will have this width, preserving aspect ratio. |
required |
quality
|
int
|
JPEG/WEBP quality (1-100). |
85
|
output_format
|
str
|
Pillow format string for output (e.g. "WEBP", "JPEG"). |
'WEBP'
|
strip_metadata
|
bool
|
Remove EXIF and other metadata. |
True
|
progressive
|
bool
|
Use progressive JPEG encoding. |
True
|
optimize
|
bool
|
Enable Pillow optimizer. |
True
|
lossless
|
bool
|
Use lossless compression for PNG/WEBP. |
False
|
Returns:
| Type | Description |
|---|---|
list[SrcsetImage]
|
List of SrcsetImage entries, sorted by width ascending. |
Source code in src/pixopt/srcset_generator.py
SrcsetImage(width: int, output_path: Path, size_bytes: int)
dataclass
¶
Adaptive quality¶
find_quality_for_target_size(img: Image.Image, pillow_fmt: str, target_size: int, *, max_width: int | None = None, max_height: int | None = None, keep_aspect_ratio: bool = True, strip_metadata: bool = True, progressive: bool = True, optimize: bool = True, lossless: bool = False, min_quality: int = 1, max_quality: int = 100, tolerance: float = 0.05, max_iterations: int = 8) -> int
¶
Find the JPEG/WEBP quality that produces a file closest to target_size.
Uses binary search over quality (1-100) and measures the actual encoded file size in memory. Returns the quality value that yields a size closest to but not exceeding the target.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
img
|
Image
|
Open PIL Image. |
required |
pillow_fmt
|
str
|
Target Pillow format (JPEG or WEBP). |
required |
target_size
|
int
|
Target file size in bytes. |
required |
max_width
|
int | None
|
Maximum width in pixels, or None. |
None
|
max_height
|
int | None
|
Maximum height in pixels, or None. |
None
|
keep_aspect_ratio
|
bool
|
Whether to keep the original aspect ratio. |
True
|
strip_metadata
|
bool
|
Whether to strip metadata before saving. |
True
|
progressive
|
bool
|
Whether to use progressive encoding. |
True
|
optimize
|
bool
|
Whether to optimize the output. |
True
|
lossless
|
bool
|
Whether to use lossless compression. |
False
|
min_quality
|
int
|
Lowest quality to try. |
1
|
max_quality
|
int
|
Highest quality to try. |
100
|
tolerance
|
float
|
Fractional tolerance around target_size (e.g. 0.05 = 5%). |
0.05
|
max_iterations
|
int
|
Maximum binary-search iterations. |
8
|
Returns:
| Type | Description |
|---|---|
int
|
Quality integer (1-100). |
Source code in src/pixopt/adaptive_quality.py
Visual comparison¶
generate_comparison_html(before_path: Path, after_path: Path, output_html: Path, title: str = 'Image Comparison') -> Path
¶
Generate a self-contained HTML file with an interactive before/after slider.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
before_path
|
Path
|
Path to the original image. |
required |
after_path
|
Path
|
Path to the optimized image. |
required |
output_html
|
Path
|
Path where the HTML file will be saved. |
required |
title
|
str
|
Page title displayed above the slider. |
'Image Comparison'
|
Returns:
| Type | Description |
|---|---|
Path
|
Path to the generated HTML file. |