Schneimi’s Dev Weblog

Batch generated spritemap and css with ImageMagick on Windows

Posted in CSS,Eclipse by schneimi on February 3, 2013
Tags: , , , ,

I had the idea of one click generated spritemaps for quiet a while, but never had time to look into it and kept going on manually creating them by online service for my projects. When I read an article about command line css spriting, I was amazed, how easy the map can be built using ImageMagick and that it’s even possible to read width and height from the images. Nevertheless, the automated generation of the css code was still missing. Especially when the icon order changes, this is still annoying work.

This made me think…we know how to create the spritemap and can also read the width and height of each sprite with ImageMagick, so the only thing that is left, is to cycle through the sprites, read width or height from them and write the css code to a file. Then I dig out some of my Windows batch skills and came up with the following little batch script. It’s not that easy to understand, so I made some comments on the relevant lines.


@echo off
rem /* prepare environment */
setlocal EnableDelayedExpansion
del spritemap.png
del spritemap.css
set position=0
set sign=
rem /* execute imagick convert and create a horizontal (use -append for vertical) sprite map, using black as transparency color */
convert.exe *.png -transparent black +append spritemap.png
rem /* loop through all png files */
for /f %%f in ('dir /B *.png') do (
  rem /* for each file execute imagick identify */
  for /f "tokens=3 delims= " %%i in ('identify.exe %%f') do (
    rem /* parse the image width from the result (use tokens=2 for height in a vertical sprite map) */
    for /f "tokens=1 delims=x" %%j in ('echo %%i') DO (
      rem /* for each image append this css code to the spritemap.css file */
      echo .ui-%%~nf { background-image: url^("../img/spritemap.png"^)^; background-position: !sign!!position!px 0^; }>>spritemap.css
      rem /* calculate the next background position */
      set sign=-
      set /a position=%%j+position

In my case the css is for custom icons in jQuery Mobile. This example only runs with all files in one folder, but paths can be adapted easily, as well as the css output. Also further image optimization with tools like optipng, as described in the mentioned article, can be easily added.

I Hope this makes someone as much happy as I are, finally having found a fully automated solution. For me it’s a perfect solution, because I already use batch-scripts to merge and pack all css and js files with one click in eclipse and I just had to add this script to my existing batch file.

Speed-up your website with one click in eclipse

Posted in CSS,Eclipse,JS by schneimi on April 30, 2009
Tags: , , , , , ,

The most important influence on the loading time of a website, apart from the amount and size of images, is the loading of JS and CSS files.

This tutorial shows you three approaches to speed up the loading of JS and CSS and how to combine them in a batch script. Finally it shows how to integrate the script in eclipse and to execute it with one click.

First of all, I will shortly describe the different approaches, before going into detail.

During development you need structure and overview, so it is necessary to split the JS and CSS code into different files. But the more files you include in your website, the more network connections have to be set up on loading, which costs unnecessary time and traffic.

To avoid this problem, the idea is to consolidate all files (of one type) to one file, so that only one connection has to be set up.

Shrinking is the removal of all unneeded characters like whitespace and comments in your code. Further the replacement of long variable-names by short ones, which simultaneously obfuscates the code.

To reduce the data being transferred, the webserver can compress it before sending. A receiving webbrowser should be able to recognize the compression and decompress the data.

The most popular compression for websites is the GZIP compression, which is supported by pretty much all browsers.

The following steps are for Windows users, but I am sure you can transform them to Linux without much effort!

1) Consolidation
The first step is to consolidate your JS and CSS files, so you only have to shrink and compress one file of each type.

Because JS and CSS includes are globally loaded into the browser, we are able to just glue all files together and include them as one file. A very simple method to achieve that, is the use of the copy command as follows:

>copy *.css styles_consolidated.css /B
>copy *.js scripts_consolidated.js /B

The /B does a binary copy and avoids text encoding problems!

2) Shrinking
To get rid of unnecessary characters in your code, there are several tools available. As we want to automate the procedure later, we choose the YUI-Compressor which is a great java command line tool that supports JS as well as CSS.

The only thing we have to do, is to set it on a JS or CSS file to create a shrinked version:

>java -jar yuicompressor-2.4.1.jar scripts_consolidated.js -o scripts_shrinked.js
>java -jar yuicompressor-2.4.1.jar styles_consolidated.css -o styles_shrinked.css

If there are any errors in your code, you will get a notice here!

3) Compression
There are two ways compression can be applied. You can compress a file once and deposit it, or you can compress a file on-the-fly when transmitting it.

I use the on-the-fly compression with PHP, because I use PHP anyway and the file is still readable. This is useful during development, where you may want to skip the shrinking for debugging and get useful line numbers in error messages.

To activate the compression for a file, you just have to make it into a PHP file and add one line of code:


<?php ob_start('ob_gzhandler');header("Content-type: text/javascript; charset: UTF-8"); ?>
[content of scripts_shrinked.js]


<?php ob_start('ob_gzhandler');header("Content-type: text/css; charset: UTF-8"); ?>
[content of styles_shrinked.css]

You include these PHP files like normal JS and CSS files:

<script type="text/javascript" src="scripts_shrinked.js.php"></script>
<link rel="stylesheet" type="text/css" href="styles_shrinked.css.php" />

4) Combination
To combine all three approaches, we will create a little batch script.

But first, we need to create two PHP files that will be used to apply the GZIP compression to our consolidated and shrinked JS and CSS file.


<?php ob_start('ob_gzhandler');header("Content-type: text/javascript; charset: UTF-8"); ?>


<?php ob_start('ob_gzhandler');header("Content-type: text/css; charset: UTF-8"); ?>

The following batch script is just an example and is set up for CakePHP and the use in different environments. You have to adapt the paths for individual usage!


@echo on
copy %1\app\vendors\js\protoaculous1.6.packed.js+%1\app\webroot\js\*.js %1\app\webroot\js\scripts_consolidated.js /B
java -jar %1\app\vendors\yuicompressor-2.4.1.jar %1\app\webroot\js\scripts_consolidated.js -o %1\app\webroot\js\scripts_shrinked.js
copy %1\app\gzip_js.php+%1\app\webroot\js\scripts_shrinked.js %1\app\webroot\js\scripts.js.php /B /Y
@echo off
del %1\app\webroot\js\scripts_consolidated.js
del %1\app\webroot\js\scripts_shrinked.js

@echo on
copy %1\app\webroot\css\*.css %1\app\webroot\css\styles_consolidated.css /B
java -jar %1\app\vendors\yuicompressor-2.4.1.jar %1\app\webroot\css\styles_consolidated.css -o %1\app\webroot\css\styles_shrinked.css
copy %1\app\gzip_css.php+%1\app\webroot\css\styles_shrinked.css %1\app\webroot\css\styles.css.php /B /Y
@echo off
del %1\app\webroot\css\styles_consolidated.css
del %1\app\webroot\css\styles_shrinked.css

Note that additional files are added with a plus sign!

Finally, we have to execute the script with the approot as first parameter and let the magic happen:

>combine.bat [cakePHP approot]

5) Eclipse integration
Eclipse offers an easy way to integrate external programs and scripts. Here is what you have to do to be able to execute the script with one click:

  1. Open the External Tools Dialog (in submenu of the run-button with red toolbox)
  2. Create a new entry
  3. Enter some name
  4. Enter the location: ${workspace_loc:cake\app\combine.bat}
  5. Enter Arguments: ${workspace_loc:cake}
  6. Choose the “Common” tab
  7. Check “External Tools” under “Display in favorites menu”
  8. Check “Allocate console (necessary for input)” to see the output in the console view

Now you should be able to select the created external tool and execute it with one click.