Python wrapper for multithreaded PNG optimizer oxipng (https://github.com/shssoichiro/oxipng)
MIT License
Python wrapper for multithreaded .png image file optimizer
oxipng (written in Rust). Use
pyoxipng
to reduce the file size of your PNG images.
Jump to a section
Install from PyPI:
pip install pyoxipng
Import in your Python code:
import oxipng
Optimize a file on disk.
Parameters:
Returns
Raises
Examples:
Optimize a file on disk and overwrite
oxipng.optimize("/path/to/image.png")
Optimize a file and save to a new location:
oxipng.optimize("/path/to/image.png", "/path/to/image-optimized.png")
Optimize raw data from a PNG file loaded in Python as a bytes
object:
Parameters:
Returns
Raises
Examples:
data = ... # bytes of png data
optimized_data = oxipng.optimize_from_memory(data)
with open("/path/to/image-optimized.png", "wb") as f:
f.write(optimized_data)
Create an optimized PNG file from raw image data:
raw = oxipng.RawImage(data, width, height)
optimized_data = raw.create_optimized_png()
By default, assumes the input data is 8-bit, row-major RGBA, where every 4 bytes represents one pixel with Red-Green-Blue-Alpha channels. To interpret non-RGBA data, specify a color_type
parameter with the oxipng.ColorType
class:
Method | Description |
---|---|
oxipng.ColorType.grayscale(int | None) |
Grayscale, with one color channel. Specify optional shade of gray that should be rendered as transparent. |
oxipng.ColorType.rgb(tuple[int, int, int]) |
RGB, with three color channels. Specify optional color value that should be rendered as transparent. |
oxipng.ColorType.indexed(list[[tuple[int, int, int, int]]) |
Indexed, with one byte per pixel representing a color from the palette. Specify palette containing the colors used, up to 256 entries. |
oxipng.ColorType.grayscale_alpha() |
Grayscale + Alpha, with two color channels. |
oxipng.ColorType.rgba() |
RGBA, with four color channels. |
Parameters:
color_type
and bit_depth
parametersoxipng.ColorType.rgba()
Examples:
Save RGB image data from a JPEG file, interpreting black pixels as transparent.
from PIL import Image
import numpy as np
# Load an image file with Pillow
jpg = Image.open("/path/to/image.jpg")
# Convert to RGB numpy array
rgb_array = np.array(jpg.convert("RGB"), dtype=np.uint8)
height, width, channels = rgb_array.shape
# Create raw image with sRGB color profile
data = rgb_array.tobytes()
color_type = oxipng.ColorType.rgb((0, 0, 0)) # black is transparent
raw = oxipng.RawImage(data, width, height, color_type=color_type)
raw.add_png_chunk(b"sRGB", b"\0")
# Optimize and save
optimized = raw.create_optimized_png(level=6)
with open("/path/to/image/optimized.png", "wb") as f:
f.write(optimized)
Save with data where bytes reference a color palette
data = b"\0\1\2..." # get index data
palette = [[0, 0, 0, 255], [1, 23, 234, 255], ...]
color_type = oxipng.ColorType.indexed(palette)
raw = oxipng.RawImage(data, 100, 100, color_type=color_type)
optimized = raw.create_optimized_png()
Methods:
Add a png chunk, such as b"iTXt"
, to be included in the output
Parameters:
Returns:
Add an ICC profile for the image
Parameters:
Returns:
Create an optimized png from the raw image data using the options provided
Parameters:
Returns:
optimize
, optimize_from_memory
and RawImage.create_optimized_png
accept the following options as keyword arguments.
Example:
oxipng.optimize("/path/to/image.png", level=6, fix_errors=True, interlace=oxipng.Interlacing.Adam7)
Option | Description | Type | Default |
---|---|---|---|
level |
Set the optimization level to an integer between 0 and 6 (inclusive) | int | 2 |
fix_errors |
Attempt to fix errors when decoding the input file rather than throwing PngError
|
bool | False |
force |
Write to output even if there was no improvement in compression | bool | False |
filter |
Which filters to try on the file. Use Use enum values from oxipng.RowFilter
|
set[RowFilter] | {RowFilter.NoOp} |
interlace |
Whether to change the interlacing type of the file. None will not change current interlacing type |
Interlacing | None | None |
optimize_alpha |
Whether to allow transparent pixels to be altered to improve compression | bool | False |
bit_depth_reduction |
Whether to attempt bit depth reduction | bool | True |
color_type_reduction |
Whether to attempt color type reduction | bool | True |
palette_reduction |
Whether to attempt palette reduction | bool | True |
grayscale_reduction |
Whether to attempt grayscale reduction | bool | True |
idat_recoding |
If any type of reduction is performed, IDAT recoding will be performed regardless of this setting | bool | True |
scale_16 |
Whether to forcibly reduce 16-bit to 8-bit by scaling | bool | False |
strip |
Which headers to strip from the PNG file, if any. Specify with oxipng.StripChunks
|
StripChunks | StripChunks.none() |
deflate |
Which DEFLATE algorithm to use. Specify with oxipng.Deflaters
|
Deflaters | Deflaters.libdeflater() |
fast_evaluation |
Whether to use fast evaluation to pick the best filter | bool | False |
timeout |
Maximum amount of time to spend (in milliseconds) on optimizations. Further potential optimizations are skipped if the timeout is exceeded | int | None | None |
Initialize the filter
set with any of the following oxipng.RowFilter
enum options:
oxipng.RowFilter.NoOp
oxipng.RowFilter.Sub
oxipng.RowFilter.Up
oxipng.RowFilter.Average
oxipng.RowFilter.Paeth
oxipng.RowFilter.Bigrams
oxipng.RowFilter.BigEnt
oxipng.RowFilter.Brute
Set interlace
to None
to keep existing interlacing or to one of following oxipng.Interlacing
enum options:
oxipng.Interlacing.Off
(interlace disabled)oxipng.Interlacing.Adam7
(interlace enabled)Initialize the strip
option with one of the following static methods in the
oxipng.StripChunks
class.
Method | Description |
---|---|
oxipng.StripChunks.none() |
None |
oxipng.StripChunks.strip(set[bytes]) |
Strip specific chunks |
oxipng.StripChunks.safe() |
Strip chunks that won't affect rendering (all but cICP, iCCP, sRGB, pHYs, acTL, fcTL, fdAT) |
oxipng.StripChunks.keep(set[bytes]) |
Strip all non-critical chunks except these |
oxipng.StripChunks.all() |
Strip all non-critical chunks |
Initialize the deflate
option with one of the following static methods in the
oxipng.Deflaters
class.
Method | Description |
---|---|
oxipng.Deflaters.libdeflater(int) |
Libdeflater with compression level [0-12] |
oxipng.Deflaters.zopfli(int) |
Zopfli with number of compression iterations to do [1-255] |
git clone https://github.com/nfrasser/pyoxipng.git
cd pyoxipng
pipenv install --dev
pipenv shell
maturin develop
pytest
black .
MIT