Python bindings for the colopresso image compression library. Encode PNG images to WebP, AVIF, or optimized PNG (PNGX) formats.
Important
AVX2 instruction set support is required on x86_64 (amd64) platforms. Intel Haswell (2013) or later, or AMD Excavator or later processors are required.
| Platform | Architecture | Requirements |
|---|---|---|
| Windows | x64 | AVX2 support |
| Windows | ARM64 | NEON (ASIMD) |
| macOS | x86_64 | AVX2 support |
| macOS | arm64 (Apple Silicon) | NEON (ASIMD) |
| Linux (glibc) | x86_64 | AVX2 support |
| Linux (glibc) | aarch64 | NEON (ASIMD) |
| Linux (musl) | x86_64 | AVX2 support |
| Linux (musl) | aarch64 | NEON (ASIMD) |
pip install "colopresso"cd python
pip install .cd python
pip install -e ".[dev]"import colopresso
# Read PNG file
with open("input.png", "rb") as f:
png_data = f.read()
# Convert to WebP
webp_data = colopresso.encode_webp(png_data)
with open("output.webp", "wb") as f:
f.write(webp_data)
# Convert to AVIF
avif_data = colopresso.encode_avif(png_data)
with open("output.avif", "wb") as f:
f.write(avif_data)
# Optimize PNG
optimized_png = colopresso.encode_pngx(png_data)
with open("output.png", "wb") as f:
f.write(optimized_png)Encode PNG data to WebP format.
Parameters:
png_data(bytes): Raw PNG file dataconfig(Config, optional): Encoding configuration. Uses defaults if not provided.
Returns:
- bytes: WebP encoded data
Raises:
ColopressoError: If encoding fails
Example:
import colopresso
with open("input.png", "rb") as f:
png_data = f.read()
# Default settings
webp_data = colopresso.encode_webp(png_data)
# Custom quality
config = colopresso.Config(webp_quality=90.0)
webp_data = colopresso.encode_webp(png_data, config)Encode PNG data to AVIF format.
Parameters:
png_data(bytes): Raw PNG file dataconfig(Config, optional): Encoding configuration. Uses defaults if not provided.
Returns:
- bytes: AVIF encoded data
Raises:
ColopressoError: If encoding fails (including when output is larger than input)
Example:
import colopresso
with open("input.png", "rb") as f:
png_data = f.read()
config = colopresso.Config(avif_quality=70.0, avif_speed=4)
avif_data = colopresso.encode_avif(png_data, config)Optimize PNG data using the PNGX encoder. Supports both lossless and lossy compression.
Parameters:
png_data(bytes): Raw PNG file dataconfig(Config, optional): Encoding configuration. Uses defaults if not provided.
Returns:
- bytes: Optimized PNG data
Raises:
ColopressoError: If encoding fails
Example:
import colopresso
with open("input.png", "rb") as f:
png_data = f.read()
# 256-color palette optimization
config = colopresso.Config(
pngx_lossy_enable=True,
pngx_lossy_type=colopresso.PngxLossyType.PALETTE256,
pngx_lossy_max_colors=256
)
optimized = colopresso.encode_pngx(png_data, config)The Config dataclass holds all encoder settings.
@dataclass
class Config:
# WebP settings
webp_quality: float = 80.0
webp_lossless: bool = False
webp_method: int = 6
# AVIF settings
avif_quality: float = 50.0
avif_alpha_quality: int = 100
avif_lossless: bool = False
avif_speed: int = 6
avif_threads: int = 1
# PNGX settings
pngx_level: int = 5
pngx_strip_safe: bool = True
pngx_optimize_alpha: bool = True
pngx_lossy_enable: bool = True
pngx_lossy_type: PngxLossyType = PngxLossyType.PALETTE256
pngx_lossy_max_colors: int = 256
pngx_lossy_quality_min: int = 80
pngx_lossy_quality_max: int = 95
pngx_lossy_speed: int = 3
pngx_lossy_dither_level: float = 0.6
pngx_threads: int = 1Specifies the type of lossy compression for PNGX.
class PngxLossyType(IntEnum):
PALETTE256 = 0 # 256-color indexed palette
LIMITED_RGBA4444 = 1 # RGBA4444 limited (16-bit color)
REDUCED_RGBA32 = 2 # Reduced color RGBA32| Value | Description | Use Case |
|---|---|---|
PALETTE256 |
Convert to 256-color indexed palette | Icons, illustrations with few colors |
LIMITED_RGBA4444 |
Limit each RGBA channel to 4 bits | Prevents banding artifacts in RGBA16bit and RGBA4444 |
REDUCED_RGBA32 |
Reduce colors while keeping RGBA32 | When PALETTE256 is not acceptable |
| Parameter | Type | Default | Description |
|---|---|---|---|
webp_quality |
float | 80.0 | Quality (0.0-100.0). Higher = better quality, larger size |
webp_lossless |
bool | False | True: lossless compression, False: lossy compression |
webp_method |
int | 6 | Compression method (0-6). Higher = better compression, slower |
Advanced WebP Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
webp_target_size |
int | 0 | Target file size in bytes. 0 = disabled |
webp_target_psnr |
float | 0.0 | Target PSNR in dB. 0 = disabled |
webp_segments |
int | 4 | Number of segments (1-4) |
webp_sns_strength |
int | 50 | Spatial noise shaping strength (0-100) |
webp_filter_strength |
int | 60 | Deblocking filter strength (0-100) |
webp_filter_sharpness |
int | 0 | Filter sharpness (0-7). 0 = sharpest |
webp_filter_type |
int | 1 | Filter type. 0 = simple, 1 = strong |
webp_autofilter |
bool | True | Auto-adjust filter strength |
webp_alpha_compression |
bool | True | Compress alpha channel |
webp_alpha_filtering |
int | 1 | Alpha filtering (0-2) |
webp_alpha_quality |
int | 100 | Alpha channel quality (0-100) |
webp_pass |
int | 1 | Number of encoding passes (1-10) |
webp_preprocessing |
int | 0 | Preprocessing. 0=none, 1=segment-smooth, 2=pseudo-random dither |
webp_partitions |
int | 0 | Number of partitions (0-3) |
webp_partition_limit |
int | 0 | Partition size limit (0-100) |
webp_emulate_jpeg_size |
bool | False | Emulate JPEG output size |
webp_thread_level |
int | 0 | Thread level (0-1) |
webp_low_memory |
bool | False | Low memory mode |
webp_near_lossless |
int | 100 | Near-lossless preprocessing (0-100). 100 = off |
webp_exact |
bool | False | Preserve RGB values in transparent areas |
webp_use_delta_palette |
bool | False | Use delta palette (experimental) |
webp_use_sharp_yuv |
bool | False | Use sharp RGB to YUV conversion |
| Parameter | Type | Default | Description |
|---|---|---|---|
avif_quality |
float | 50.0 | Quality (0.0-100.0). Higher = better quality, larger size |
avif_alpha_quality |
int | 100 | Alpha channel quality (0-100) |
avif_lossless |
bool | False | True: lossless compression, False: lossy compression |
avif_speed |
int | 6 | Encoding speed (0-10). 0 = best quality/slowest, 10 = lowest quality/fastest |
avif_threads |
int | 1 | Number of threads for encoding |
Recommended Settings:
| Use Case | quality | speed | Description |
|---|---|---|---|
| High Quality | 80-90 | 4 | High quality web images |
| Balanced | 50-60 | 6 | General purpose |
| Fast | 40-50 | 8-10 | Batch processing, previews |
| Parameter | Type | Default | Description |
|---|---|---|---|
pngx_level |
int | 5 | Compression level (1-6). Higher = better compression |
pngx_strip_safe |
bool | True | Remove safely removable metadata |
pngx_optimize_alpha |
bool | True | Optimize color info in transparent pixels |
pngx_threads |
int | 1 | Number of threads for processing |
| Parameter | Type | Default | Description |
|---|---|---|---|
pngx_lossy_enable |
bool | True | Enable lossy compression |
pngx_lossy_type |
PngxLossyType | PALETTE256 | Type of lossy compression |
pngx_lossy_max_colors |
int | 256 | Maximum colors for palette mode (2-256) |
pngx_lossy_quality_min |
int | 80 | Minimum quality (0-100) |
pngx_lossy_quality_max |
int | 95 | Maximum quality (0-100) |
pngx_lossy_speed |
int | 3 | Quantization speed (1-10). Higher = faster, lower quality |
pngx_lossy_dither_level |
float | 0.6 | Dithering strength (0.0-1.0) |
| Parameter | Type | Default | Description |
|---|---|---|---|
pngx_lossy_reduced_colors |
int | -1 | Target color count after reduction. -1 = auto |
pngx_saliency_map_enable |
bool | True | Adaptive quantization using saliency map |
pngx_chroma_anchor_enable |
bool | True | Preserve chroma anchor points |
pngx_adaptive_dither_enable |
bool | True | Adaptive dithering |
pngx_gradient_boost_enable |
bool | True | Gradient enhancement |
pngx_chroma_weight_enable |
bool | True | Apply chroma weighting |
pngx_postprocess_smooth_enable |
bool | True | Post-processing smoothing |
pngx_postprocess_smooth_importance_cutoff |
float | 0.6 | Smoothing importance cutoff |
pngx_palette256_gradient_profile_enable |
bool | True | Enable gradient profile |
pngx_palette256_gradient_dither_floor |
float | 0.78 | Gradient dither floor |
pngx_palette256_alpha_bleed_enable |
bool | False | Enable alpha bleed |
pngx_palette256_alpha_bleed_max_distance |
int | 64 | Maximum bleed distance in pixels |
pngx_palette256_alpha_bleed_opaque_threshold |
int | 248 | Opaque threshold |
pngx_palette256_alpha_bleed_soft_limit |
int | 160 | Soft bleed limit |
| Parameter | Type | Default | Description |
|---|---|---|---|
pngx_lossy_reduced_bits_rgb |
int | 4 | RGB channel bit depth (1-8) |
pngx_lossy_reduced_alpha_bits |
int | 4 | Alpha channel bit depth (1-8) |
def get_version() -> intGet the colopresso version number.
def get_libwebp_version() -> intGet the libwebp version number (e.g., 67072 = 1.4.0).
def get_libpng_version() -> intGet the libpng version number.
def get_libavif_version() -> intGet the libavif version number.
def get_pngx_oxipng_version() -> intGet the oxipng version number.
def get_pngx_libimagequant_version() -> intGet the libimagequant version number.
def get_buildtime() -> intGet the build timestamp (Unix time).
def get_compiler_version_string() -> strGet the C compiler version string.
def get_rust_version_string() -> strGet the Rust compiler version string.
def is_threads_enabled() -> boolCheck if multithreading is enabled.
def get_default_thread_count() -> intGet the default number of threads.
def get_max_thread_count() -> intGet the maximum available thread count.
class ColopressoError(Exception):
code: int # Error code
message: str # Error messageError Codes:
| Code | Name | Description |
|---|---|---|
| 0 | OK | Success |
| 1 | File not found | File not found |
| 2 | Invalid PNG | Invalid PNG data |
| 3 | Invalid format | Invalid format |
| 4 | Out of memory | Memory allocation failed |
| 5 | Encode failed | Encoding failed |
| 6 | Decode failed | Decoding failed |
| 7 | IO error | Input/output error |
| 8 | Invalid parameter | Invalid parameter |
| 9 | Output not smaller | Output is not smaller than input |
Example:
import colopresso
try:
result = colopresso.encode_avif(png_data)
except colopresso.ColopressoError as e:
if e.code == 9:
print("AVIF compression was not effective. Using original PNG.")
else:
print(f"Error: {e.message}")import colopresso
with open("photo.png", "rb") as f:
png_data = f.read()
# High quality WebP
config = colopresso.Config(
webp_quality=95.0,
webp_method=6,
webp_use_sharp_yuv=True
)
high_quality = colopresso.encode_webp(png_data, config)
# High compression WebP
config = colopresso.Config(
webp_quality=60.0,
webp_method=6
)
compressed = colopresso.encode_webp(png_data, config)
# Lossless WebP
config = colopresso.Config(webp_lossless=True)
lossless = colopresso.encode_webp(png_data, config)import colopresso
with open("large_image.png", "rb") as f:
png_data = f.read()
# Multithreaded high-speed encoding
config = colopresso.Config(
avif_quality=70.0,
avif_speed=6,
avif_threads=4
)
avif_data = colopresso.encode_avif(png_data, config)import colopresso
with open("icon.png", "rb") as f:
png_data = f.read()
config = colopresso.Config(
pngx_lossy_enable=True,
pngx_lossy_type=colopresso.PngxLossyType.PALETTE256,
pngx_lossy_max_colors=256,
pngx_lossy_quality_min=85,
pngx_lossy_quality_max=100,
pngx_lossy_dither_level=0.8
)
optimized = colopresso.encode_pngx(png_data, config)
print(f"Original: {len(png_data)} bytes")
print(f"Optimized: {len(optimized)} bytes")
print(f"Reduction: {(1 - len(optimized)/len(png_data))*100:.1f}%")import colopresso
with open("screenshot.png", "rb") as f:
png_data = f.read()
config = colopresso.Config(
pngx_lossy_enable=False, # Disable lossy compression
pngx_level=6, # Maximum compression level
pngx_strip_safe=True, # Remove metadata
pngx_optimize_alpha=True # Optimize alpha
)
optimized = colopresso.encode_pngx(png_data, config)import colopresso
with open("texture.png", "rb") as f:
png_data = f.read()
# RGBA4444 format (16-bit color)
config = colopresso.Config(
pngx_lossy_enable=True,
pngx_lossy_type=colopresso.PngxLossyType.LIMITED_RGBA4444,
pngx_lossy_reduced_bits_rgb=4,
pngx_lossy_reduced_alpha_bits=4
)
optimized = colopresso.encode_pngx(png_data, config)import colopresso
from pathlib import Path
from concurrent.futures import ThreadPoolExecutor
def convert_to_webp(png_path: Path) -> tuple[Path, int, int]:
"""Convert PNG to WebP and return size info"""
with open(png_path, "rb") as f:
png_data = f.read()
config = colopresso.Config(webp_quality=80.0)
webp_data = colopresso.encode_webp(png_data, config)
webp_path = png_path.with_suffix(".webp")
with open(webp_path, "wb") as f:
f.write(webp_data)
return webp_path, len(png_data), len(webp_data)
# Parallel conversion
png_files = list(Path("images").glob("*.png"))
with ThreadPoolExecutor(max_workers=4) as executor:
results = list(executor.map(convert_to_webp, png_files))
for path, original, converted in results:
print(f"{path.name}: {original} -> {converted} ({(1-converted/original)*100:.1f}% reduction)")import colopresso
def safe_encode(png_data: bytes, format: str = "webp") -> bytes | None:
"""Encode with error handling"""
config = colopresso.Config()
try:
if format == "webp":
return colopresso.encode_webp(png_data, config)
elif format == "avif":
return colopresso.encode_avif(png_data, config)
elif format == "pngx":
return colopresso.encode_pngx(png_data, config)
else:
raise ValueError(f"Unknown format: {format}")
except colopresso.ColopressoError as e:
if e.code == 2:
print("Error: Input is not a valid PNG")
elif e.code == 9:
print(f"{format.upper()} compression was not effective")
return png_data # Return original data
else:
print(f"Encoding error: {e.message}")
return None
# Usage
with open("input.png", "rb") as f:
png_data = f.read()
result = safe_encode(png_data, "avif")
if result:
with open("output.avif", "wb") as f:
f.write(result)cd python
pip install build
python -m build --wheelThe wheel will be created in python/dist/.
colopresso is licensed under GPL-3.0-or-later.
Copyright (C) 2026 COLOPL, Inc.