Yes, tools for creating CSS sprites exist. I even made one such
service . But they break from time to time (as now, mine). But the team is worth a lot, and
imagemagick . Let's see how we can create CSS sprites only from the command line.
Creating a picture
To begin with, we have a list of individual files:
$ ls
1.png 2.gif dot.png phoney.gif tw.gif
- 1.png
- 2.gif
- dot.png
- phoney.gif
- tw.gif
Make a sprite out of them:
$ convert *png *gif -append result/result-sprite.png
Yes that's all. See the result.

Read more
The
imagemagick command usually looks like this:
$ convert image1.png image2.png image3.png -append result/result-sprite.png
We can replace the list of pictures with an asterisk:
$ convert * -append result-sprite.png
Or, as in the previous case, the mask is * .gif and * .png.
What about a horizontal sprite? All you need to do is replace -append with + append:
$ convert *png *gif +append result/result-sprite-horizon.png
')
Result:

Also note that the original images can be of any format - GIF, PNG, JPEG, we get PNG at the output. I would recommend starting with PNG8:
$ convert *png *gif -append PNG8:result/result-sprite-horizon.png
CSS
Since these are all manual operations, CSS is not automatically generated. But it is also quite simple. Take a vertical sprite:

All images will have the background-position-x property equal to 0px.
At the first picture the 16x16 coordinate background-position-y is also 0px. Then:
.first { width: 16px; height: 16px; background: url(result/result-sprite.png) 0 0; }
... where the coordinates 0 0 are optional and can be omitted.
The second picture is also 16x16, so more convenient. Its X coordinate is 0, and Y is the height of the previous image with the opposite sign:
.second { width: 16px; height: 16px; background: url(result/result-sprite.png) 0 -16px; }
And so on. Y coordinate = Y of the previous element - the height of the previous one.
But ... but ... every time find out the size and track height? You are joking?
Imagemagick comes to the rescue.
'identify' allows you to get basic information about the image:
$ identify 1.png
1.png PNG 16x16 16x16 + 0 + 0 DirectClass 8-bit 260b
'identify' also has the
'-format' option and supports the mask *. Therefore, it is easy to get all the information in a pleasant way:
$ identify -format "%g - %f\n" *
16x16 + 0 + 0 - 1.png
16x16 + 0 + 0 - 2.gif
6x6 + 0 + 0 - dot.png
10x16 + 0 + 0 - phoney.gif
16x16 + 0 + 0 - tw.gif
% f is the file name,% g is the geometry.
\ n - line break for easy display.
Therefore, if you want to get the Y coordinate of the 5th element, add up the heights of the previous ones: 16 + 16 + 6 + 16
.last { width: 16px; height: 16px; background: url(result-sprite.png) 0 -54px }
Some optimizations
Imagemagick does not generate optimized PNGs, so some optimizations are needed. You can use
pngout, optipng, etc. Or web tools like
smush.it or
punypng.com .
Or how about ... smush.it on the command line:
$ curl http://www.smushit.com/ysmush.it/ws.php?img=http://www.phpied.com/files/sprt/result/result-sprite.png
The result is a JSON object:
{"src": "http: \ / \ / www.phpied.com \ / files \ / sprt \ / result \ /result-sprite.png",
"src_size": 1759,
"dest": "http: \ / \ / smushit.zenfs.com \ / results \ / 5a737623 \ / smush \ /% 2Ffiles% 2Fsprt% 2Fresult% 2Fresult-sprite.png",
"dest_size": 1052,
"percent": "40.19",
"id": "}
The savings are almost doubled. Copy the "dest" field
$ curl http:\/\/smushit.zenfs.com\/results\/5a737623\/smush\/%2Ffiles%2Fsprt%2Fresult%2Fresult-sprite.png > result/smushed-sprite.png
That's all.
Summarize
1. Create a sprite:
$ convert *png *gif -append PNG8:result/result-sprite.png
2. Get the dimensions:
$ identify -format "%g - %f\n" *png *gif
3. And optimize:
$ curl http://www.smushit.com/ysmush.it/ws.php?img=http://url...
Translation of the article by Stoyan Stefanov
Command-line CSS spriting .
PS Theme ImageMagick was already
mentioned in Habré, but the second part of this article seemed to me useful and I decided to translate it entirely.