问题描述:

I'm trying to convert some images into either PNG or JPG and trying to find out which format will result in the smaller file size. With most of the cases PNG will give me the best compression but some odd images I get better compression out of JPG. I have two questions:

  1. What characteristics of image will cause it to give better results?

  2. Is there a way to pre-determine which format will give me better

    results without converting them first?

This photo gives better compression result using PNG

This photo provides substantially better compression using JPG

网友答案:

I have absolutely no time to develop this line of thought further but the image entropy is probably a good discriminant for selecting JPEG or PNG - see my earlier comment on your question.

If you use ImageMagick, you can calculate the Entropy easily like this:

identify -verbose -features 1 image.jpg | grep -i -A1 entropy

Your top image gives output like this:

identify -verbose -features 1 t.jpg | grep -i -A1 entropy
Sum Entropy:
    0.703064, 0.723437, 0.733147, 0.733015, 0.723166
  Entropy:
    1.01034, 1.12974, 1.14983, 1.15122, 1.11028
  Difference Entropy:
    0.433414, 0.647495, 0.665738, 0.671079, 0.604431

and your bottom image gives output like this:

identify -verbose -features 1 b.jpg | grep -i -A1 entropy
  Sum Entropy:
    1.60934, 1.62512, 1.65567, 1.65315, 1.63582
  Entropy:
    2.19687, 2.33206, 2.44111, 2.43816, 2.35205
  Difference Entropy:
    0.737134, 0.879926, 0.980157, 0.979763, 0.894245

I suspect images with a higher entropy will compress better as JPEGs and those with a lower entropy will fare better as PNGs - but I have to dash now :-)

There are 5 values for each type of entropy - horizontal, vertical, left diag, right diag and overall. I think the last value is the only one you need consider.

Updated

Ok, I have had a little more time to spend on this now. I do not have a pile of sample images to test my theory on, so I did it a different way. I made a little script to calculate the following for a given input file:

  • ratio of JPEG size to PNG size
  • entropy

Here it is:

#!/bin/bash
f="$1"
jsize=$(convert "$f" -strip JPG:- | wc -c)
psize=$(convert "$f" PNG:- | wc -c)
jpratio=$(echo $jsize*100/$psize | bc)
# Make greyscale version for entropy calculation
rm temp*.jpg 2> /dev/null
convert "$f" -colorspace gray temp.jpg
entropy=$(identify -verbose -features 1 temp.jpg | grep -A1 "  Entropy:" | tail -n 1 | awk -F, '{print $5}')
echo $jpratio:$entropy

So, for a given image, you would do this:

./go image.jpg
8:3.3       # JPEG is 8x bigger than PNG and entropy is 3.3

Then I took your image and added different amounts of noise to it to increase its entropy, like this

for i in {1..99}; do convert bottom.jpg +noise Gaussian -evaluate add ${i}% xx${i}.jpg;done

that gives me files called xx1.jpg with 1% noise, xx2.jpg with 2% noise and so on, up to xx99.jpg with 99% noise.

Then I ran each of the files through the first script, like this:

for f in xx*.jpg; do ./go $f;done > data.txt

to give me data.txt.

Then I created the following gnuplot command file plot.cmd:

set title 'Plotted with Gnuplot'
set ylabel 'Entropy'
set xlabel 'JPEG size/PNG Size'
set grid
set terminal postscript color landscape dashed enhanced 'Times-Roman'
set output 'file.eps'
plot 'data.txt'

and ran it with

gnuplot plot.cmd

And I got the following plot which shows that as ImageMagick's entropy number increases, the ratio of JPEG size to PNG size improves in favour of JPEG... not very scientific, but something at least. Maybe you could run the script against the type of images you normally use and see what you get.

网友答案:

That depends very much on your use case.

1) JPG is usually not as good for text because the artifacts tend to "smear" or blur the image. For photos, this is usually not a problem; also for high-resolution textual images the problem will be much less pronounced (because the blur radius is smaller relative to image size).

Note that PNG is usually used to losslessly compress images, while JPG is inherently lossy. With a higher compression ratio, JPG files will be much smaller, but the artifacts will be more pronounced. Note also that there are programs that are able to do lossy compression in PNG (which could well beat JPG compression in some cases).

In short: PNGs will work well with computer-generated images, because those tend to be quite regular and thus easy to deflate. JPGs will fare better with photos which tend to have more jitter, which is hard to compress. When you move away from ImageMagick and libpng, there are other possibilities.

2) While it would be possible to train a neural network to decide whether JPG or PNG would compress better, it would probably take longer and be less exact than just trying both and looking at the output. Note also that there are some approximative measurements that can tell you if an image is too blurry (which may help you setting the correct compression level if you want to tune further).

网友答案:

One big difference is that PNG allows for alpha transparencies so that you can see parts of what is behind the image. Jpg will block out a rectangle.

相关阅读:
Top