Linux
Linux

Compressing epub in Linux CLI


Many epub files are not saved in optimized sizes because the intended path is that you download them once to a device. However, if you use something like calibre-web and stream the file to readers every time you open the epub reader, you might wish some better compression was used. epubs are actually just zip files, with some very specific restrictions, but opening the files to recompress the images isn’t too hard.

I also found a lot of epubs use PNG format for the images and that is a mixed bag for improvement. PNG is a lossless format that does great for transparency and keeping text readable but not the best for file size. Converting to JPG would give huge benefits in size but updating the HTML code to reflect the new file extension is annoying. Most browsers actually don’t care if you send a JPG under the name of PNG but in this first example, we will just do the normal PNG compression route. For low color images, there is a mode that uses 8-bit palleted colors that can make PNG outperform JPG in quality and file size.

vi ~/bin/compressepub

echo starting epub compressing...

rm -rf ./epub #delete the folder if it already exists

unzip "$1" -d epub

# run pngpal on png images
shopt -s globstar
for i in **/*.png; do

   #pngpal is a lossless compressor that works best if it can go to 8-bit
   #pngpal "${i}"


   # pngquant is a lossy png compressor that reduces more bytes
    pngquant --skip-if-larger --output "${i}" --force "${i}"
done

# check for jpg

# rezip the epub
cd epub
zip -0 -X "../compress.epub" mimetype
zip -rDX9 "../compress.epub" * -x mimetype
cd ..

echo '-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-'

rm -rf ./epub
 # remove our work directory

mv "$1" "${1}.original"
mv compress.epub "$1"

du -h "${1}.original"
du -h "$1"

echo '-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-'

chmod +x ~/bin/compressepub

Better Compression

Using the trick mentioned above, your browser actually doesn’t care if a file says PNG but is actually a different format, as long as it knows how to render it. So lets go all out and use a next-gen image format like webp. You will need to make sure you have webp cli tool installed on the machine that will do this compression.

sudo apt install webp

Now take this large book full of screenshots and example images at a huge 112MB and re-encoding all the png into webp got us down to 13MB.

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
112M Unity 2018 Shaders and Effects Cookbook – John P. Doran.epub.original
13M Unity 2018 Shaders and Effects Cookbook – John P. Doran.epub
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

Our compression script will look a little different this time around

echo compressing with webp...

rm -rf ./epub #delete the folder if it already exists

unzip "$1" -d epub

# find images
shopt -s globstar
for i in **/*.{png,jpg,jpeg}; do
    cwebp -short "${i}" -o "${i}"
done

# zip epub
cd epub
zip -0 -X "../compress.epub" mimetype
zip -rDX9 "../compress.epub" * -x mimetype
cd ..

rm -rf ./epub # remove work directory

# move the compressed one and rename the other to original
mv "$1" "${1}.original"
mv compress.epub "$1"

echo '-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-'
du -h "${1}.original"
du -h "$1"
echo '-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-'

Downside to webp

Most new browsers support it (Chrome, Firefox, Edge, etc) with a weird exception for anything but the absolute latest Safari 14. If you are opening these epubs on older e-reader devices, it’s probably not going to like webp either so you are stuck with the PNG compression at the top.


I'm a 32 year old UIUC Computer Engineer building mobile apps, websites and hardware integrations with an interest in 3D printing, biotechnology and Arduinos.

View Comments
There are currently no comments.

This site uses Akismet to reduce spam. Learn how your comment data is processed.