Web Graphics and Animations

(Your monitor must be set to 24-bit colour (or 32-bit), i.e. millions of colours or “true colour”, to view the examples in a correct way.)
You should know that the two most common picture formats used in web pages, are GIF (CompuServe Graphics Interchange Format) and JPEG (Joint Photographers Expert Group). Actually, these are practically the only formats supported in most web browsers. A third format, PNG (Portable Network Graphics) has gained popularity and is supported by most modern browsers. It has been designed to avoid the patents and licensing associated with GIF, and is more performant. Even though the patents on GIF have recently expired, PNG still is technically superior so it's expected to replace GIF in the long run.
It's very important to know the difference between these formats, since this is essential in making pages that both load fast and are of high quality. The goal is to reduce the disk space - and download time - to a minimum, without making your site look ugly. If you don't know much about image formats, read on. If you think you know, read on anyway, maybe you'll get surprised.
The main difference between GIF, JPEG and PNG, is the way the images are stored. In GIF and PNG, every pixel is stored as it is, without altering the image data. However, a type of compression is used, which reduces the file size. This is called "lossless compression". JPEG on the other hand, uses an adjustable "lossy compression". This means that in order to make the file smaller, the image is slightly altered. This is done in such a way that it is as invisible to the human eye as possible. More info about this can be found in the paragraph about compression.
Another difference is the amount of available colours: a GIF uses a colour table which can hold at maximum 256 colours. So you can use 256 colours or grayscales, or less. However, using less colours means less data, hence a smaller file. This method of using a limited amount of colours with a colour table, is called indexed colour. JPEG always uses either 8-bit grayscale (256 shades of gray) or 24-bit colour (16.777.216 colours). So there is no reduction in file size by using fewer colours, but all existing colours can be used simultaneously. PNG supports both indexed colour, and full 24-bit colour.
An advantage of GIF, is that it supports transparency: you can mark some of the colours in the colour table as "transparent", hence all pixels that have those colours, will not be drawn. This allows images of any shape. This is impossible in JPEG, because due to the lossy compression, there is no guarantee that the pixels in the saved image retain their original colour. A JPEG image is therefore necessarily rectangular. PNG also supports transparency by using a separate alpha channel. This even allows to vary the degree of transparency, but unfortunately, not all browsers are able to render this correctly.
Yet another important difference: JPEG and PNG can only contain one image, so no animations. If you want to make an animation, use GIF, you have no choice (unless you do it in QuickTime or Flash, but that's only suitable for large animations or movies, and requires a plug-in). There's an extension of PNG, called MNG, which allows animations too, but it's not widely supported.
Recent paint programs offer the possibility to save a JPEG in "Progressive" format, which is analog to "Interlaced" GIF: the image is displayed while it's being loaded, and becomes more refined as more data is received. There's only one disadvantage: older browsers and some image programs cannot read progressive JPEG files. But don't worry: almost nobody uses such browsers anymore today.
To demonstrate the differences between GIF, JPEG and PNG, the same image (yes, I know it's ugly) is displayed here in each of the formats:

GIF image, 4961 bytes

JPEG image, 18342 bytes

PNG image, 3783 bytes
The GIF image (at the left) takes only 4.8 KBytes, while the JPEG takes 18 KBytes! The PNG image is even smaller with 3.7 KBytes. And if you look well enough, you'll see that the JPEG doesn't even look as good as the GIF or PNG: the borders between the colours are blurred. This is due to JPEG's "lossy" compression algorithm. By adjusting the compression, I can make the JPEG as small as 8.5 KBytes, but then it looks really horrible; if I would try to make it look as good as the GIF, it would take even more disk space. So you might think that JPEG is a useless format. Well, just look at another example:

GIF image, 22040 bytes

JPEG image, 11174 bytes
Now the GIF image (at the left) takes 21.5 KBytes, and the JPEG takes only 10.9 KBytes! And if your monitor is set to a high colour resolution, you may see that the GIF has a kind of "grainy" look. This is because it can only use a limited number of colours, so some colours need to be approximated by "dithering", i.e. using dot patterns. This does not only deteriorate the image, but it also prevents efficient compression.
So why does this image take much less space in JPEG format, while the previous example was much smaller in GIF? The reason is: the latter had only 8 colours and consists of large uniform areas. This allows for efficient compression, and only 3 bits are needed to represent each colour. The second image, however, has much more colours, even more than 256. Here, its GIF version was saved with only 64 colours (6 bits), because it would take even more space if I had used all 256 colours. The JPEG compression algorithm does a much better job here, because it is well suited for smooth colour transitions.
What about PNG for such types of images? Well, the situation is more complex. You could save this image with a 64 colour map like the GIF; in this case it takes about 21K, so only slightly better than the GIF. It's also possible to save the original image with all its colours, but then the file takes a whopping 76K! This is because PNG doesn't use a lossy compression like JPEG. Therefore, unless it's absolutely necessary that the image quality is not degraded in any way, on webpages PNG is unsuitable for photographs and other images with smooth colour gradients.
It is clear that for indexed colour images with few colours, GIF and PNG are the winners, with PNG beating GIF in most cases. So a general rule of thumb for choosing between GIF (PNG) and JPEG, is: if your image contains only few colours, and/or large areas in the exact same colour, you should use GIF or indexed colour PNG, with the smallest number of colours that still faithfully represents your image. Also, if your image is really small, like smaller than 32x32 pixels, you should also use GIF/PNG, because a JPEG file has a larger data header, and for such small images it's mostly useless to use more than 256 colours anyway.
For (non-tiny) images with a lot of colours (like a photo, rendered 3D image...), JPEG is the optimal format. Remember, you can (and should) choose the compression rate while saving JPEG files. You should use the strongest compression that still looks good enough (a preview function when saving is a must). If your image has a lot of detail, use a "Good" compression rate (6 on a scale of 10), which introduces only very little fuzz. However, "Medium" (3/10) or even "Low" (1/10) will be good enough in most cases, especially when your image has no sharp details (like most backgrounds). For webpages, you should never use "Maximum" (above 6/10). Just let your eyes decide!
Pop quiz: in which format would you save this pure black-and-white-only image?

Mystery format #1, 1359 bytes

Mystery format #2, 7887 bytes
In GIF or PNG, right! Mystery format 1 is GIF, 2 is JPEG. As you can see, JPEG is a ridiculous waste of disk space for such images! The JPEG takes 6 times the size of the GIF, and it's even saved in Photoshop's lowest possible quality setting! This causes the ugly noise you can see. I hope that if you remember only one thing from this page, it'll be at least this one...
As for the better performance of PNG compared to GIF: this is only valid if the image is compressed with the best method — PNG supports multiple methods, but a decent graphics application will offer the option to choose the best method automatically, or do this by default. Therefore, if you want to squeeze every bit of redundant data out of your webpage, you should use PNG for indexed colour images and keep GIF for animations only.
However, the problem with PNG is that it's relatively new, and not (fully) supported by all software. Also — this may sound stupid but that happens to be the way some people are — since it's a free format and not designed by some huge software company, some software developers look down upon it, even though it is technically superior to GIF. Also, some programs have a sloppy PNG implementation, or don't give the option to use the most efficient compression and use an inefficient default instead (Photoshop 7 is an example, even though older versions had this option).
Therefore, I would only recommend using PNG if you know what you're doing, and have verified that your graphics program doesn't cripple PNG's potential. For saving PNG files in their most optimal format, I can recommend using the GIMP.
Last but not least: if you're not sure whether to use JPEG or GIF/PNG, just save your image in all formats, and look at their sizes: if the smallest file still looks good enough, use it. Remember that most people zap to another page if it takes too long to load images which occupy far more space than they should.
Also, make sure not to include useless data in your image files. Many programs like to include colour profiles, previews and stuff like that in your images. These are almost always useless to web visitors, and can take huge amounts of space. Turn them off or use the 'web export' function of your program, if available. I've seen web comics with 60K of real image data and 600K of unknown, useless metadata. That's a big don't!
(This paragraph is intended for the people interested in the "magic" behind GIF, PNG and JPEG image compression. For the average webmaster this is way too detailed so you may skip this paragraph if you wish, although it may give extra insight.)
I already mentioned the words "lossless" and "lossy" compression. The lossless compression technique a GIF file uses, is a variant of the Lempel-Ziv compression scheme. This is the same type of scheme used in "ZIP" files, and that's logical because when you compress a text or data file, the compression must be lossless, i.e. the data must come out exactly as it went in. Unfortunately, the GIF compression has been patented by Unisys and therefore it's hard to find the details about how it works, and programmers need to pay a fee when using it in their own software.
Lempel-ziv type compression is a fairly simple technique: it tries to describe data as a combination of preceding data. This means: the more repetition in the data (like lots of consecutive pixels in the same colour in an image), the better the compression will work. But it's also the reason why an error in a ZIP or GIF file is fatal for all data coming after the error: the error is copied into the following data, which becomes completely useless.
Important about this scheme, is that it works in a 1-dimensional way, while images are 2-dimensional. So a choice had to be made on how to represent images: as a sequence of rows, or columns. The simplest decision was rows, because that's the way images are drawn on a computer screen. So images are read and written in the same way most western people read and write text (left-to-right, top-to-bottom). This has a major impact on how efficiently an image is being compressed. Consider the following two images:

GIF image, 381 bytes

GIF image, 1295 bytes
If you understand what I just said, it shouldn't surprise you that the right image takes more than 3 times the size of the left image! This is because the left image consists of long rows of the same colour, while in the right image, the colours change much more often from a rows point of view. There are some programs available which exploit this fact to make GIF images smaller without noticeable degradation of the image: by increasing the amount of repeating patterns in the rows of the image, the compression efficiency can be boosted.
When saving the above images in the PNG format, they take 139 and 128 bytes, respectively. The small difference between both, is because PNG can use more complex ways to represent the image than just row-by-row. A good PNG implementation will always try multiple descriptions when saving an image, and pick the one with the best compression performance. PNG also uses a different compression scheme.
The compression scheme of JPEG is a totally different story. This scheme works roughly as follows: first, the image is split up into squares of 8x8 pixels. Then, a Discrete Cosine Transform (DCT) is computed for each square. This transformation gives a kind of description of the square in terms of frequencies. Next, this frequency description is being reduced in such a way that it will have minimal visual impact. This mostly means: throw away the highest and weakest frequency components. The user can determine how much is thrown away, allowing a trade-off between image quality and file size. This reduced description is then compressed with a simple lossless scheme (Huffman encoding) and that's what's in your final JPEG file. Displaying the JPEG is just the reverse operation: decompresing of the Huffman code, and then computing the inverse DCT.
To demonstrate the fact that the image is divided in 8x8 blocks, here are three images:

JPEG image, 1614 bytes

JPEG image, 6702 bytes

Noise in second image (amplified)
The first two images are compressed with the lowest possible JPEG quality. However, the leftmost image has been reproduced flawlessly and takes little more than its GIF equivalent, while the middle image (which is nothing more than the left image shifted over 4 pixels in both directions) has some noise and takes 4 times the disk space of the left image! The noise in this image is shown in the rightmost image, which is the difference between the original and the JPEG, amplified to make it more visible. This difference in performance is self-evident, since the compression scheme had to work with more complicated 8x8 squares in the second image than in the first - the squares were just plain dumb uniform colours in that case!
You might be wondering what happens if the image is not evenly divisable into 8x8 squares. In that case, image data is simply repeated at the borders until the image fits. So if you really want to squeeze the max out of your JPEG images, make their dimensions multiples of 8.
Because JPEG compression is based on frequencies, smooth images compress better than images with sharp components. With "better", I mean both better quality and a smaller file size, as illustrated in the second pair of images on this page.
By the way, the same conclusions count for most modern video compression schemes, like MPEG, DivX and 3ivx. They also split up the video frames into blocks (mostly 16x16) and use DCT transforms. But because they work with multiple frames, they can squeeze out a lot more redundancy by comparing subsequent frames.
It is obvious that the disk space occupied by an image is proportional to its area. However, due to the compression algorithms of GIF, PNG and JPEG, large empty (i.e. uniform) areas won't take much space. Also, images with lots of repetition will take less space than noisy images.
More important is that it's strongly recommended to specify the image's size in the webpage itself, even if you just want to display the image at its normal dimensions. E.g. for a 100x200 pixel image, the tag should look like: <IMG src="image.gif" width=100 height=200>. The reason for this, is that if you don't provide the image's size, a browser will only be able to display the page after the image has started loading, hence it will take much longer until the page shows up. Even worse, if the image can't be loaded for some reason, your entire lay-out may get scrambled.
Another important tip: never make your images larger than they appear on your web page, that's the most efficient way to make users angry because of the slow loading speed. For example, if you have a catalog of large images which can be browsed via thumbnails, don't use these large images themselves for their thumbnails, but use small copies of them, which take much less disk space. Otherwise the loading time for your catalog will be as long as for all the large images together and that's just not practical for people with a slow connection!
The only occasion where it's justified to make the images larger than they appear on the page, is for special pages which need to look good when printed: for a 150dpi image, make your images twice as large than on the webpage, for 300dpi, make them four times as large (assuming your screen resolution is set to 75dpi).
On the other hand, an image which is displayed larger than it is, will look disgusting. Don't do this unless you really want to.
Most people know that the GIF format can contain a lot more than just a still picture. If you took the time to download the entire home page, you should have seen a lot of examples of this! Assembling animations is possible with some recent versions of drawing programs, but if you don't have any of these, you need a separate program. However, since these programs don't offer drawing tools, you need a drawing program too (I still consider PhotoShop as the best available.)
There are enough GIF animation programs available today. In the early days of the web, GifBuilder (freeware, by Yves Piguet) was an excellent Mac program, and for Windows users Gif Construction Set (shareWare, by Alchemy Mindworks) was popular, but there are far more programs now. For Linux, the GIMP has extensive ways to create GIF and MNG animations.
A GIF anim just contains several different GIF images (frames) which are displayed after each other. Each frame can have its own delay (expressed in 100ths of a second), size, position and disposal method. This means that you can build up a large image with small pieces, by adding a small part each time. Here's an example of this:
In this animation, each time a part of the sentence 'This is an example' was added, without disposing of the previous frame. The result is that each new part is put on top of the previous one, with as final result the entire phrase. If you would take this animation apart, you would get: a white rectangle, 5 small pieces of text, and a frame.
Making an animation is as easy as creating the different frames and putting them together. But making a GOOD animation is a different thing. A common problem are the different colour tables.
We know that a normal GIF can contain a maximum of 256 colours. This also counts for animations: only one colour palette per animation. The clue is to use a palette that represents the overall colours of the animation. This looks hard to do, but is quite easy: just make all the frames in 24-bit colour, and when they are ready, put all of them in one big file. Convert this file to 256 colours (or less) with an "Adaptive" palette and save this palette. Next, save all the separate frames in GIF files, using that palette. (In PhotoShop 4 or newer, you can use the 'Actions' palette to automate this.) Now you can import the frames in your animation program, using the palette of any frame as the overall palette.
Note: never use the option 'Remove unused colours' in any of the programs while doing this, because this can screw up the palette. You can try this while saving the final result.
You don't always need to use all those 256 colours. In fact, it's better to use as few as possible. If you know something about bits and bytes, you should know that a number with 'x' bits can contain 2x different values, a 7-bit number for example can represent 128 different values. So a GIF file with 7-bit colour has 128 colours.
You could think that GIF files can only have a number of colours that is a power of 2, but that's not the case. You can use any number between 2 and 256, and strange enough: a file with 200 colours takes less space than a file with 256 colours, although theoretically you would also need to use 8 bits to represent those 200 colours. I tested it (see graph at the right) and the file size seems to be approximately proportional to the number of used colours. (This is a result of the compression scheme of the GIF format, see above).
The morale of this mathematical story is: use as few colours as possible while still keeping the images appealing; your website visitors will be grateful to you!
An animation can contain transparent parts, just as any GIF file. The only 'disadvantage' of this is that you'll have to 'sacrifice' one colour of your palette to do this. Every pixel which has that specific colour will then be transparent. It is recommended to use pure blue for this colour, as it's rather rare in images. But you can use any colour you want.
What is special about transparency in animations, though, is that you can use a different transparent colour for each frame in the same animation. Using transparency is not only useful to create non-rectangular animations, but also for optimization (see below).
As said before, you can specify a delay for each separate frame. This delay is expressed in 100ths of a second (let's abbreviate this to cSec, for centiSeconds).
For example, to create a flashing light you only need two images: one for the light when it's off, one for the burning light. If you want the light to flash shortly each second, you can set the delay of the first frame to 95 cSec and of the second frame to 5 cSec. Notice that you can use totally different delays for the frames. In most 'classic' animations however, the delays are the same for all frames.
Mind that very fast animations (with delays of < 10 cSec) will not play fast enough on slower computers. But all frames will be displayed, this means that if the computer is not fast enough, the animation will be slowed down. (This is different from most other animation systems like QuickTime, which skip frames to keep the animation's timing correct.)
You can create two types of animations: 'simple' animations and 'looped' animations.
The first type will play its frames only once. This means that the animation will stop at the last frame and that frame will stay on the screen. This is useful to create a banner which comes scrolling or falling onto the screen or so. The animation starts either as soon as the image is being loaded (Netscape), or when the entire page has loaded (Internet Explorer) so you cannot specify when it will start.
Looped animations are most common. As you can guess, the animation will jump back to the first frame as soon as the last frame is reached, and so on. Again, there are two possibilities: you can repeat this loop for a limited number of times, or infinitely. I noticed that GifBuilder and some versions of GCS use a different system: if you check an animation as 'infinite' in GCS and open it in GifBuilder, you'll see that the loop is limited, though, but to a large number of iterations. So it's possible that some animations will stop running after a long time.
It can be very annoying having to wait for a large animation to load, especially if that animation appears to be quite simple. For example, you could make a large image with only a small flashing light in it. It is a bit ridiculous to use for each frame almost exactly the same image, while only a very small part of it changes. The animation will occupy a lot of space this way. So a solution to this is to use for the flashing light only a small image which covers the area that differs from the previous frame, and put this image on top of the previous frame, at the right position.
GifBuilder automatically checks which is the smallest rectangle that has changes in it, and shrinks the frame to that rectangle. This technique is called "Prune compression" and is also available in GCS.
If you don't understand what is meant here, open this "Weird Stuff" animation (from the former main page) with your animation program. You'll see that only the first frame contains the entire button, the others contain just the lights. I had to do this manually, since GifBuilder only shrinks the frames to the smallest rectangle, it is not able to cut away all similar parts. You need to use a transparent colour for this, otherwise it's impossible to create 'holes' in your image.
Ideally, you should make of each frame all pixels which do not differ from the previous frame transparent. Your animation won't contain any superfluous information this way! But if you have no specialised program for this you'll have more work with it than it's worth.
Optimizing can require a lot of work sometimes, but it surely is worth the effort: it speeds up the downloading, so this means people won't have to wait too long for your site to appear on their screen. A lot of people just stop downloading and go somewhere else if it takes too long, so...
Another way of reducing an animation's size is to use as few colours as possible, as described in the "Colours" section.
Using an image as background for your page can improve the lay-out, but there are a few complications which may have just the reverse effect. If you use an image with too much details, it may become annoying to read the text on top of it. Smoothing a too "busy" image may improve reading comfort. The general rule is to make a sufficiently large contrast between text and background. Yellow text on a near-white image is about the worst you can do! There are a few other colour combinations which are a pain to the eyes, like red text on a blue background, or green text on red. And last but not least, there are colour combinations that make text invisible for people with colour blindness. Remember: black text on a white background may look boring, but it's guaranteed to be readable.
A second common error people make when using an image as background, is: they don't use an appropriate background colour for the page itself. With "background colour", I mean the colour which is set with the "bgcolor" attribute of the BODY tag or its CSS equivalent. Imagine you have a page with white text over a dark image, and you didn't specify any background colour. Now what if that image loads extremely slow, or not at all? You then get white text over a white page! And that's not quite readable, is it? So just remember to provide a background colour which represents the dominant colour in the background image.
There are a few reasons not to use an animated GIF as background for your page. The first, and most important, is that an animated background may be extremely annoying if people need to read a lot of text between those wiggling and wobbling things. Only use animated backgrounds if you know what you're doing!
Another reason is that some browsers don't support this and in such cases the background won't be loaded at all. The more recent browsers, nl. everything from Internet Explorer 3.0 and NetScape 4.0 on, can handle animated backgrounds. If you really want to use one but want to avoid a flat background on older browsers, include a JavaScript which inserts a still image if the browser is below IE 3 or NetScape 4.
So, that's it. With this information you should be able to create decent graphics and animations. The only thing I cannot learn you is good taste, which, spiteful enough, is hard to find in some websites... Also, keep in mind that although animations can be fun, they become annoying easily, especially if your website's visitors are supposed to be paying attention to another part of the webpage, like a large block of text. Animations have the most effect when used sparely at the right occasions.