Skip to main content

🪗 Kompressor

Compress, convert, resize, trim, and slugify images.

Features

Rename — Modify the image name in multiple ways. Add a string to the source image, the compressed image, or both and put them in the current dir or a subdir.

Compress — Compress the images on a 1-100 scale, with a default of 80.

Resize — Set a max width and height for the image. The image will be resized to fit within the bounds while maintaining the aspect ratio.

Trim — Trim pixels from the sides of the image, by specifying a number of pixels from each site. This is particularly useful for removing bad lines from the edges of images.

Convert — Convert the image to a different format. Supported formats are png, jpeg, webp and avif.

Strip metadata — Remove all metadata from the image using exiftool.

Requirements

Four command line tools are used for the actual compression, pngquant, jpegoptim, cwebp and avif, and exiftool is used to remove metadata. Kompressor assumes they exist and are on the PATH.

They can be installed with the following commands.

Linux:
apt install pngquant jpegoptim webp exiftool

Macos:
brew install pngquant jpegoptim webp exiftool

AVIF:
npm install avif

Also, UV is required to build the tool. It can be installed with pipx or curl. See the UV install docs for more info.

Installation

Kompressor can be installed from pypi. Its recommended you use pipx to install python applications.

pip install kompressor
# or better yet,
pipx install kompressor

Installing from the git repo:

git clone https://github.com/8cylinder/kompressor.git
cd kompressor
uv sync
uv build
uv tool install ./dist/kompressor-XXXXX-py3-none-any.whl
# kompressor is now installed

Output dir

If the --output option is not used, the compressed image will be put in a dir called kompressor in the same dir as the source image. If the dir doesn't exist, it will be created. That means that if multiple images are specified in a dir tree, then there will be multiple kompressor dirs created.

When using the --output option, the compressed dir will use that name. If . is used, then the compressed images won't be put in a subdir but will be in the same dir as the source image. In which case you will need to use the --destination-rename or the --source-rename option to avoid an error.

Piping

Files can be piped into kompressor using the find command.

find . -type f -name "*.png" | kompressor
# or with options
find . -type f -name "*.png" | kompressor --quality 50 --output . --source-rename "-ORIGINAL"

Renaming

Files can optionally have a string added to the end of the filename using the --source-rename / -s and --destination-rename / -d options. The -d option renames the compressed image and the -s option renames the source image. These are applied whether it's put into a subdir or not.

Eg, with an argument of -ORIGINAL, this file image.jpg would become image-ORIGINAL.jpg.

Usage

By default, if the --output option is not used, the compressed file will be put in a subdir called "kompressor" in the same dir as the source file. It will be created if it doesn't exist.

Supported formats: png, jpeg, webp and avif.

Basic usage — compress single or multiple images. This will create the kompressor dir and put the compressed image in it.

# single image
kompressor file.png

# multiple images
kompressor file1.png file2.png file3.png
# or
kompressor *.png

Renaming files — add a string to the end of the filename.

kompressor --destination-rename "-COMPRESSED" image.png
# new compressed image: ./kompressor/image-COMPRESSED.png

kompressor --source-rename "-ORIGINAL" image.png
# new compressed image: ./kompressor/image.png
# original image:       ./image-ORIGINAL.png

kompressor --source-rename "-ORIGINAL" --destination-rename "-COMPRESSED" image.png
# new compressed image: ./kompressor/image-COMPRESSED.png
# original image:       ./image-ORIGINAL.png

Setting the --output option to . will put the compressed image in the same dir as the source image. If you don't specify a rename flag, you will get an error about the file already existing.

kompressor --output . --source-rename "-ORIGINAL" image.png
# new compressed image: ./image.png
# original image:       ./image-ORIGINAL.png

kompressor --output . --source-rename "-ORIGINAL" --destination-rename "-COMPRESSED" image.png
# new compressed image: ./image-COMPRESSED.png
# original image:       ./image-ORIGINAL.png

To generate multiple compressed images with different quality settings, use a range. The following example generates 3 compressed images with different quality settings and puts them in the 'kompressor' directory.

for QUALITY in 10 50 80; do
  kompressor --quality=$QUALITY --destination-rename "-$QUALITY" *.png;
done

# ./kompressor/image-10.png
# ./kompressor/image-50.png
# ./kompressor/image-80.png

Trim — Cromp the image by removing a number of pixels from each side. The format for trimmng is t10,r10,b10,l10. This trims 10 pixes from the top, right, bottom and left sides. Use a comma to separate the values. Not all fields are required.

# trim 10 pixels from the top, right, bottom and left sides
kompressor --trim t10,r10,b10,l10 image.png
# trim 1 pixel from the top and 3 from the right side
kompressor --trim t1,r3 image.png

Resize — Shrink the image to fit within the bounds of the width and height, the aspect ratio is maintained. Use a comma to separate the width & height. If only one value is specified, that will set the width.

kompressor --resize 1000,1000 image.png
kompressor --resize 1000 image.png

Convert — Convert the image to a different format. Supported formats are png, jpeg, webp and avif.

# convert image.png to image.webp
kompressor --convert webp image.png
# new compressed image: ./kompressor/image.webp
# original image:       ./image.png

kompressor --convert png image.jpg -o .
# new compressed image: ./image.png
# original image:       ./image.jpg

Output

Output can be a table or json using the --table (default) or --json flag.

kompressor image-*.png -d '-NEW' -x 1000 1000
image-01.png -> kompressor/image-01-NEW.png |  48K ->  25K | 52% | 1538x 985 -> 1000x 640
image-03.png -> kompressor/image-03-NEW.png | 6.3M -> 428K |  7% | 2080x1880 -> 1000x 904
image-04.png -> kompressor/image-04-NEW.png | 213K ->  38K | 18% | 1538x 985 -> 1000x 640
image-05.png -> kompressor/image-05-NEW.png | 6.5M -> 472K |  7% | 2080x1880 -> 1000x 904
image-06.png -> kompressor/image-06-NEW.png | 205K ->  35K | 17% | 1538x 985 -> 1000x 640
image-07.png -> kompressor/image-07-NEW.png | 6.1M -> 385K |  6% | 2080x1880 -> 1000x 904
image-08.png -> kompressor/image-08-NEW.png |  12K ->   4K | 32% |  392x 146 ->  392x 146
image-09.png -> kompressor/image-09-NEW.png |  17K ->   5K | 30% |  430x 146 ->  430x 146
image-10.png -> kompressor/image-10-NEW.png |  18K ->   5K | 30% |  420x 146 ->  420x 146
image-11.png -> kompressor/image-11-NEW.png |   3K ->   3K | 95% |  380x 146 ->  380x 146
image-12.png -> kompressor/image-12-NEW.png |   9K ->   3K | 31% |  276x 146 ->  276x 146
image-13.png -> kompressor/image-13-NEW.png |   4K ->   1K | 24% | 1000x1000 -> 1000x1000

Using the --json flag, output will look like this. Note I'm using jq to format the output.

kompressor image-{3,4}.png -x 100 100 --json | jq
[
  {
    "files": {
      "source": "/path/to/images/image-4.png",
      "compressed": "/path/to/images/kompressor/image-4.png"
    },
    "bytes": {
      "original_size": 217785,
      "compressed_size": 1561
    },
    "human": {
      "original_size": "213K",
      "compressed_size": "2K"
    },
    "original_dimensions": [
      1538,
      985
    ],
    "compressed_dimensions": [
      100,
      64
    ]
  },
  {
    "files": {
      "source": "/path/to/images/image-3.png",
      "compressed": "/path/to/images/kompressor/image-3.png"
    },
    "bytes": {
      "original_size": 6644905,
      "compressed_size": 7233
    },
    "human": {
      "original_size": "6.3M",
      "compressed_size": "7K"
    },
    "original_dimensions": [
      2080,
      1880
    ],
    "compressed_dimensions": [
      100,
      90
    ]
  }
]

Development

Run

uv run kompressor --help

Build

uv build

Install

pipx install ./dist/kompressor-XXXXX-py3-none-any.whl

uv tool install ./dist/kompressor-XXXXX-py3-none-any.whl

Install editable

uv tool install --editable .

Upload to pypi

twine upload --repository testpypi dist/*
twine upload dist/*

Metadata

Release files for kompressor 0.2.9

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for kompressor 0.2.9
File Size Uploaded
kompressor-0.2.9.tar.gz 53.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for kompressor 0.2.9
File Interpreter ABI Platform
kompressor-0.2.9-py3-none-any.whl Python 3 none any Details

Total release size: 78.0 kB

Release files / kompressor-0.2.9.tar.gz

Download URL kompressor-0.2.9.tar.gz
Size 53.5 kB
Tags Source
SHA-256 checksum
How to use checksums
1fe72a881f54bb01b03ee1b32e293045ed298165b49ed83cb939adec2a8d7951
BLAKE2b-256 checksum
How to use checksums
7d13546b439f6dea574c7de9286da81f0441f5ec21a54ddd3b74707aba281fe7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.3

Release files / kompressor-0.2.9-py3-none-any.whl

Download URL kompressor-0.2.9-py3-none-any.whl
Size 24.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
cb05093f6ee0e918cdeec48ac5fdf9decc976cb759a7f3cdc6c60ed2627c330f
BLAKE2b-256 checksum
How to use checksums
28e59447c9604da32378d64de5533b8362e8d83a39fe4738eb9c1106ac11b979
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.3

Release history Release notifications | RSS feed

This release

0.2.9 This release

2 release files

0.2.7

2 release files

0.2.6

2 release files

0.2.5

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page