Crush png in Sitecore

This post describes a module to crush png in Sitecore which can be downloaded from Sitecore MarketPlace and the latest version of the code is also available free on github.

Chrush png in Sitecore

Continuing my fight with Google Page Speed.

.NET does not offer an approach for compressing png files other than the default compression. This makes it hard to please google page speed automatically since one of their checks is if the images on a site are losslessly compressed.

To compress a png file further than the default compression and still without loss then unnecessary metadata must be removed from the file. I do not really know which metadata this is or how it is removed. Several tools have been developed by other people who specializes in image compression.

Crushing a png file can take time depending on its size so it is not something which can be done on-the-fly at least not without proper support in .NET (a small plead to Microsoft).

So to make sure that png images can be crushed by Sitecore editors I made a button for the Media tab in the content editor/media library ribbon which is shown when the selected item is a png file.

When the button is clicked a custom pipeline is started which calls the command line version of pngcrush. When the png file has been crushed it is saved back in the media library either replacing the existing media item or creating a new depending on a setting.

The code for crushing

First  I thought about which steps was required to crush the png and which arguments they should resolve. I then created a new include config fileand declared the following custom pipeline:

The arguments should contain the media item to crunch, two temporary file paths for source and destination files and the path to the pngcrush executable.

 Locating the pngcrush executable

First step is to locate the pngcrush executable which is located in the /bin directory. If it does not exist then break the pipeline with an error message.

Note, a x64 bit version of pngcrush is used in the module.

Creating the temporary files

Next thing is to create a temporary file for the source and stream the media item content into this file.

 Crushing the png

Now we have the executable, the source file and the name of the destination file so all that is left is to call the pngcrush executable with these parameters.

I also added a setting for using the -brute argument for pngcrush.

Saving the crushed png

Last step is to save the crushed png back into the media library. I made a setting for either instructing the module to replace the existing media item or to create a new one. The new one will be prefixed with the word _crunched.

If the destination file does not exist then it is because the source file was really not a png file. This can happen since someone might have named another image type as .png and then pngcrush will fail but it does not throw an exception.

Inserting the button

Now the pipeline is ready so all that is left is to start the pipeline from a command which then can be mapped to a new button in the media tab.

The command hides the button if the currently selected item is not a png file.

In Sitecore we create a new button under /sitecore/content/Applications/Content Editor/Ribbons/Contextual Ribbons/Images/Media/Image in the core database.

buttoncrushpnginsitecore

To map the button with the command we make the following entry in /App_Config/Commands.config

Now when we select a png media item in the media library the button will appear.

CrunchPng

In this version there is no progress indication when the button is pressed and it can take even up to some minutes if the png is a MB or more. It works very fast for small png files though.

By the way the extra settings for replacing existing item and using the -brute argument looks like this:

Final question, why is the module called CrunchPng and not CrushPng. Well to be honest mostly due to a small distraction at first and then not willing to rename the whole project after I got started. I think it makes sense though since the module crunches the data of the png file through to crush its file size. And no I am not renaming the module.

That was it, quite straight forward.

Anders Laub

Anders Laub Christoffersen

Anders has been working with Sitecore for over a decade and has in this time been the lead developer and architect on several large scale enterprise solutions all around the world. Anders has been nominated a Sitecore Technical MVP three years in a row for 2014, 2015 and 2016. Anders is now working as a Sr. Solutions Architect at Sitecore in Copenhagen.

Leave a Reply

Your email address will not be published. Required fields are marked *

*
*
Website