How to Generate Gradients and Textures
I've recently extended that code to support radial as well as linear gradients and to be able to add Gaussian noise to give a bit of texture.
Here is the famous blue gradient used by default in Pinax:
which was generated with the following code:
write_png("example5.png", 50, 80, gradient(LINEAR_Y, NO_NOISE, [ (1.00, (0x00, 0x11, 0x33), (0x00, 0x55, 0x77)), ]))
Here is a glassy button background and the code used to create it. Notice the use of an HSV colour space to keep consistent hue and saturation and only vary the value.
write_png("example7.png", 200, 40, gradient(LINEAR_Y, NO_NOISE, [ (0.5, HSV(0.55, 0.2, 0.40), HSV(0.55, 0.2, 0.54)), (1.0, HSV(0.55, 0.2, 0.47), HSV(0.55, 0.2, 0.61)), ]))
This is an example of a subtle radial gradient combined with a Gaussian noise texture.
write_png("example11.png", 480, 100, gradient(RADIAL(0.5, 0.0), GAUSSIAN(0.01), [(0.8, (0x22, 0x22, 0x22), (0x00, 0x00, 0x00))] ))
write_png("example15.png", 200, 350, gradient(LINEAR_Y, GAUSSIAN(0.01), [(0.5, (0x01, 0x10, 0x09), (0x09, 0x2D, 0x1F))] ))
In practice, the non-radial, non-textured gradients only need to be one pixel thick. I've just made all these thicker so you can see the effect. With Gaussian noise textures, you want a thickness of at least 50 pixels (depending on the level of noise) otherwise the repetition is obvious. For example
where the number represents the actual width of the repeating background. Note that the noise is quite high in these examples (0.05) so even 50 isn't sufficient.
Obviously radial gradients need to be the full width as they aren't repeated.
The library code for generating all this (which is less than 80 lines of Python) is available from a git repository on GitHub.