Oxipng - a multithreaded lossless PNG compression optimizer

Overview

Oxipng

Build Status Version License Docs

Overview

Oxipng is a multithreaded lossless PNG compression optimizer. It can be used via a command-line interface or as a library in other Rust programs.

Installing

Oxipng for Windows can be downloaded from the Releases link on the GitHub page.

For MacOS or Linux, it is recommended to install from your distro's package repository, if possible.

Alternatively, oxipng can be installed from Cargo, via the following command:

cargo install oxipng

Oxipng can be built from source using the latest stable or nightly Rust. This is primarily useful for developing on oxipng.

git clone https://github.com/shssoichiro/oxipng.git
cd oxipng
cargo build --release
cp target/release/oxipng /usr/local/bin

The current minimum supported Rust version is 1.56.0.

Oxipng follows Semantic Versioning.

Usage

Oxipng is a command-line utility. Basic usage looks similar to the following:

oxipng -o 4 -i 1 --strip safe *.png

The most commonly used options are as follows:

  • Optimization: -o 1 through -o 6, lower is faster, higher is better compression. The default (-o 2) is sufficiently fast on a modern CPU and provides 30-50% compression gains over an unoptimized PNG. -o 4 is 6 times slower than -o 2 but can provide 5-10% extra compression over -o 2. Using any setting higher than -o 4 is unlikely to give any extra compression gains and is not recommended.
  • Interlacing: -i 1 will enable Adam7 PNG interlacing on any images that are processed. -i 0 will remove interlacing from all processed images. Not specifying either will keep the same interlacing state as the input image. Note: Interlacing can add 25-50% to the size of an optimized image. Only use it if you believe the benefits outweigh the costs for your use case.
  • Strip: Used to remove metadata info from processed images. Used via --strip [safe,all]. Can save a few kilobytes if you don't need the metadata. "Safe" removes only metadata that will never affect rendering of the image. "All" removes all metadata that is not critical to the image. You can also pass a comma-separated list of specific metadata chunks to remove. -s can be used as a shorthand for --strip safe.

More advanced options can be found by running oxipng -h.

Library Usage

Although originally intended to be used as an executable, oxipng can also be used as a library in other Rust projects. To do so, simply add oxipng as a dependency in your Cargo.toml, then extern crate oxipng in your project. You should then have access to all of the library functions documented here. The simplest method of usage involves creating an Options struct and passing it, along with an input filename, into the optimize function.

History

Oxipng began as a complete rewrite of the OptiPNG project, which was assumed to be dead as no commit had been made to it since March 2014. (OptiPNG has since released a new version, after Oxipng was first released.) The name has been changed to avoid confusion and potential legal issues.

The core goal of rewriting OptiPNG was to implement multithreading, which would be very difficult to do within the existing C codebase of OptiPNG. This also served as an opportunity to choose a more modern, safer language (Rust).

Contributing

Any contributions are welcome and will be accepted via pull request on GitHub. Bug reports can be filed via GitHub issues. Please include as many details as possible. If you have the capability to submit a fix with the bug report, it is preferred that you do so via pull request, however you do not need to be a Rust developer to contribute. Other contributions (such as improving documentation or translations) are also welcome via GitHub.

License

Oxipng is open-source software, distributed under the MIT license.

Benchmarks

Tested oxipng 5.0.0 (compiled on rustc 1.55.0-nightly (7a16cfcff 2021-07-11)) against OptiPNG version 0.7.7 on AMD Ryzen 7 4800H with Radeon Graphics with 16 logical cores


Benchmark #1: ./target/release/oxipng -P ./tests/files/rgb_16_should_be_grayscale_8.png
  Time (mean ± σ):     128.8 ms ±  14.2 ms    [User: 296.0 ms, System: 14.3 ms]
  Range (min … max):    98.8 ms … 152.3 ms    21 runs

Benchmark #2: optipng -simulate ./tests/files/rgb_16_should_be_grayscale_8.png
  Time (mean ± σ):     254.2 ms ±  16.0 ms    [User: 252.8 ms, System: 1.2 ms]
  Range (min … max):   208.4 ms … 263.8 ms    14 runs

Summary
  './target/release/oxipng -P ./tests/files/rgb_16_should_be_grayscale_8.png' ran
    1.97 ± 0.25 times faster than 'optipng -simulate ./tests/files/rgb_16_should_be_grayscale_8.png'



Benchmark #1: ./target/release/oxipng -o4 -P ./tests/files/rgb_16_should_be_grayscale_8.png
  Time (mean ± σ):     141.4 ms ±  14.9 ms    [User: 611.7 ms, System: 21.1 ms]
  Range (min … max):   100.2 ms … 160.4 ms    23 runs

Benchmark #2: optipng -o 4 -simulate ./tests/files/rgb_16_should_be_grayscale_8.png
  Time (mean ± σ):     730.0 ms ±  25.9 ms    [User: 728.0 ms, System: 1.2 ms]
  Range (min … max):   713.3 ms … 768.2 ms    10 runs

Summary
  './target/release/oxipng -o4 -P ./tests/files/rgb_16_should_be_grayscale_8.png' ran
    5.16 ± 0.58 times faster than 'optipng -o 4 -simulate ./tests/files/rgb_16_should_be_grayscale_8.png'

Comments
  • Add Windows builds to rust everywhere

    Add Windows builds to rust everywhere

    This is a followup to #34. @japaric, @TPS suggested that you could help. Do you have experience with deploying rust-everywhere for Windows on Travis CI? The Travis docs seem to indicate that Windows isn't a supported platform. Is the workaround then to use Appveyor for Windows builds?

    T-Feature I-Medium T-Help Wanted 
    opened by shssoichiro 16
  • Switch to crossbeam-channel + rayon::spawn

    Switch to crossbeam-channel + rayon::spawn

    So this PR might look a bit weird, but hopefully still acceptable. There are two things going on here:

    1. A custom alternative to std::thread::spawn based on rayon + crossbeam-channel. See the comment on the function for motivation and more details, but TL;DR is that it makes possible to run OxiPNG with threads even on a Wasm target! (in engines that support Wasm threads). Working variant of Squoosh.app that makes use of this patch and runs OxiPNG+threads here: https://multithread--squoosh.netlify.app/editor
    2. Since the part 1 requires crossbeam-channel anyway, I switched to it from std::sync::mspc, too, for the better performance as well as API improvements. For example, before this, evaluator had to use sync_channel(4) - a blocking synchronous channel with a magical constant maximum of 4 - because the async version of std::sync::mpsc::Sender can't be shared between threads (it doesn't implement Sync trait). However, with crossbeam it's not a problem, and it becomes possible to use asynchronous unbounded channel instead.
    opened by RReverser 13
  • Is preset 4 deprecated or incorrect?

    Is preset 4 deprecated or incorrect?

    Currently --help says:

    Optimization levels:
        -o 0  =>  --zc 3 --nz                  (0 or 1 trials)
        -o 1  =>  --zc 9                       (1 trial, determined heuristically)
        -o 2  =>  --zc 9 --zs 0-3 -f 0,5       (8 trials)
        -o 3  =>  --zc 9 --zs 0-3 -f 0-5       (24 trials)
        -o 4  =>  --zc 9 --zs 0-3 -f 0-5 -a    (24 trials + 6 alpha trials)
        -o 5  =>  --zc 3-9 --zs 0-3 -f 0-5 -a  (96 trials + 6 alpha trials)
        -o 6  =>  --zc 1-9 --zs 0-3 -f 0-5 -a  (180 trials + 6 alpha trials)
    

    However, actual code for preset 4 is equivalent to preset 3 (no alpha optimisation):

        fn apply_preset_3(mut self) -> Self {
            for i in 1..5 {
                self.filter.insert(i);
            }
            self
        }
    
        fn apply_preset_4(self) -> Self {
            self.apply_preset_3()
        }
    

    I suppose this is the outcome of a decision not to perform alpha optimisations by default, made in https://github.com/shssoichiro/oxipng/pull/187.

    Which is fine, but makes state of this preset fairly confusing. Should it be removed at this point?

    Also, docs for higher opt levels should probably be updated as well to exclude -a?

    I-Minor T-Docs T-Question 
    opened by RReverser 11
  • Non-deterministic output

    Non-deterministic output

    Trying to run e.g.

    cargo run -- -o 6 -P tests/files/grayscale_alpha_16_reduce_alpha_right.png --alpha
    

    on current master (39ff7cfd5c8403af82df097f7a227ebac370254a) seems to produce non-deterministic results.

    Sometimes I'm getting

    Processing: tests/files/grayscale_alpha_16_reduce_alpha_right.png
        200x152 pixels, PNG format
        2x16 bits/pixel, GrayscaleAlpha
        IDAT size = 32322 bytes
        File size = 32400 bytes
    Trying: 216 combinations
    Found better combination:
        zc = 9  zs = 1  f = 5        20295 bytes
        IDAT size = 20295 bytes (12027 bytes decrease)
        file size = 20373 bytes (12027 bytes = 37.12% decrease)
    Running in pretend mode, no output
    

    and sometimes (more frequently) a worse result

    Processing: tests/files/grayscale_alpha_16_reduce_alpha_right.png
        200x152 pixels, PNG format
        2x16 bits/pixel, GrayscaleAlpha
        IDAT size = 32322 bytes
        File size = 32400 bytes
    Trying: 216 combinations
    Found better combination:
        zc = 9  zs = 1  f = 5        20335 bytes
        IDAT size = 20335 bytes (11987 bytes decrease)
        file size = 20413 bytes (11987 bytes = 37.00% decrease)
    Running in pretend mode, no output
    

    Originally posted as comments on https://github.com/shssoichiro/oxipng/commit/239ca81db7b45b3ac731a8d8b2746e760500d0a9#commitcomment-37751319.

    T-Bug I-Medium 
    opened by RReverser 11
  • optipng generates much smaller files than oxipng even at lower levels

    optipng generates much smaller files than oxipng even at lower levels

    $ cd /tmp
    $ wget -q 'https://raw.githubusercontent.com/petvas/i3lock-blur/master/lock.png'
    $ cp lock.png{,.orig}
    
    $ optipng -v
    OptiPNG version 0.7.7
    Copyright (C) 2001-2017 Cosmin Truta and the Contributing Authors.
    
    This program is open-source software. See LICENSE for more details.
    
    Portions of this software are based in part on the work of:
      Jean-loup Gailly and Mark Adler (zlib)
      Glenn Randers-Pehrson and the PNG Development Group (libpng)
      Miyasaka Masaru (BMP support)
      David Koblas (GIF support)
    
    Using libpng version 1.6.37 and zlib version 1.2.11
    
    $ optipng -o4 lock.png
    ** Processing: lock.png
    512x512 pixels, 4x8 bits/pixel, RGB+alpha
    Reducing image to 8 bits/pixel, 233 colors (232 transparent) in palette
    Input IDAT size = 13216 bytes
    Input file size = 13359 bytes
    
    Trying:
      zc = 9  zm = 8  zs = 0  f = 0		IDAT size = 6592
      zc = 9  zm = 8  zs = 3  f = 0		IDAT size = 6251
    
    Selecting parameters:
      zc = 9  zm = 8  zs = 3  f = 0		IDAT size = 6251
    
    Output IDAT size = 6251 bytes (6965 bytes decrease)
    Output file size = 7336 bytes (6023 bytes = 45.09% decrease)
    
    $ oxipng --version
    oxipng 2.3.0
    
    $ cp lock.png{.orig,}
    $ oxipng -o6 lock.png
    Processing: lock.png
        512x512 pixels, PNG format
        4x8 bits/pixel, RGBA
        IDAT size = 13216 bytes
        File size = 13359 bytes
    Trying: 216 combinations
    Found better combination:
        zc = 9  zs = 0  f = 0        8927 bytes
        IDAT size = 8927 bytes (4289 bytes decrease)
        file size = 9055 bytes (4304 bytes = 32.22% decrease)
    Output: lock.png
    
    I-Medium T-Compression 
    opened by desbma 11
  • Add support for optimizing in-memory PNGs.

    Add support for optimizing in-memory PNGs.

    In keeping with being able to use oxipng as a library, there should be a way to alter an image already in-memory. This allows end users working with in-memory representations -- say, external web servers providing optimization services -- to easily take advantage of oxipng.

    opened by tobz 11
  • PNG files are often corrupted when inputs are monochrome.

    PNG files are often corrupted when inputs are monochrome.

    Processing: Mona_Lisa-PNG8-Scatter-BW.png
        404x600 pixels, PNG format
        1x8 bits/pixel, Grayscale
        IDAT size = 18171 bytes
        File size = 18242 bytes
    Reducing image to 1x1 bits/pixel, Grayscale
    Trying: 6 combinations
    Found better combination:
        zc = 0  zs = 0  f = 0        16966 bytes
        IDAT size = 16966 bytes (1205 bytes decrease)
        file size = 17037 bytes (1205 bytes = 6.61% decrease)
    The resulting image is corrupted and will not be outputted.
    This is a bug! Please report it at https://github.com/shssoichiro/oxipng/issues
    The resulting image is corrupted
    

    I don't know what's happening here, but I ran the command line oxipng -s -o 6 -Z --fix *BW.png in an attempt to figure out why earlier runs (without -Z, as well as with and without -D) had some corrupt images, but only for monochrome black and white PNGs (1-bit). All of the attached PNGs had corrupt output when given the above command line. I an on Windows 10 64-bit, and used a just-downloaded 5.0.1 release. Zopfli compression claimed it had significant size reductions, but then also that the output was corrupted and so was not saved. I don't have a Rust dev environment set up, and I suspect compiling oxipng from source would be a challenge for me, so I guess I'm just reporting what it says to report, and providing some of the images that failed.

    Mona_Lisa-PNG8-BlueNoise-BW Mona_Lisa-PNG8-ChaoticNoise-BW Mona_Lisa-PNG8-Diffusion-BW Mona_Lisa-PNG8-Gradient-BW Mona_Lisa-PNG8-Neue-BW Mona_Lisa-PNG8-None-BW Mona_Lisa-PNG8-Pattern-BW Mona_Lisa-PNG8-Scatter-BW

    EDIT: I originally uploaded GIFs, not PNGs, though the contents were identical. Sorry about that!

    T-Bug I-Medium 
    opened by tommyettinger 10
  • 🚀 Revamp alpha optimisation

    🚀 Revamp alpha optimisation

    This PR introduces an entirely different approach to alpha optimisation, which is more effective than before and much faster. I think this is quite cool, so I'll start by showing off some benchmarks.

    Set of non-reducible RGBA files totalling 15,737,898 bytes, compressed using -o3: | Test | Size | Time | |-|-|-| | Without -a | 9,868,361 | 20.463 | | With -a, master | 8,813,177 | 24.155 | | With -a, PR | 8,754,222 | 20.488 |

    Following comments on #468, I continued searching for better alpha techniques and eventually came across CryoPNG. The key here is to alter the data such that it becomes zero when filtered. While CryoPNG does this assuming a single delta filter for the whole image, we can take it to the next level by integrating the technique into the actual filtering stage. This allows it to work for heuristic filters and actually help guide the heuristic selection.

    The speed advantage is that there's no need to do any evaluator trials. Being tailored to the specific filter being applied, the output is near-optimal - this doesn't mean it's the best possible but does mean it would be difficult to improve upon. As such, the original image data is no longer considered - there are still images where the original data could be better but these would be quite rare and it would be impractical to evaluate in the new setup.

    An example of what the technique looks like: elephant elephant-reveal

    I've removed all the redundant tests and associated files (and also some redundant deflate benches leftover from before the switch to libdeflate).

    opened by andrews05 9
  • Zopfli compression in 6.0.0 results in a corrupted image in some cases

    Zopfli compression in 6.0.0 results in a corrupted image in some cases

    Using the newly-released 6.0.0 version on Windows 11 (64-bit) on the attached PNG results in the following:

    > oxipng -Z -o max cover.png

    Processing: cover.png
        2981x2981 pixels, PNG format
        3x8 bits/pixel, RGB
        IDAT size = 6087921 bytes
        File size = 6088031 bytes
    Trying: 6 combinations
    Found better combination:
        zc = 0  zs = 0  f = 4        5897004 bytes
        IDAT size = 5897004 bytes (190917 bytes decrease)
        file size = 5897114 bytes (190917 bytes = 3.14% decrease)
    The resulting image is corrupted and will not be outputted.
    This is a bug! Please report it at https://github.com/shssoichiro/oxipng/issues
    The resulting image is corrupted
    

    As per instructions, here I am.

    The problematic image is available at https://user-images.githubusercontent.com/1986890/188520158-84a1a201-a63f-4884-b880-19980932551b.png

    FWIW, I had just successfully compressed this image (same command) with oxipng 5.0.1 a few days ago.

    The -o max flag doesn't make a difference, either (same error), but I don't get the error in normal mode (it can't achieve better compression and doesn't even try, I guess).

    opened by bgunnink 9
  • non-parallel mode broken on master

    non-parallel mode broken on master

    Looks like https://github.com/shssoichiro/oxipng/commit/4ef92089d5743e896c920d6fa364ff66ab22c346 landed yesterday and removes the non-parallel mode added in #194.

    These conditional compilation attributes and a separate synchronous code are important for environments like WebAssembly (which is what they were added for in the first place), where thread::spawn is not available and errors out at runtime.

    After this change, it's invoked unconditionally again.

    T-Bug I-Critical 
    opened by RReverser 8
  • Make cloudflare-zlib dependency optional

    Make cloudflare-zlib dependency optional

    Although the Cloudflare fork of zlib may introduce performance improvements, there are issues building it with MinGW toolchains on Windows, as evidenced by this StackOverflow question.

    However, it is not always possible to switch to the MSVC toolchain on Windows, because that may break other native C libraries which have trouble with MSVC instead, and just compiling to a 32-bit target can get pretty messy too.

    I've opened an issue to get this error fixed upstream, in the cloudflare-zlib-sys crate, but several months have passed with no answer.

    Therefore, make the Cloudflare zlib dependency optional, so users will have to explicitly opt in for it.

    opened by AlexTMjugador 7
  • [RFC] Raw API

    [RFC] Raw API

    This is a draft proposal for a raw API, as discussed in #376. Although it's not final yet, I wanted to get a PR up now before the holidays and hopefully get some feedback on it. One question I have is, should the input PngImage be an & reference? More refactoring may be required to allow this, as I don't think you can create an Arc from a shared reference without cloning.

    opened by andrews05 0
  • Other input formats?

    Other input formats?

    Hello, I used to use optipng on the output of long image processing pipelines and when doing so, I chose the simplest possible interchange format to avoid any useless encoding cost. Usually, it was PPM (since I knew my input didn't have an alpha channel).

    Would it be possible for oxipng to support at least one such format? Netpbm would probably be the most suitable and the image crate seems to have support for some of them (https://docs.rs/image/latest/image/codecs/pnm/index.html).

    For an idea of the "cost" of using PNG in this situation (multiplied by num_images / num_cpu):

    $ magick identify /tmp/tmp.ppm
    /tmp/tmp.ppm PPM 5551x6380 5551x6380+0+0 8-bit sRGB 101.324MiB 0.120u 0:00.087
    $ time magick convert -define png:compression-level=0 /tmp/tmp.ppm /tmp/tmp.png
    magick convert -define png:compression-level=0 /tmp/tmp.ppm /tmp/tmp.png  1.72s user 0.16s system 182% cpu 1.033 total
    $ time magick convert /tmp/tmp.ppm /tmp/tmp2.ppm
    magick convert /tmp/tmp.ppm /tmp/tmp2.ppm  0.19s user 0.11s system 99% cpu 0.300 total
    $ time magick convert /tmp/tmp.ppm /tmp/tmp.pam
    magick convert /tmp/tmp.ppm /tmp/tmp.pam  0.18s user 0.11s system 99% cpu 0.289 total
    $ time magick convert /tmp/tmp.ppm /tmp/tmp.miff
    magick convert /tmp/tmp.ppm /tmp/tmp.miff  0.19s user 0.11s system 99% cpu 0.302 total
    
    opened by ILoveGoulash 2
  • I try compile to wasm, but failed.

    I try compile to wasm, but failed.

    ℹ️ Compiling your crate in development mode...

    [INFO]: 🎯 Checking for the Wasm target... [INFO]: 🌀 Compiling to Wasm... Compiling libdeflate-sys v0.10.0 The following warnings were emitted during compilation:

    warning: In file included from libdeflate/lib/arm/cpu_features.c:38: warning: In file included from libdeflate/lib/arm/../cpu_features_common.h:38: warning: libdeflate/lib/arm/../lib_common.h:64:10: fatal error: 'string.h' file not found warning: #include <string.h> warning: ^~~~~~~~~~ warning: 1 error generated.

    error: failed to run custom build command for libdeflate-sys v0.10.0

    Caused by: process didn't exit successfully: /Users/ruansan/Development/kg/rust-projects/png-optimize/target/debug/build/libdeflate-sys-a95b79cdfa5005fb/build-script-build (exit status: 1) --- stdout TARGET = Some("wasm32-unknown-unknown") OPT_LEVEL = Some("0") HOST = Some("x86_64-apple-darwin") CC_wasm32-unknown-unknown = None CC_wasm32_unknown_unknown = None TARGET_CC = None CC = None CFLAGS_wasm32-unknown-unknown = None CFLAGS_wasm32_unknown_unknown = None TARGET_CFLAGS = None CFLAGS = None CRATE_CC_NO_DEFAULTS = None DEBUG = Some("true") running: "clang" "-O0" "-ffunction-sections" "-fdata-sections" "-fPIC" "-g" "-fno-omit-frame-pointer" "--target=wasm32-unknown-unknown" "-I" "libdeflate" "-o" "/Users/ruansan/Development/kg/rust-projects/png-optimize/target/wasm32-unknown-unknown/debug/build/libdeflate-sys-c7005d76609b5c0d/out/lib/libdeflate/lib/arm/cpu_features.o" "-c" "libdeflate/lib/arm/cpu_features.c" cargo:warning=In file included from libdeflate/lib/arm/cpu_features.c:38: cargo:warning=In file included from libdeflate/lib/arm/../cpu_features_common.h:38: cargo:warning=libdeflate/lib/arm/../lib_common.h:64:10: fatal error: 'string.h' file not found cargo:warning=#include <string.h> cargo:warning= ^~~~~~~~~~ cargo:warning=1 error generated. exit status: 1

    --- stderr

    error occurred: Command "clang" "-O0" "-ffunction-sections" "-fdata-sections" "-fPIC" "-g" "-fno-omit-frame-pointer" "--target=wasm32-unknown-unknown" "-I" "libdeflate" "-o" "/Users/ruansan/Development/kg/rust-projects/png-optimize/target/wasm32-unknown-unknown/debug/build/libdeflate-sys-c7005d76609b5c0d/out/lib/libdeflate/lib/arm/cpu_features.o" "-c" "libdeflate/lib/arm/cpu_features.c" with args "clang" did not execute successfully (status code exit status: 1).

    Error: Compiling your crate to WebAssembly failed Caused by: failed to execute cargo build: exited with exit status: 101 full command: "cargo" "build" "--lib" "--target" "wasm32-unknown-unknown"

    opened by kaneruan 2
  • Try to compress better than `pngcrush`

    Try to compress better than `pngcrush`

    Currently pngcrush at max settings always compresses a little more than oxipng at max settings.

    Source used is “Cosmic Cliffs” in the Carina Nebula (NIRCam and MIRI Composite Image) from webbtelescope.org.

    λ wget "https://stsci-opo.org/STScI-01G8GYD8B1H306SSPR4MY6NGN0.png"
    --2022-07-23 12:53:58--  https://stsci-opo.org/STScI-01G8GYD8B1H306SSPR4MY6NGN0.png
    Loaded CA certificate '/etc/ssl/certs/ca-certificates.crt'
    Resolving stsci-opo.org (stsci-opo.org)... 65.9.95.4, 65.9.95.10, 65.9.95.43, ...
    Connecting to stsci-opo.org (stsci-opo.org)|65.9.95.4|:443... connected.
    HTTP request sent, awaiting response... 200 OK
    Length: 50166110 (48M) [image/png]
    Saving to: ‘STScI-01G8GYD8B1H306SSPR4MY6NGN0.png’
    
    STScI-01G8GYD8B1H306SSPR4MY6NGN0.png            100%[======================================================================================================>]  47.84M  5.78MB/s    in 8.0s    
    
    2022-07-23 12:54:08 (5.96 MB/s) - ‘STScI-01G8GYD8B1H306SSPR4MY6NGN0.png’ saved [50166110/50166110]
    
    λ pngcrush -brute -rem alla -rem allb -rem text -reduce -check STScI-01G8GYD8B1H306SSPR4MY6NGN0.png pngcrush.png
      Recompressing IDAT chunks in STScI-01G8GYD8B1H306SSPR4MY6NGN0.png to pngcrush.png
       Total length of data found in critical chunks            =  50145112
    pngcrush: iCCP: known incorrect sRGB profile
       Best pngcrush method        =  16 (ws 15 fm 5 zl 2 zs 2) =  45336617
    CPU time decode 101.124237, encode 2127.660889, other 0.256804, total 2229.506836 sec
    
    λ oxipng --opt max --strip all --alpha --interlace 0 --threads 8 --out oxipng.png STScI-01G8GYD8B1H306SSPR4MY6NGN0.png
    Processing: STScI-01G8GYD8B1H306SSPR4MY6NGN0.png
        11264x3904 pixels, PNG format
        3x8 bits/pixel, RGB
        IDAT size = 50144491 bytes
        File size = 50166110 bytes
    Trying: 216 combinations
    Found better combination:
        zc = 1  zs = 2  f = 5        45398613 bytes
        IDAT size = 45398613 bytes (4745878 bytes decrease)
        file size = 45398670 bytes (4767440 bytes = 9.50% decrease)
    Output: oxipng.png
    
    λ ls -l *.png
    -rw-r--r-- 1 txtsd users 45398670 Jul 23 12:59 oxipng.png
    -rw-r--r-- 1 txtsd users 45336617 Jul 23 13:35 pngcrush.png
    -rw-r--r-- 1 txtsd users 50166110 Jul 21 23:25 STScI-01G8GYD8B1H306SSPR4MY6NGN0.png
    
    opened by txtsd 9
  • Not directly related to oxipng, but do you or anyone else know of something that works similarly for .ico files?

    Not directly related to oxipng, but do you or anyone else know of something that works similarly for .ico files?

    I absolutely love oxipng, it is my new favorite PNG optimizer.

    I have been using it like this (Is it possible to get more compression? did I miss any of the advanced options?):

    oxipng -o max --strip all -a -Z *.png

    I am wondering if there is a tool that does something similar for .ico files? (I still have one of these for old browser compatibility)

    opened by Jieiku 14
Releases(v8.0.0)
Owner
Josh Holmer
Wannabe multimedia engineer. Crab enthusiast. 10x polyglot rockstar ninja unicorn.
Josh Holmer
A quasi-lossless Balkanoidal meta-lingual compressor.

A quasi-lossless Balkanoidal meta-lingual compressor. Background It has long been accepted that Serbian is a compact variant of Russian, with less lib

Emil Koutanov 3 Aug 17, 2022
Fast encoder/decoder for the lossless DTM 16 bit image format

DTM Image Format Fast encoder/decoder for the DTM image format. The DTM image format is a 16-bit lossless image format supporting one to four channels

Kurt Kühnert 4 Oct 15, 2022
A simple command-line utility (and Rust crate!) for converting from a conventional image file (e.g. a PNG file) into a pixel-art version constructed with emoji

EmojiPix This is a simple command-line utility (and Rust crate!) for converting from a conventional image file (e.g. a PNG file) into a pixel-art vers

Michael Milton 22 Dec 6, 2022
PNG decoding and encoding library in pure Rust

PNG Decoder/Encoder PNG decoder/encoder in pure Rust. It contains all features required to handle the entirety of the PngSuite by Willem van Schack. p

image-rs 247 Dec 25, 2022
Refract - A guided AVIF/JPEG XL/WebP conversion utility for JPEG and PNG sources.

Refract GTK Refract is a guided image conversion tool written in Rust for x86-64 Linux systems with GTK. It takes JPEG and PNG image sources and produ

Blobfolio 34 Nov 28, 2022
🖼️Combines a Javascript and WASM file into a single executable polygot PNG+HTML file.

WASIMAGE Combines a Javascript and WASM file into a single executable polygot PNG+HTML file. Usage: cargo install wasimage wasimage --wasm-file my.was

Nervive 2 Mar 30, 2022
Add image watermark for multiple file (jpeg, jpg, png, tiff, bmp,etc)

Rust image watermark Add image watermark CLI program for multiple image format (jpeg, jpg, png, tiff, bmp, etc.) manipulation, browser WASM build supp

Johnathan 5 Jan 20, 2023
Image Compression Algorithm

Image Compression Algorithm ?? A new lossless image compression algorithm. In the newest version the algorithm performs rather good, but manages to su

Hannes 31 May 10, 2022
Automated image compression for efficiently distributing images on the web.

Imager Apparently this project made it into the GitHub Archive Program. About Imager is a tool for automated image compression, and can competitively

Imager IO 487 Dec 25, 2022
Zopfli Compression Algorithm is a compression library programmed in C to perform very good, but slow, deflate or zlib compression.

Zopfli Compression Algorithm is a compression library programmed in C to perform very good, but slow, deflate or zlib compression.

Google 3.2k Jan 6, 2023
A Rust encoder/decoder for Dominic Szablewski's QOI format for fast, lossless image compression.

QOI - The “Quite OK Image” format This is a Rust encoder and decoder for Dominic Szablewski's QOI format for fast, lossless image compression. See the

Chevy Ray Johnston 62 Nov 29, 2022
Mirror of oxipng for pre-commit.

oxipng pre-commit mirror Mirror of oxipng for pre-commit. Installation Add to your pre-commit config: - repo: https://github.com/adamchainz/pre-comm

Adam Johnson 11 Jan 15, 2022
A keyboard layout optimizer for layouts of the

Keyboard Layout Optimizer Neo variant layout optimizer written in rust. The optimizer is based on the "evolve-keyboard-layout" scripts by ArneBab. It

Dario Götz 29 Jan 4, 2023
A Wasm component optimizer (mostly a wrapper around wasm-opt)

component-opt An optimizer for Wasm Components Current Status This project currently only offers one optimization and does not allow it to be configur

Robin Brown 6 Mar 4, 2024
Lossless compressor and decompressor for numerical data using quantiles

This rust library compresses and decompresses sequences of numerical data very well. It currently supports the following data types: i32, i64, u32, u64, f32, f64. Smaller data types like i16 can be efficiently compressed by casting to i32. Timestamp support may come soon in the future.

Martin 163 Dec 14, 2022
A library and application for lossless, format-preserving, two-pass optimization and repair of Vorbis data, reducing its size without altering any audio information.

OptiVorbis A library and application for lossless, format-preserving, two-pass optimization and repair of Vorbis data, reducing its size without alter

OptiVorbis 27 Jan 3, 2023
A quasi-lossless Balkanoidal meta-lingual compressor.

A quasi-lossless Balkanoidal meta-lingual compressor. Background It has long been accepted that Serbian is a compact variant of Russian, with less lib

Emil Koutanov 3 Aug 17, 2022
Fast encoder/decoder for the lossless DTM 16 bit image format

DTM Image Format Fast encoder/decoder for the DTM image format. The DTM image format is a 16-bit lossless image format supporting one to four channels

Kurt Kühnert 4 Oct 15, 2022
Secure multithreaded packet sniffer

sniffglue sniffglue is a network sniffer written in rust. Network packets are parsed concurrently using a thread pool to utilize all cpu cores. Projec

null 914 Dec 30, 2022
A multithreaded programming language!

hydracane A multithreaded programming language! Getting started Coming Soon! Features: Multithreaded Platform independent Folders: src/vm: The Virtual

Krishna Ramasimha 0 Dec 10, 2021