Recipe: compress PNG with zopflipng

uhop edited this page Dec 1, 2014 · 5 revisions

PNG files produced by grunt-tight-sprite are ultimately created using node-canvas package, which is not very good at compression. The result is always can be compressed even further losslessly. While there are many utilities to do this compressing as a post-processing step, I came to rely on zopflipng of zopfli. In this recipe I call it using grunt-exec plugin.

Installing dependencies

First, you should install and compile zopfli, if it is not readily available on your platform:

git clone
cd zopfli
make zopflipng

Now you can move it to be in your default path, or call it directly by absolute name. The example below assumes a default path.


Now we are ready to write a gruntfile:


  tight_sprite: {
    icons: {
      options: {
        hide: "tests/icons"
      src: ["tests/icons/*/**/*.{png,jpg,jpeg,gif}"],
      dest: "tests/icons/sprite.png"
  exec: {
    compress_icons: {
        cmd: [
          "zopflipng -m <%= tight_sprite.icons.dest %> " +
            "<%= tight_sprite.icons.dest %>.zopfli",
          "mv <%= tight_sprite.icons.dest %>.zopfli " +
            "<%= tight_sprite.icons.dest %>"
        ].join(" && ")

grunt.registerTask("sprite", ["tight_sprite:icons", "exec:compress_icons"]);

As you can see, our compression command uses a reference to access a sprite file. Leveraging this grunt feature helps to keep all information in one place: later on we can modify the location of a sprite, and our compression task will "know" that automatically.

With this gruntfile we can build our sprite any time we want manually, or incorporate it in other tasks:

grunt sprite
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.