calibreapp / image-actions

A Github Action that automatically compresses JPEGs, PNGs and WebPs in Pull Requests.
https://calibreapp.com/blog/compress-images-in-prs
GNU General Public License v3.0
1.43k stars 67 forks source link

image-actions versus TinyPng #90

Open tunetheweb opened 3 years ago

tunetheweb commented 3 years ago

TinyPNG.com seems to produce much smaller images (40-60% smaller) with no noticeable loss in quality as far as my untrained eye can see. Any ideas how they do this? As I do really like this integration in GitHub Actions but at the moment I end up using this for the immediate effect and then going back and TinyPNG-ing the images later when I have time.

Any way to look at images and see what compression ratio they are using? Or are they stripping meta-data that Calibre is not? Or something else?

Would love it, it there was a simple config change to get same savings and save me this effort!

benschwarz commented 3 years ago

Thanks for the report @bazzadp, if you've got some file compression stats to share it may be helpful to figure out a target for us to reach.

To answer your questions:

Can we see what compression ratio they are using?

Nope. Though you can inspect the resulting files to explore their properties using the ImageMagick identify command:

identify -verbose public/slack-app-icon.png

Verbose command output ``` Image: Filename: public/slack-app-icon.png Format: PNG (Portable Network Graphics) Mime type: image/png Class: DirectClass Geometry: 800x800+0+0 Resolution: 28.35x28.35 Print size: 28.2187x28.2187 Units: PixelsPerCentimeter Colorspace: sRGB Type: PaletteAlpha Base type: Undefined Endianness: Undefined Depth: 8-bit Channel depth: Red: 8-bit Green: 8-bit Blue: 8-bit Alpha: 8-bit Channel statistics: Pixels: 640000 Red: min: 48 (0.188235) max: 255 (1) mean: 101.051 (0.396277) standard deviation: 90.2672 (0.353989) kurtosis: -0.751185 skewness: 1.11646 entropy: 0.167521 Green: min: 87 (0.341176) max: 255 (1) mean: 130.056 (0.510023) standard deviation: 73.2604 (0.287296) kurtosis: -0.751204 skewness: 1.11645 entropy: 0.18027 Blue: min: 244 (0.956863) max: 255 (1) mean: 246.819 (0.967917) standard deviation: 4.79682 (0.0188111) kurtosis: -0.751132 skewness: 1.11663 entropy: 0.237999 Alpha: min: 253 (0.992157) max: 255 (1) mean: 254.998 (0.99999) standard deviation: 0.0499688 (0.000195956) kurtosis: 362.061 skewness: -19.9588 entropy: 0.0159103 Image statistics: Overall: min: 48 (0.188235) max: 255 (1) mean: 183.231 (0.718552) standard deviation: 42.0936 (0.165073) kurtosis: -1.58611 skewness: -0.5781 entropy: 0.150425 Colors: 52 Histogram: 473514: (48,87,244,255) #3057F4FF srgba(48,87,244,1) 1598: (48,87,244,254) #3057F4FE srgba(48,87,244,0.996078) 1: (48,87,244,253) #3057F4FD srgba(48,87,244,0.992157) 143: (61,98,245,255) #3D62F5FF srgba(61,98,245,1) 6: (73,108,245,255) #496CF5FF srgba(73,108,245,1) 208: (74,108,245,255) #4A6CF5FF srgba(74,108,245,1) 6: (75,108,245,255) #4B6CF5FF srgba(75,108,245,1) 5: (87,118,245,255) #5776F5FF srgba(87,118,245,1) 55: (87,118,246,255) #5776F6FF srgba(87,118,246,1) 1: (88,118,246,255) #5876F6FF srgba(88,118,246,1) 46: (99,129,246,255) #6381F6FF srgba(99,129,246,1) 74: (100,129,247,255) #6481F7FF srgba(100,129,247,1) 11: (112,139,247,255) #708BF7FF srgba(112,139,247,1) 9: (112,139,248,255) #708BF8FF srgba(112,139,248,1) 25: (113,139,248,255) #718BF8FF srgba(113,139,248,1) 61: (125,150,248,255) #7D96F8FF srgba(125,150,248,1) 56: (126,150,248,255) #7E96F8FF srgba(126,150,248,1) 41: (138,160,248,255) #8AA0F8FF srgba(138,160,248,1) 21: (138,161,248,255) #8AA1F8FF srgba(138,161,248,1) 5: (139,160,249,255) #8BA0F9FF srgba(139,160,249,1) 4: (139,161,249,255) #8BA1F9FF srgba(139,161,249,1) 128: (151,171,249,255) #97ABF9FF srgba(151,171,249,1) 33: (152,171,250,255) #98ABFAFF srgba(152,171,250,1) 11: (163,181,250,255) #A3B5FAFF srgba(163,181,250,1) 8: (163,182,250,255) #A3B6FAFF srgba(163,182,250,1) 37: (164,181,250,255) #A4B5FAFF srgba(164,181,250,1) 5: (164,181,251,255) #A4B5FBFF srgba(164,181,251,1) 13: (164,182,250,255) #A4B6FAFF srgba(164,182,250,1) 2: (164,182,251,255) #A4B6FBFF srgba(164,182,251,1) 1: (165,182,251,255) #A5B6FBFF srgba(165,182,251,1) 27: (176,191,251,255) #B0BFFBFF srgba(176,191,251,1) 83: (177,192,251,255) #B1C0FBFF srgba(177,192,251,1) 2: (178,192,251,255) #B2C0FBFF srgba(178,192,251,1) 10: (189,201,251,255) #BDC9FBFF srgba(189,201,251,1) 3: (189,202,251,255) #BDCAFBFF srgba(189,202,251,1) 24: (190,202,251,255) #BECAFBFF srgba(190,202,251,1) 7: (190,203,251,255) #BECBFBFF srgba(190,203,251,1) 48: (202,212,252,255) #CAD4FCFF srgba(202,212,252,1) 5: (202,213,252,255) #CAD5FCFF srgba(202,213,252,1) 97: (203,213,252,255) #CBD5FCFF srgba(203,213,252,1) 5: (215,222,253,255) #D7DEFDFF srgba(215,222,253,1) 8: (215,223,253,255) #D7DFFDFF srgba(215,223,253,1) 29: (216,223,253,255) #D8DFFDFF srgba(216,223,253,1) 72: (228,233,254,255) #E4E9FEFF srgba(228,233,254,1) 20: (228,234,254,255) #E4EAFEFF srgba(228,234,254,1) 127: (229,234,254,255) #E5EAFEFF srgba(229,234,254,1) 64: (241,243,254,255) #F1F3FEFF srgba(241,243,254,1) 2: (241,244,254,255) #F1F4FEFF srgba(241,244,254,1) 91: (242,244,254,255) #F2F4FEFF srgba(242,244,254,1) 43: (254,254,255,255) #FEFEFFFF srgba(254,254,255,1) 78: (254,255,255,255) #FEFFFFFF srgba(254,255,255,1) 163027: (255,255,255,255) #FFFFFFFF white Rendering intent: Perceptual Gamma: 0.454545 Chromaticity: red primary: (0.64,0.33) green primary: (0.3,0.6) blue primary: (0.15,0.06) white point: (0.3127,0.329) Matte color: grey74 Background color: white Border color: srgb(223,223,223) Transparent color: none Interlace: None Intensity: Undefined Compose: Over Page geometry: 800x800+0+0 Dispose: Undefined Iterations: 0 Compression: Zip Orientation: Undefined Convex hull: 0,0 799,0 799,798 798,799 0,799 0,0 Minimum bounding box: 799,0 799,799 0,799 0,0 Properties: date:create: 2020-08-03T03:25:32+00:00 date:modify: 2020-06-18T02:59:15+00:00 minimum-bounding-box:_p: 0,0 minimum-bounding-box:_q: 799,0 minimum-bounding-box:_v: 798,799 minimum-bounding-box:angle: 0 minimum-bounding-box:area: 638401 minimum-bounding-box:height: 799 minimum-bounding-box:unrotate: -0 minimum-bounding-box:width: 799 png:IHDR.bit-depth-orig: 8 png:IHDR.bit_depth: 8 png:IHDR.color-type-orig: 6 png:IHDR.color_type: 6 (RGBA) png:IHDR.interlace_method: 0 (Not interlaced) png:IHDR.width,height: 800, 800 png:pHYs: x_res=2835, y_res=2835, units=1 png:sRGB: intent=0 (Perceptual Intent) signature: e2875f86b03276de50966f8e48fb15ab8c84b97be74570d96d58b429fcc1522c Artifacts: verbose: true Tainted: False Filesize: 9229B Number pixels: 640000 Pixels per second: 65.7632MP User time: 0.020u Elapsed time: 0:01.009 Version: ImageMagick 7.0.10-27 Q16 x86_64 2020-08-11 https://imagemagick.org ```

Maybe there's some clues there?

Or are they stripping meta-data that Calibre is not?

Internally image-actions uses sharp. The default configuration is to not include metadata. You'll find reference of this in the sharp docs:

The default behaviour, when withMetadata is not used, is to convert to the device-independent sRGB colour space and strip all metadata, including the removal of any ICC profile.

AFAIK, the differences you've observed are not metadata related.


@bazzadp Once we've some details on the images themselves, we can start to explore the differences in output and take it from there.

tunetheweb commented 3 years ago

Thanks @benschwarz !

Please find attached all the details

CalibreVsTinyPNG-Details.xlsx

It looks to me like the histogram is about half the size - which is directly reflected in the file size.

I dunno if they just have a much more aggressive compression level, or if they use any magic to figure out what they can get away with in terms of compression level?