contact Me

Use the form on the right to contact me.

You are welcome, to contact me regarding the topics of this page, my open source projects, or my work. Please use the contact form and leave a valid email address for me to respond to.

Thank you.

Egidestr. 9
44892 Bochum
Germany

/brain/dump

Random thoughts, bright ideas and interesting experiments. In short the ramblings of a fulltime nerd.

 

Generate sprites using the Web-Sprite-Generator

Jakob Westhoff

The usage of so called sprites is a well known technique among web developers to enhance the loading speed of webpages. With google now starting to measure loading speeds to integrate them into their ranking this gets even more important. Creating sprite images by hand can be a painful job. The Web-Sprite-Generator does automate this process for you. Furthermore it supports complex layout techniques of the final sprite image. One of these is a color matching algorithm, which allows to save up even more space in the final image.

What are web sprites exactly?

Sprites are a technique where a bunch of images is combined into one big picture containing all of them. Thus allowing the client to fetch the needed pictures in one request instead of multiple ones. Some of the common problems in web applications can be eliminated or at least weakened by this. First of all sprites minimize the loading time, as all pictures can be requested at once, without the need for multiple requests. Another side-effect of this technique, is the elimination of cache misses when images are changed, for example by on hover effects. Therefore flickering while the new image is loaded can be successfully avoided. With a growing rate of sites, which use animations and effects these days this gets more and more important every day.

You may ask yourself: Wait if all pictures are inside the same image, how can I use them independently of each other then?

This problem is solved using the CSS background-position property. This property allows the positioning of background images inside their container element. Under normal circumstances this does not help with the given problem, as it would only allow to move the big sprite image around in its container. But if negative offset values combined with fixed dimensions of the container are used an arbitrary clipping area of the sprite image can be created.

The example below does not only show an incarnation of a sprite image containing some mimetype icons of the humanity icon set, which has been automatically color grouped and created using the Web-Sprite-Generator, it does furthermore present a CSS rule, which isolates a certain icon to be displayed from this sprite.

sprite-example.png
.ogg-icon {
    background: transparent url( 'sprite.png' ) -240px -48px; 
    width: 48px;
    height: 48px;
}
ogg-cutout.png

The shown CSS rule displays a cutout of the sprite image showing the icon for ogg media files. Different rules like this one can be created for each of the images inside the sprite picture. The source images do not need to be of the same size, even though this example might suggest that.

What is this Web-Sprite-Generator you are talking about?

The Web-Sprite-Generator (wsgen) is an Application I wrote in PHP to automate the process of generating sprite images. It is fully unit tested and created with a architecture of loosely coupled components in mind. This ensures that most of the components and thereby processing steps can be replaced by a different implementation easily. For example, to read and render the final sprite images wsgen uses the GD library as it is available on most PHP installations. However writing another Renderer to support a different library like Cairo, would be a piece of cake.

Specifying which images to use for input

The application does ship with multiple implementations of DefinitionReaders which allows for different ways of inputting the source images to use for sprite generation. Besides a reader which takes a file pattern like some/directory/*.png as input, more complex ones exist. The default DefinitionReader takes a file with a CSS like syntax and extracts the needed information out of it.

Such a file may look something like this:

some.css:rule,
more.than:one > rule#is.possible {
  image: /path/to/image/file.png;
}
...

As you can see it follows the syntax of CSS definitions. Arbitrary sets of selectors may be used. These selectors will be used for the output definition CSS file, which will be created during the generator process.

The only property understood by the reader at this point is called image. The property name is followed by a colon. It does contain the path to an image, which should be added to the sprite using the CSS definition supplied.

If any other property is specified a parse error will be thrown.

I have plans to create a more sophisticated CSS parser in the future. The ultimate plan is to input normal CSS files and automatically identify and extract background images, which can be exported to a sprite image. At the moment this are however only some ideas I have got in my mind. A lack of freetime doesn't allow me to pursue these plans at the currently.

Controlling the layout of the final sprite

To be able to control the layout of the final sprite, different LayoutManager implementations exist. These control the positions of all the images inside a sprite as well as its final dimensions.

Currently two different LayoutManagers are available a vertical one, which simply positions all images below each other and a color group based layout, which sorts images by their color.

To generate the example image shown above the color grouping layout has been used. What exactly is done by this layout, which is the default one by the way, needs a little more explanation. The color group LayoutManager analyzes every available image, before the real layouting takes place. The average of the most significant colors of any given picture is calculated and compared to each other. Images within a certain range of this color are grouped together horizontally in one line, sorted descending by their height from left to right.

Grouping by color? Isn't this wasting a lot of space?

The question is why should a sprite images be grouped by its color? As the above example clearly shows there are a lot of free spots in the sprite, which could have been avoided using for example a simple vertical or horizontal layout approach. Isn't this color grouping making the image a lot bigger, than it needs to be?

Well the answer to this isn't that simple. First of all yes, the image will most likely be greater in its dimensions. But does this always include a bigger filesize? The answer to that question differs dependent on the used image format for output. For a lot of images on the web PNG is the format of choice. This does at least apply to icons and parts of the page design itself. Photos are another story, but they aren't normally delivered as sprites. PNG uses a lossless compression approach to minimize the image filesize. However before the actual compression takes place a preprocessing is applied to the picture. While a bunch of slightly different preprocessing algorithms is used, there outcome is quite the same. All of them transform the pictures raw color values into color difference values. Each pixel isn't stored as an absolute RGBA color value after that, but as a value indicating the difference in color from the pixels around it. Therefore fields of similar color are most likely to provide a better compression ratio, than fields with a lot of different colors.

This implies two things. First the overhead for empty regions in the created image changes the filesize only in a minimalistic way and may be disregarded. At least in the quantities occurring in our field of application. The second more important thing is that color grouping allows for better PNG compression ratios. Therefore minimizing the filesize even further. The results may vary for different sprites, but the color grouping showed an average filesize improvement by about 5% in my tests. In very special cases, where really big images have been used, this method even reduced the image size by nearly 34% in comparison to their randomly horizontal or vertically places sprites. However there are certain cases, in which the color grouped image may be bigger, than their vertical or horizontal counterparts. Therefore if filesize does really matter to you create different layouts and compare for yourself. Maybe I will integrate a functionality in the future, which uses every available layout once and compares the resulting filesizes afterwards choosing the smallest one.

A final word of advise. As already said, all of this theory does only apply to PNG images. Even though this is currently the only possible output format of the Web-Sprite-Generator, you should have this mind if other output formats are added in the future.

Download and detailed usage instructions

The download information can be found on the Web-Sprite-Generators project page together with detailed usage instructions and further information about all the different available application modules.

If you discover a bug please open up an issue at the projects github issue tracker. Comments on this blog article as well as the software itself are always welcome. Either use the comment function on this blog or email me directly.