diff --git a/docs/config.rst b/docs/config.rst index 14904a4..ba35b41 100644 --- a/docs/config.rst +++ b/docs/config.rst @@ -777,6 +777,24 @@ Image options **Default:** ``2`` + ``oxipng`` + An optipng replacement written in Rust. Works much like optipng. + ``olevel`` + An integer between ``0`` (few optimizations) and ``6`` (many + optimizations). The default should be satisfactory for everyone, + higher levels than the default see almost no benefit. + + **Default:** ``2`` + + ``threads`` + An integer specifying how many threads per process to use. Note that + Overviewer spawns one oxipng process per Overviewer worker process, + so increasing this value if you already have one Overviewer process + per CPU thread makes little sense, and can actually slow down the + rendering. + + **Default:** ``1`` + ``pngcrush`` pngcrush, like optipng, is a lossless PNG recompressor. If you are able to do so, it is recommended to use optipng instead, as it generally yields better results in less diff --git a/overviewer_core/optimizeimages.py b/overviewer_core/optimizeimages.py index 69292e1..30b1ecd 100644 --- a/overviewer_core/optimizeimages.py +++ b/overviewer_core/optimizeimages.py @@ -192,6 +192,26 @@ class jpegoptim(Optimizer, JPEGOptimizer): return True +class oxipng(Optimizer, PNGOptimizer): + binarynames = ["oxipng"] + + def __init__(self, olevel=2, threads=1): + if olevel > 6: + raise Exception("olevel should be between 0 and 6 inclusive") + if threads < 1: + raise Exception("threads needs to be at least 1") + self.olevel = olevel + self.threads = threads + + def optimize(self, img): + Optimizer.fire_and_forget(self, [self.binaryname, "-o" + + str(self.olevel), "-q", "-t" + + str(self.threads), img]) + + def is_crusher(self): + return True + + def optimize_image(imgpath, imgformat, optimizers): for opt in optimizers: if imgformat == 'png':