Simple image in generativepy
Martin McBride, 2021-11-07
Tags generativepy tutorial rectangle draw setup
Categories generativepy generativepy tutorial
In this article we will create a very simple vector image using generativepy. The image looks like this:
generativepy can also be used to create bitmap images, NumPy images, 3D images, and videos. These will be covered in later tutorials, but the basic process is similar in all cases.
Here is the code to draw the image above:
from generativepy.drawing import make_image, setup from generativepy.color import Color from generativepy.geometry import Rectangle def draw(ctx, pixel_width, pixel_height, frame_no, frame_count): setup(ctx, pixel_width, pixel_height, background=Color(0.4)) color = Color(1, 0.5, 0) Rectangle(ctx).of_corner_size((100, 150), 250, 200).fill(color) make_image("rectangle.png", draw, 500, 400)
This code is available on github in tutorial/getting-started/rectangle.py.
We will now look at this in more detail.
The basic structure of the code is:
- A user-defined function
drawthat does the drawing.
- A call to
make_image. This function controls the process of creating an image and saving it to a file. We pass in the
drawfunction to control the image content.
This basic structure is used throughout generativepy.
For vector images, like this one, generativepy uses the Pycairo library. In fact, as we will see,
ctx is a Pycairo drawing context.
make_image function, from the drawing module, is the main function that handles creating vector images.
The basic parameters are:
- The filename of the output PNG file.
drawfunction that does the actual drawing.
- The width and height of the image in pixels.
draw function is a function that we define ourselves to perform the drawing. It doesn't have to be called
draw - you can call it whatever you like, provided you pass its name into
make_image. It must have the correct parameters.
draw accepts 5 parameters:
ctxis a Pycairo context. This is like a virtual drawing surface that you can draw on in code. Whatever you draw will appear on the final image.
pixel_heightare the width and height of the image in pixels. These are the values that we passed into
frame_countare only used when you want to create image sequences (for videos), so we can ignore them here.
generativepy uses Pycairo as its drawing library. Pycairo has an extensive set of drawing functions that you can use to draw on the context, but generativepy also provides some extra functions that are useful for generative art. You can mix and match these functions - that is especially useful if you want to use some advanced feature of Pycairo that generativepy doesn't directly support. It is usually best to use the generativepy functions if possible, as they act at a slightly higher level.
draw function calls the
setup function to set up the drawing area, then draws a rectangle.
setup function isn't mandatory, but it does some useful things so you will often want to call it.
setup accepts 3 required parameters - the
pixel_height that were passed in to the
draw function. It has some optional parameters that do various things.
In this case, we are setting the
background parameter to
Color(0.4) which sets the background colour to a mid grey (it sets r, g and b to 40%). We define the colour using the color module of generativepy.
We also create another colour,
Color(1, 0.5, 0) for use later on. This is 100% red, 50% green and 0% blue, which is an orange colour.
Drawing a rectangle
We use a
Rectangle object to draw a rectangle, like this:
Rectangle(ctx).of_corner_size((100, 150), 250, 200).fill(color)
All shapes are drawn using the same pattern:
- Declare a shape object, for example
Rectangle(ctx). The context is passed in at this stage.
- An of_xxx function is used to define the shape. In this case,
of_corner_sizedefines a rectangle from the position of its corner, and its width and height. The corner is specified using an
- A drawing function is then used to actually draw the shape. In this case, we use
fillthat fills the shape with the supplied orange colour.
By default, the size and position of shapes we draw using generativepy are measured in pixels, based on the size of the image we are creating.
- The origin of the coordinate system (0, 0) is at the top left of the image.
- x values increase from left to right.
- y values increase as you move down the image.
In our case:
- Our image is 500 by 400 pixels.
- The orange rectangle is 250 by 200 pixels.
- The position of the rectangle (that is, the position of its top-left corner) is at pixel position (100, 150).
This diagram illustrates the coordinates of the rectangle:
The example place is a good place to start if you want to experiment with other shape objects, which all work in a similar way.