(The complete code is available at the end of the article)
The idea is as follow: create a palette of colors, paint the whole image with a 2D->3D Bezier to create a smooth background, then stroke many 1D->2D Beziers. The palette of colors is created as follow: a few base colors are selected randomly, and many other variations are created from these base colors by altering the saturation and value without touching the hue. The background's Bezier takes as input the scaled coordinates in the image, and return as output the RGB value of the pixel at that coordinates. Its control point values are the RGB value of some randomly choosen colors in the palette. Its order too is randomly selected. The foreground Beziers also have a random order. Each stroke is divided into several substrokes, each one with random size, pen's hardness, and variation of colors from the same base color. The control point are the 2D coordinates of the curve, randomly selected for each stroke and then randomly modified at each substroke. Parameters allow to control the amount of randomness and achieve a satisfying result.
First, lets define a structure to hold all the needed data.
and a few constants to control the generation
and a few shortcuts.
Exception management is simple, there is only the case for invalid image dimensions to care about.
The base of the main function is the same as usual:
and the try block looks as follow. First, define the command line interface of the appli.
then parse and check the arguments
Once this is done, the generation can be performed. A CapyDisplay is used to display the image during generation and let the user interacts with the appli.
The generation is divided into the creation of the palette, the background generation and the foreground generation.
The palette is stored in a two dimensional array to make it easy to use later. The first index will be the base color index and the second index will be the variation.
The base color selection consists simply of setting the three RGB values at random. If the user requested a grey image these 3 values are forced to the same one.
The variations are obtained by converting the base color RGB to HSV (to be able to transform it without modifying the hue), randomly modifying the saturation and value, and converting it back to RGB.
The background generation consists of creating a 2D->3D Bezier
and using it to paint the image.
The foreground is created one stroke at a time.
Each stroke receives a random size for the pen and base color from the palette.
The initial shape of the stroke is created with a 1D->2D Bezier having random control points.
The stroke is then divided into several substrokes.
Each substroke is affected a variation of the base color of the stroke, and a hardness for the pen. The size of the pen and the shape of the stroke are altered as well.
Create a CapyPen and draw the substroke on the image. The color opacity is also altered here for a smoother blending in the image.
Everything put together, it becomes:
Compile with the following Makefile:
Examples of generated image (click to enlarge):