Image Compression Quality - Asking for Opinions

Would you notice these differences? Should I use lossy compression? (Read the OP)

  • Yes I would notice. The tradeoff is reasonable.

    Votes: 0 0.0%
  • I don't care - I just like pressing buttons

    Votes: 0 0.0%

  • Total voters
    8

kin-kun

Active Member
Modder
Jul 10, 2020
963
2,322
I've been repackaging some games, generally while using lossless image compression. Basically I've spending days using a brute force solver on the various zlib parameters to make the PNG header smaller.

I'm now looking at .

Let me give an example, with thumbnails (click for full size):
Before compression:
before.png
This is approximately 2.4 MB before header compression. It is 2.3 MB after header compression. Finding optimal zlib settings for all the PNG files in this game took about 24 hours.​

After compression:
after.png
This is approximately 657 KB or 28% of the original size. Lossy compression of all the PNG assets took about 15 minutes.​

Flipping back and forth you can see there are tiny changes. In this case they aren't even visible to the user as this is in motion (rotating).

Here's another example:
BeforeAfter
TownBefore.png TownAfter.png
4.2 MB - 4,199,579 bytes1.1 MB - 1,137,182 bytes
Here you see an ever so slight shift in the colors, most notable the foam on the water goes from a blueish color to more white.

The results are impressive to say the least. If I look at Succubus Farm:
Lossless compression:​
PNG assets go from 583,635,069 bytes to 322,068,011 bytes by compressing headers alone or 55% of the original size.​
Lossy compression:​
PNG assets go from 583,635,069 bytes to 115,033,463 bytes or 19% of the original size.​

Smaller assets have a number of advantages including:
  • Faster download times (less cost for metered connections)
  • Faster load times
  • Less memory usage
  • Less disk space usage
So here's my question and I realize it is subjective. Would you even notice these differences if you couldn't compare the two side by side? And is that worth the savings in file size?
 

hiya02

Member
Oct 14, 2019
169
95
Personally, I think it depends on the total size of the game. If it is large enough, say 5+ GB, then I'd like to have compressed version. For the smaller games, I don't think it is worth spending much time to compress it, unless the process is automated.
 

kin-kun

Active Member
Modder
Jul 10, 2020
963
2,322
Personally, I think it depends on the total size of the game. If it is large enough, say 5+ GB, then I'd like to have compressed version. For the smaller games, I don't think it is worth spending much time to compress it, unless the process is automated.
Oh yeah, this is all scripted. I can see why you might think otherwise. Using an automated script, it took 24 hours of real time with 4 cores fully loaded.
 

recreation

pure evil!
Respected User
Game Developer
Jun 10, 2018
6,268
22,311
In the first example the original is already low quality so that's not a good example. In the second example it's visible in some spots, but I bet nobody will ever notice unless you tell them, there's way to much going on in that image.
Honestly png compression is not really worth it imo, the compression algorythm is far from perfect, webp and/or jpg are far better in that case and png compression can also cause problem on some systems and software.

do people really care about game size?
Absolutely, you wouldn't believe how often people ask for compressed versions.
 
  • Like
Reactions: kin-kun

Winterfire

Forum Fanatic
Respected User
Game Developer
Sep 27, 2018
5,037
7,374
Eh... Compression is one of Ren'Py weaknesses.
The developer should only worry to deliver the best quality possible, nothing more.
WEBP/WEBM lossless offers the best quality with the smallest file size.
 
  • Like
Reactions: kin-kun

Baka plays

Engaged Member
Game Developer
Aug 31, 2017
2,533
5,501
Rendering 4k .png = 8MB big images.
After denoising and postwork, converting them to 1080p webp = roughly 700Kb size.
No complaints abt the image quality from neither my patrons nor in my game thread, so i guess i'm doing sth right.
Atm i got over 1000 images with a complete file size of roughly 740 MB(inclusing sound+music files).
 

Winterfire

Forum Fanatic
Respected User
Game Developer
Sep 27, 2018
5,037
7,374
Yeah, sounds about right.
WEBP is really good, there is really no reason to take it further than that.
If you put 100000 images in your game, you can't expect it to be 100mb.
 

Bip

Active Member
Donor
May 4, 2017
734
2,100
In my very own opinion and practice, for a final version (complete tag), I'll always go for the uncompressed version.
For an intermediate version, I'll always prefer patches from previous versions rather than compression. Fucking easy to do with renpy games, harder or impossible with other engines :(

When I do some pic lossy compression, I often go for a 85% quality compression. I hardly never choose a lower quality.
And I agree that going to a webp format is not a bad choice. (lossy) Compressing png files is awful, since it flattens the colors and I think everyone has seen the disaster of compressing a jpg.

But I really prefer a lossless compression, even if it's bigger.
 

Tompte

Member
Dec 22, 2017
215
155
I like the uncompressed better. Storage is cheap, do people really care about game size?
I think this is a very common fallacy. Just because you don't care about something doesn't mean everyone else feels the same. I used to think like this about a lot of things until I encountered the people who did care.

But I agree that it's probably not worth worrying about individual megabytes in this day and age (unless you're on mobile and want to stay below the mobile data size limit). I'd say people mostly care about orders of magnitude. Is it 1 meg? 10 megs? 100 megs? 1 gig?

If my game was 500 megs, I'd at least want to investigate where those megs were going and try to see if I could optimize it down a little.

Optimizing texture sizes is worthwhile if you get good reduction with low-to-no quality difference.

Personally though, and maybe I'm being a bit contradictory here, if a game is 12 megs I tend to go "pfft.. so it's what, 5 minutes long?" and skip it.
 
  • Like
Reactions: kin-kun

kin-kun

Active Member
Modder
Jul 10, 2020
963
2,322
First thank you all for the lively discussion.

I understand the argument that disk space is cheap. With SSDs it isn't as cheap as it used to be but generally it is cheap at least for a PC.

What isn't cheap is performance, bandwidth, and storage space on a phone/tablet.

Let me explain in more detail:
  • Performance
    • Larger images take more memory. More memory invalidates image caching faster, meaning more reads from disk.
    • Larger images require more time to read from disk.
  • Bandwidth
    • Turns out while most people have unlimited bandwidth, not all do. For example those in Australia pay per byte downloaded.
    • Using a phone can also have a metered connection.
  • Tablet/Phone Storage Space
    • A lot of the games I work on are RPGMaker MV games. I've successfully created JOIPlay packages, which makes it easy to take the same game and play it on mobile. Obviously that storage space is at a premium.
Now, I look at it this way:
if the savings are more than 5% it is worth up to 20 minutes of time. If the savings are more than 50% it is worth some real time/effort. If a game is less than 50 MB there's no point.

Here's a real example:
Original image assets of a game were 364 MB. (5804 images)
Eliminating unused assets from the game made it 174 MB. (Done by hand took multiple days, 5372 images)
With careful work and lossless compression brought it down to 142 MB.
Now here's where it gets interesting:
  • Running pngquant -f --ext .png --quality 85-100 "${item}.png" followed by pingo -sa "${item}.png"
    • Starting size 142 MB
    • Runs in about 6.5 minutes
    • Final size is 71 MB or 40% of 174 MB size
  • Running cwebp -q 85 -o "${item}.webp" -- "${item}.png"
    • Starting size 142 MB
    • Runs in about 1 minute
    • Final size is 53 MB or 30% of 174 MB
  • Running cwebp -q 85 -mt -m 6 -hint picture -af -o "${item}.webp" -- "${item}.png"
    • Starting size 142 MB
    • Runs in about 1 hour
    • Final size is 51 MB or 29% of 174 MB
  • Running cwebp -lossless -mt -hint picture -o "${item}.webp" -- "${item}.png"
    • Starting size 142 MB
    • Runs in about 90 seconds
    • Final size is 106 MB or 60% of 174 MB
  • Running cwebp -z 9 -mt -hint picture -o "${item}.webp" -- "${item}.png"
    • Starting size 142 MB
    • Runs in about 66 minutes
    • Final size is 97 MB or 56% of 174 MB
Assuming you have a recent version of GNU here's a script you can use to find all the png files in www and run them through another script (optimize_image.bash)
Bash:
#!/bin/bash
set -$-eu${DEBUG+xv}
function calcSize()
{
    find "${directory}" "${search_criteria[@]}" -print0 | du -bc --files0-from=- | tail -n 1 | cut -f 1
}

type="images"
directory="www"
search_criteria=("-type" "f" "(" "-iname" "*.png" "-o" "-iname" "*.webp" ")")

originalSize="$(calcSize)"
originalSizeH="$(numfmt --to=iec "${originalSize}")"
echo "Original size of ${type}: ${originalSizeH} (${originalSize} bytes)"

date
SECONDS=0
# Random order
#find "${directory}" "${search_criteria[@]}" -print0 | sort -R -z | parallel -0 -j 5 --eta bash "optimize_image.bash" "{}" > "optimize_${type}.log"

# Dictionary order
#find "${directory}" "${search_criteria[@]}" -print0 | sort -z | parallel -0 -j 4 --eta bash "optimize_image.bash" "{}" > "optimize_${type}.log"

# largest first
find "${directory}" "${search_criteria[@]}" -printf '%s %p\0' | sort -r -n -z | cut -z -d ' ' -f 2- | parallel -0 -j 4 --eta bash "optimize_image.bash" "{}" > "optimize_${type}.log"

# smallest first
#find "${directory}" "${search_criteria[@]}" -printf '%s %p\0' | sort -n -z | cut -z -d ' ' -f 2- | parallel -0 -j 4 --eta bash "optimize_image.bash" "{}" > "optimize_${type}.log"

# Most recently changed
#find "${directory}" "${search_criteria[@]}" -printf '%C@ %p\0' | sort -r -n -z | cut  -z -d ' ' -f 2- | parallel -0 -j 4 --eta bash "optimize_image.bash" "{}" > "optimize_${type}.log"

echo "Took ${SECONDS} seconds to optimize ${type}"
date

finalSize="$(calcSize)"
finalSizeH="$(numfmt --to=iec "${finalSize}")"
echo "Final size of ${type}: ${finalSizeH} (${finalSize} bytes)"
And here's what optimize_image.bash looks like
Bash:
#!/bin/bash
set -$-eu${DEBUG+xv}

function optimize_file
{
    local item="${1}"
    local ext=""
   
    # convert to webp
    cwebp -q 85 -mt -m 6 -hint picture -af -o "${item}.webp" -- "${item}.png" 2>&1
   
    mkdir -p "$(dirname "pic_hash/${item}")"
   
    sha512sum "${item}.webp" > "pic_hash/${item}.sha512"
}

file="${1%.*}"
# only works on png images
if [ -f "${file}.png" ]; then
    # See if we've hashed this file
    if [ -f "pic_hash/${file}.sha512" ]; then
        # If we've hashed this file and the has matches, do nothing
        # otherwise optimize it.
        sha512sum -c "pic_hash/${file}.sha512" || optimize_file "${file}"
    else
        # If we haven't hashed this file, optimize it (which will hash it)
        optimize_file "${file}"
    fi
fi
 
  • Like
Reactions: S-G-H