In order to generate a BMP image file, we're going to need some pixel data. We've included a simple module fractal.py which produces pixel values for the iconic Mandelbrot set fractal.
We're not going to explain the fractal generation code in detail, still less the math behind it. But the code is simple enough, and it doesn't rely on any Python features we haven't encountered previously:
# fractal.py
"""Computing Mandelbrot sets."""
import math
def mandel(real, imag):
"""The logarithm of number of iterations needed to
determine whether a complex point is in the
Mandelbrot set.
Args:
real: The real coordinate
imag: The imaginary coordinate
Returns:
An integer in the range 1-255.
"""
x = 0
y = 0
for i in range(1, 257):
if x*x + y*y > 4.0:
break
xt = real + x*x - y*y
y = imag + 2.0 * x * y
x = xt
return int(math.log(i) * 256 / math.log(256)) - 1
def mandelbrot(size_x, size_y):
"""Make an Mandelbrot set image.
Args:
size_x: Image width
size_y: Image height
Returns:
A list of lists of integers in the range 0-255.
"""
return [ [mandel((3.5 * x / size_x) - 2.5,
(2.0 * y / size_y) - 1.0)
for x in range(size_x) ]
for y in range(size_y) ]
The key takeaway is that the mandelbrot() function uses nested list comprehensions to produce a list of lists of integers in the range 0–255. This list of lists represents an image of the fractal. The integer value for each point is produced by the mandel() function.
Generating fractal images
Let's fire up a REPL and use the fractal and bmp modules together. First we use the mandelbrot() function to product an image of 448 by 256 pixels. You'll get best results using images with an aspect ratio of 7:4:
>>> import fractal
>>> pixels = fractal.mandelbrot(448, 256)
We can take a look at the returned data structure:
>>> pixels
[[31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
31,31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
31, 31,
...
49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
49]]
It's a list of lists of integers, just as we were promised. Let's write those pixel values to a BMP file:
>>> import bmp
>>> bmp.write_grayscale("mandel.bmp", pixels)
Find the file and open it in an image viewer, for example by opening it in your web browser.
Picture of grayscale Mandelbrot set: