10

We are exploring using Dianoga for dynamic image compression of assets in the media library. After installing the NuGet package and running some simple tests (comparing MediaCache image sizes with and without Dianoga), we are seeing approximately a 13% compression ratio.

However, if we take some example images and run them through online tools, we get much higher compression ratios (numbers below are from an example PNG with the starting size of 424 KB):

These seem to be using lossy compression methods, so I'm sure that has an impact, too.

Has anyone else implemented additional compression processors for Dianoga using other tools beyond the defaults?

3
  • 1
    Have you looked at TinyPNG? which does have an API. Oct 3, 2017 at 20:51
  • 1
    Dianoga is configurable: There is setting Media.Resizing.Quality in Dianoga.config that allows you to set quality of JPEG files. Unfortunately PNGOptimizerDll.dll for PNG compression is not configurable.
    – Anton
    Oct 3, 2017 at 20:52
  • 1
    You're comparing Dianoga's lossless compression to lossy algorithms. Sitecore already does lossy compression when the image is invoked with any resizing parameters, so there is no need to tack on another lossy algorithm. You will probably want to change the Media.Resizing.Quality configuration item for JPEG. I believe the default is 95% which is would likely increase file size for most images.
    – maz
    Oct 4, 2017 at 13:15

3 Answers 3

14

Your comparison of Dianoga with the other tools isn't quite fair- though what you found is accurate. A few things to point out:

  • Dianoga is lossless compression, which means as the size is reduced, the image should look identical from the version before it was run through the algorithm
  • Sitecore only applies the quality setting to an image if you include resize parameters in the media request. It appears with your tests (based on my own discoveries) that you were not altering the size of the image, e.g. h=100&w=100

I created an add-on to Dianoga called Dianoga.ImageMagick that is lossy. It is available via NuGet: Just install, and build, default settings should be sufficient for most.

What it does better

It contains a few crucial changes for your use-case (and mine):

  1. It sets the default quality setting in Sitecore to 100 and instead alters the quality of the image as part of the ImageMagick execution. Default is 70 for JPG, 9 for PNG (highest compression)
  2. It properly respects the Media.Resizing.MaxWidth and Media.Resizing.MaxHeight settings. Normally, these settings are only enforced on images when the image is upscaled- requested with query string params ‘h’ and ‘w’ greater than the original image. Native Sitecore will still output an image much larger than these settings if the original image exceeds the ‘MaxWidth’ or ‘MaxHeight’.

The result of Dianoga.ImageMagick is that ALL images get the same dimensional size reduction treatment if the image exceeds the ‘MaxWidth’ or ‘MaxHeight’. And all images are served with a reduced quality. In my tests it was not uncommon to go from 10+ MB to less than 1 MB for a given page with no obvious loss in image quality.

Since your question targeted PNGs, I ran a test quick with an image I created in Gimp. I intentionally applied no compression to my test image. The final size came out to 3.9 MB.

I added the image to Sitecore and ran it through the Dianoga.ImageMagick algorithm and it reduced it to 1.2 MB.

I then went back to Gimp to see how well it would do with full compression and it too reduced the image to 1.2 MB.

The beauty of using ImageMagick is that there is an enormous number of options available to meet anyone's needs: https://www.imagemagick.org/script/command-line-options.php. I have done my best to choose defaults that work for everyone, but feel free to tweak.

Relevant Settings

JPG:

<dianogaOptimizeImageMagickJpeg>
  <processor type="Dianoga.ImageMagick.ImageMagickResizer, Dianoga.ImageMagick">
    <ExePath>/App_Data/Dianoga Tools/imagemagick/magick.exe</ExePath>
    <AdditionalImageMagick>-quality 70 -dither None -define jpeg:fancy-upsampling=off -interlace none -colorspace sRGB</AdditionalImageMagick>
  </processor>
  ...
</dianogaOptimizeImageMagickJpeg>

PNG:

<dianogaOptimizeImageMagickPng>
  <processor type="Dianoga.ImageMagick.ImageMagickResizer, Dianoga.ImageMagick">
    <ExePath>/App_Data/Dianoga Tools/imagemagick/magick.exe</ExePath>
    <AdditionalImageMagick>-define png:compression-filter=5 -define png:compression-level=9 -define png:compression-strategy=1</AdditionalImageMagick>
  </processor>
  ...
</dianogaOptimizeImageMagickPng>

Further Help

5

I decided to add my own lossy PNG optimizer using pngquant. It's relatively straight-forward to do so and makes a big difference to file size.

If you'd like to use it, you can grab the source from my GitHub fork or see the specific changes I made in the PR to kamsar's source.

Do it yourself

  1. Download the command-line version of pngquant from here (under the Command-line section, you want the Binary for Windows link).
  2. Extract the files from the downloaded zip and add them to a new pngquant folder in the App_Data\Dianoga Tools folder in your solution.
  3. Create a class with the below implementation for pngquant.

    using System.IO;
    
    namespace MyDianoga.Optimizers.Pipelines.DianogaPng
    {
        // uses pngquant: https://pngquant.org/
        public class PngQuantCliOptimizer : CommandLineToolOptimizer
        {
            protected override bool OptimizerUsesSeparateOutputFile => false;
    
            protected override string CreateToolArguments(string tempFilePath, string tempOutputPath)
            {
                return $"--force --ext .png \"{tempFilePath}\"";
            }
    
            protected override string GetTempFilePath()
            {
                // must have a PNG extension and the default gives us .tmp
                return Path.ChangeExtension(base.GetTempFilePath(), ".png");
            }
        }
    }
    
  4. Add the below to App_Config\Include\Dianoga\Dianoga.Png.config inside the dianogaOptimizePng element, before the processor of type "Dianoga.Optimizers.Pipelines.DianogaPng.PngOptimizer, Dianoga".

    <processor type="MyDianoga.Optimizers.Pipelines.DianogaPng.PngQuantCliOptimizer, Dianoga">
      <ExePath>/App_Data/Dianoga Tools/pngquant/pngquant.exe</ExePath>
      <AdditionalToolArguments></AdditionalToolArguments>
    </processor>
    
2

Dianoga by default uses tools that offer lossless images compression. For example, for JPEGs, it uses the jpegtran tool.

However in my recent project, after lossless Dianoga compression, Google's Page Speed suggested that images can be compressed by additional 6MB in total on the homepage.

After January 2017 Page Speed algorithm changed a bit, and now it is recommended to use 85% quality for JPEGs. In other words, you should use lossy compression for JPEGs.

Google's Page Speed suggests using jpegtran or jpegoptim to compress JPEGs. The latter has the option to set jpeg quality.

I tested it, and with the quality set to 90%, I got quite similar results like Google's Page Speed suggest. The 700kb image (after lossless Dianoga compression) was compressed additional 500kb without any visual differences.

So I implemented jpegoptim processor for Dianoga. I added pull request for it here: Jpeg Lossy Pull Request to Dianoga

What else?

Additionally, you can think of resizing and compressing images during upload to Media Library. I described how to do this here: How to resize and compress images with Dianoga during upload to sitecore media library

2
  • any chance you could update these docs with what you are using for MaxWidthProcessor? thanks
    – nologo
    May 3, 2019 at 3:02
  • 1
    I'm not using MaxWidthProcessor. If you are reffering to article on my blog, it was a typo. I updated article. May 8, 2019 at 5:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.