
My challenge was to write a script to generate random images which I will use as background images on my blog. Whilst these images can be relatively quick and easy to manually create, I wanted to have a little fun and see what the randomly-generated output would look like.
I settled on two-colour linear gradients generated via a Python script. The images are output in SVG format and the image consists of a combination of two random colours (rgb 0-255) in a random linear gradient.
The SVG output
I first needed to learn how a gradient is mapped in a SVG. Basically, there are two points, x
and y
, meaning a straight line, declared via a <linearGradient>
node. Then, there are <stop>
nodes which declare the colour at certain positions along the gradient. Let’s call this “the fade” where the two colours mix; I’m looking for a smooth, soft blend at the transition point.
With a simple, two-colour gradient in mind, the output I was looking for was similar to this:
The SVG code is relatively straightforward:
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 1400 400">
<rect width="1400" height="400"/>
<defs>
<linearGradient id="a" x1="22%" y1="31%" x2="9%" y2="74%">
<stop offset="0%" style="stop-color:rgb(81,169,147);stop-opacity:1" />
<stop offset="100%" style="stop-color:rgb(204,238,41);stop-opacity:1" />
</linearGradient>
</defs>
<rect fill="url(#a)" width="1400" height="400"/>
</svg>
The Python script
Using random
, two classes are required; one to randomise the points x
and y
and the other to randomise the colours, specified as RGB. Because we need two colours, we need to set two lines (x1:y1
& x2:y2
).
The rest is fairly self-explanatory.
#!/usr/bin/env python3
import random
class rand():
def __str__(self):
return str(random.randint(0, 100))
class rgbset():
def __str__(self):
return str(random.randint(0, 255))
ran = rand()
rgb = rgbset()
svg1 = '<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 1400 400">\n<rect width="1400" height="400"/>\n<defs>\n'
svg2 = '<linearGradient id="a" x1="'+str(ran)+'%" y1="'+str(ran)+'%" x2="'+str(ran)+'%" y2="'+str(ran)+'%">\n'
svg3 = '<stop offset="0%" style="stop-color:rgb('+str(rgb)+','+str(rgb)+','+str(rgb)+');stop-opacity:1" />\n'
svg4 = '<stop offset="100%" style="stop-color:rgb('+str(rgb)+','+str(rgb)+','+str(rgb)+');stop-opacity:1" />\n'
svg5 = '</linearGradient>\n</defs>\n<rect fill="url(#a)" width="1400" height="400"/>\n</svg>'
# write to file
file = open("grad.svg", "w")
file.writelines("%s%s%s%s%s" % (svg1,svg2,svg3,svg4,svg5))
file.close()
Some interesting results can be obtained by randomising the stop offset=
output but, as mentioned above, my personal preference is for a nice, smooth transition.
GitHub
The script is on GitHub along with a shell script to output 10 gradients at a time. Some further examples of the output are also available.