Random Art Generator is a command-line application. As such, it is called from a terminal, with several arguments or flags passed to it.
The general format for running RAG is as follow:
rag target-file-image [FLAGS] [OPTIONS]
For example:
rag profile.jpg --generations 100
Or using the circles
painter with specific parameters for illustration:
rag target.jpg --generations 10 --output mypic.png --background-color ff0022 --painter circles --painter-alpha 0.1-0.2 1.0 --painter-radius 1-100 --painter-radius-bias -3 --margins 10% --color-seed 0.9
Running with a single -h
or --help
argument will show you all arguments available, and a brief or semi-brief explanation of each, respectively:
rag -h
RAG was developed with a liberal approach to arguments: anything that make sense to be controlled via arguments, and is not too redundant with editing that could be manually performed using an external application like Photoshop, is added as an argument. Therefore, the list of arguments is large (and growing), and some of them might admitedly sound a bit too specific.
A list of all arguments, with examples, follow. Examples are generated with an argument of --rng-seed 1
(to make them easily reproducible), or with additional options to better expose differences between the result of each example, like variations of --painter-alpha
.
For the purpose of examples, this documentation uses the Mandrill test image as a "target" image.
- Flags/options
--background-color <color>
--benchmark
--blending-mode <blending-mode>...
-c
,--candidates <integer>
--color-seed <scale>
--diff <scale>
-g
,--generations <integer>
-h
,--help
-i
,--input <filename>
--margins <sizes>
--no-metadata
-t
,--max-tries <integer>
-o
,--output <filename>
-p
,--painter <painter>
--painter-alpha <alpha>...
--painter-alpha-bias <bias>
--painter-disable-anti-alias
--painter-height <size>...
--painter-height-bias <bias>
--painter-radius <size>...
--painter-radius-bias <bias>
--painter-wave-height <size>...
--painter-wave-height-bias <bias>
--painter-wave-length <size>...
--painter-wave-length-bias <bias>
--painter-width <size>...
--painter-width-bias <bias>
--rng-seed <integer>
-s
,--scale <float>
--save-often
--target-color-matrix <color-matrix>
- Data types
Default: 000000
Type: Color
The color to be used as the default background for the new image.
Outputs benchmark results.
With this flag, the application will gather some benchmark metrics and output them after it runs. This is useful to measure efficiency of the algorithm as it evolves.
Note that using this implies --candidates 1
. It's also recommended to use the same --rng-seed
value across different runs, for consistent results.
Default: normal
Type: Single string or list of strings enumerated from normal
, multiply
, screen
, overlay
, darken
, lighten
, color-dodge
, color-burn
, hard-light
, soft-light
, difference
, and exclusion
Blending mode(s) to be used when overlaying new candidates, either as a single entry, or as a list. The blending modes follow some of the classic Photoshop blending modes.
Use this option with caution. Some monotonic blending modes (screen
, multiply
, etc) might cause the image generation to never finish. For example, with a complete white base image, it's impossible for it to be altered further with the screen
blending mode.
Default: 0
Type: Integer
Number of parallel image painting candidates per try.
In general, the higher the number of candidates, the better the resulting images, at a cost of higher CPU usage.
When set to 0
, this uses the number of available cores in the CPU.
Default: 0
Type: Scale
Amount of color from the original target image to use as a "seed" when deciding on what color to use when painting a new candidate. With this set to 0
; the algorithm will try painting with a completely random new color; with this set to 1
, the algorithm will use the color already found in the target color; and everything in between is a blend of the two.
Using a higher color seed number causes the algorithm to generate valid candidates much faster, and thus create a new image that is closer to the target in shorter time. It does decrease the randomness of the output image, and could in some ways be seen as "cheating" as the algorithm isn't painting blindly anymore.
Default: 0
Type: Scale
Expected difference score to reach, indicating the desired difference from the new generated image to the target image. New candidates are generated continuously until the resulting difference is below this threshold.
On each successfull image generation, the new diff value is generated by calculating the color difference of every pixel. For example, for a completely white target image, a completely black image has 100% difference, while a gray image would have 50% difference.
Be aware that the lower the target difference, the longer the time taken for full generation, sometimes exponentially so. Very low diff numbers (e.g. 10% and lower) might be virtually impossible to reach, or take an unordinate amount of time.
Default: 0
Type: Integer
Number of successful generations desired.
This is equivalent to the number of times the result image is expected to be successfully painted. In general, the higher the number of generations, the closer the image will be to the target image.
Set to 0
if no limit is desired.
Displays this help in text form. Use -h
for a short output, and --help
for longer explanations.
Type: File path or name string
The filename for an input image, if any.
When present, the input image that serves as the starting image before anything is painted atop it. The --background-color
parameter is also ignored.
Default: 0
Type: Size as one of all
, or entries of vertical,horizontal
, top,horizontal,bottom
, or top,right,bottom,left
Set the margins for the output image.
This can either be a single size for all margins, or a comma-separated list of 2..4 items denoting the margins for each specific side (similar to how margins are written in CSS).
When a percentage unit is used, they refer to the maximum width or height of the image. Values higher than the image size (in pixels or in percentages higher than 100%
) are allowed, in which case they cause the paint algorithm to bleed out of the image space.
Disables writing image metadata.
By default, the output image file includes metadata with the software name and version, all generation statistics, and original command line arguments used, including original file names passed. With this flag set, nothing is written.
Default: 0
Type: Integer
Maximum number of image generation tries (successful or nor) to run.
On each try, the painter algorithm tries creating an image that is closer to the target image (with several "candidates" per try).
The more complex the result image gets, the harder it is to create an improved image, so it's common to have many unsuccessful tries. Use this option to set a maximum number of tries.
Using a limited number of tries can give a predicted time for completion, but also gives an unpredictable number of successful paints. Use the -g
/--generations
parameter to control the number of desired paints instead.
Set to 0
if no limit is desired.
Default: output.png
Type: File path or name string
The filename for the result image to be saved to.
On each successful generation, this file is rewritten with the results. Extensions such as .png
or .jpg
are allowed. More formats might be supported in the future.
If the destination file already exists, it is overwritten without warning.
Default: rects
Type: One of circles
, strokes
, or rects
Painter to be used.
This determines how new candidates will be painted when trying to approximate the target image. A selection of basic painters currently exist.
Painters can be further configured with other --painter-*
arguments.
Default: 1
Type: Single entry or list, of ranges or unique values, of opacity floats
Opacity to use when painting new images.
This can be either a single value between 0.0
(fully transparent) and 1.0
(fully opaque), or a range in the same scale for randomized values.
The argument is a list, so it can also feature more than one value (or ranges, or a mix of values or ranges), in which case one new entry is randomly picked for each new paint.
Default: 0
Type: Bias
Bias for distribution in --painter-alpha
ranges.
Disables calculating antialias on edges when painting new elements.
This makes rendering faster in some cases, but can produce jagged edges, and is therefore not recommended.
The one exception is when creating artwork meant to be printed. In that case, antialiased edges can produce dithering artifacts during the printing process; it is better to create an aliased result at a higher resolution instead (using --scale
) to match the printer's resolution.
Default: 0%-100%
Type: Single entry or list of sizes
Height to use when painting elements.
This applies when --painter
is set to rects
or strokes
.
The argument is a list, so it can also feature more than one value (or ranges, or a mix of values or ranges), in which case one new entry is randomly picked for each new paint.
Default: 0
Type: Bias
Bias for distribution in --painter-height
ranges.
Default: 0%-50%
Type: Single entry or list of sizes
Radius to use when painting elements, when applicable.
This applies when --painter
is set to circles
. In case a percentage value is passed, it is relative to either the width or height of the result image (whichever is smaller).
The argument is a list, so it can also feature more than one value (or ranges, or a mix of values or ranges), in which case one new entry is randomly picked for each new paint.
Default: 0
Type: Bias
Bias for distribution in --painter-radius
ranges.
Default: 0.5%
Type: Single entry or list of sizes
Height of paint waves, when applicable.
This applies when --painter
is set to strokes
. In case a percentage value is passed, it is always relative to the width of the result image.
In the strokes
painter, waves are the deformations that occur on the edges of each painted element. The waves have a height (their strength, perpendicular to the edge itself) and a length (the size of an entire wave along the direction of the edge). The higher the wave, the stronger they look.
Default: 0
Type: Bias
Bias for distribution in --painter-wave-height
ranges.
Default: 400%
Type: Single entry or list of sizes
Length of paint waves, when applicable.
This applies when --painter
is set to strokes
. In case a percentage value is passed, it is always relative to the height of the result image.
In the strokes
painter, waves are the deformations that occur on the edges of each painted element. The waves have a height (their strength, perpendicular to the edge itself) and a length (the size of an entire wave along the direction of the edge). This length encompasses a set of different waves (rather than just one wave), to create a noise-like pattern. The bigger the length, the gentler the wave looks, similarly to producing a sound wave of lower frequency.
Default: 0
Type: Bias
Bias for distribution in --painter-wave-length
ranges.
Default: 0%-100%
Type: Single entry or list of sizes
Height to use when painting elements.
This applies when --painter
is set to rects
or strokes
.
The argument is a list, so it can also feature more than one value (or ranges, or a mix of values or ranges), in which case one new entry is randomly picked for each new paint.
Default: 0
Type: Bias
Bias for distribution in --painter-width
ranges.
Default: 0
Type: Integer
The seed to use for the pseudorandom number generator.
This should be an unsigned 32-but integer number (that is, between and 0
and 4294967295
, inclusive). If 0
is passed, the seed iself is randomized.
When generating new candidates, the application tries creating new images in a randomized, but deterministic, fashion. This means that as long as all inputs - target images, parameters - are the same, the end result will always be the same.
To allow for that but also an element of unpredictability, it uses a random seed which is a number that determines the point in the random number sequence where new random numbers will come from.
In other words, re-running the application repeated times with the same value for --rng-seed
should always produce the same result. This is useful in case a particularly interesting image is generated; in this case, it's worth re-running the application with a higher --scale
value, to create a larger image (e.g. for printing).
When no seed is passed, one is chosen at random, and both printed during the program's output, and added to the generated file's metadata, in case one wants to recreate the result image.
Bias for distribution in --painter-width
ranges.
Default: 0
Type: Float
The new size of the output image, as a scale of the target image.
This is useful if one wants the result image to be either smaller or larger than the target image.
Larger images tend to take more time to generate. It's useful to try and generate smaller images (or of the same size as the target) when trying out parameters, and once one is happy with the results, regenerate the image using a larger scale and the same random number generator seed used in the original result (via --rng-seed
).
Save the output file more frequently.
The default behavior for the application is to only write the final output file when the target generations, tries, or diff are achieved. With this flag, the output file will be saved frequently, on every successful generation.
This is useful if one expects to be interrupting the writing process in the middle.
Default: none
Type: 3x4 float matrix as a comma-separated array
Color matrix to be applied to the target image before using it.
This allows one to change how colors in the target image are perceived by the system when determining whether a newly painted candidate is close to the target or not. While editing the target image on an image editor (by changing its colors) prior to running Random Art Generator has the same effect, running a color matrix transformation as part of the application can help automate the generation process.
This is a (somewhat) typical 3x4 matrix for color transformations between RGB channels, in the format:
r_from_r, r_from_g, r_from_b, r_offset,
g_from_r, g_from_g, g_from_b, g_offset,
b_from_r, b_from_g, b_from_b, b_offset
For example, the identity matrix (equivalent to no change) is 1,0,0,0,0,1,0,0,0,0,1,0
.
While the command line is a string, it accepts parameters that expect data in several different formats.
Some arguments might expect data in custom formats, but these are the more generic data types:
A bias is a float value that denotes how numbers are randomized from potential range values. This allows the application to generate random values that are biased toward the begin or end of ranges, effectively making either side of the range more frequent when painting.
For example, consider the range 0.0-1.0
. Normally, using that range in any input (for example, --painter-alpha
) would mean the application would randomly select a value between 0.0
and 1.0
with equal probabilities; in other words, using a linear distribution.
This linear distribution is the equivalent of a bias of 0.0
, the default when a range is present.
However, using a bias, one can move the needle in either direction of the range. When using a negative bias (values below 0.0
), the randomization of the range is biased towards the low end of the range, and a positive (higher than 0.0
value) means a bias towards the high end of the range.
Given an input bias
, a range minimum min
, and a maximum max
, the calculation for a random number in a range works like this (in pseudocode):
r = random_in_range(0, 1);
if bias < 0 {
r = power(r, -bias + 1);
} else if bias > 0 {
r = 1 - power(1 - r, bias + 1);
}
return min + r * (max - min)
In practice, this is how what it means, given a 0.0-1.0
range:
- Bias
-2.0
: cubic bias towards0.0
; e.g. 50% chance of a number between0.0
and0.125
, and 50% chance of a number between0.125
and1.0
- Bias
-1.0
: quadratic bias towards0.0
; e.g. 50% chance of a number between0.0
and0.25
, and 50% chance of a number between0.25
and1.0
- Bias
0.0
: linear distribution; e.g. 50% chance of a number between0.0
and0.5
, and 50% chance of a number between0.5
and1.0
- Bias
1.0
: quadratic bias towards1.0
; e.g. 50% chance of a number between0.0
and0.75
, and 50% chance of a number between0.75
and1.0
- Bias
2.0
: cubic bias towards1.0
; e.g. 50% chance of a number between0.0
and0.875
, and 50% chance of a number between0.875
and1.0
Bias parameters have no limit in range; the lower the number, the more biased it is towards the start of the range; the higher the number, the more biased towards the end.
Also, notice that a bias changes the randomized values, not the frequency of values actually used. A bias can cause a certain value in the low or high end to be tried more often, but it doesn't mean that the successfully painted results will follow the same distribution: it's possible that candidates might not produce a better result image. As an example, consider an image being generated with --painter circles
, with a radius bias on the high end (towards 50%): this means it will try painting a circle that takes the whole image area, which is unlikely to be a successful painting that improves the image very often. In this case, smaller circles will more often produce successful results when tried, even if they're tried less frequently (since there's a bias against trying them in the first place).
A color denotes a RGB format either in RRGGBB or RGB hexadecimal formats (with or without a leading #
), a readable color name, or a color function like rgb()
, cmyk()
, or hsl()
(think CSS colors).
These are valid colors:
white
'#ff0'
'#4C4C4C'
'rgb(76, 76, 76)'
'cmyk(0%, 0%, 0%, 70%)'
'hsl(0, 0%, 29.8%)'
Notice that in some cases the terminal might have trouble with parameters starting with the character #
or containing spaces, hence why quotes might be required for the value.
Additionally, to pass hexadecimal color values, the following syntax also works:
ff0
4C4C4C
This value is parsed by the color_processing crate.
Any number with or without a decimal point.
For example:
0
1.0
2
3.141592653
15
A rounded number.
For example:
0
1
-2
19720
A list of values, separated by space, with optional weight per item.
When a list of values is passed, it means "use any of these values". This means that during any new try, the algorithm will pick a value at random from the supplied entries.
Additionally, a list can be weighted: by adding a @
followed by a number, items in the list can control the likelyhood of being picked at random (assume entries have a weight of 1
by default, and the total sum of weights for all entries determines how chances are distributed).
For example:
- A list of floats where each has a 25% chance of being used:
0 1.5 2 10
- A list of floats where the first one is 10 times more likely to be chosen than all other items:
0@10 1.5 2 10
- A list of floats where each has a 25% chance of being used:
0@10 1.5@10 2@10 10@10
- A list of scales where each has a 1/3rd chance of being used:
0.5 10% 20.2%
- A list of scales where each has a 1/3rd chance of being used:
0.5@5 10%@5 20.2%@5
A range between two values, where the beginning and end values are concatenated by an hyphen (-
).
Some argument inputs can take a value but also allow a range to be passed, in which case the value to be used is randomized from the range.
Values of different units can be mixed in the same range, as long as the type is the same.
For example:
0-1
: a float value between0
and1
0.5-100
: a float value between0.5
and100
0.05-50%
: a scale value between0.05
and0.5
, or5%
and50%
(same thing)50
: a float value between50
and50
A special type of number usually representing a value between 0
and 1
. This can be either represented as a real number (0.0
...1.0
) or as a percentage (0%
...100%
). Some arguments might accept numbers outside of this range.
These are valid (and equivalent) examples:
0
or0%
0.1
or10%
0.5265
or52.65%
1.0
or100%
3.0
or300%
-0.5
or-50%
0.001
or0.1%
A number that represents an image size, either in pixels (as a float number) or as a percentage of the total size available (ending with a %
).
Some examples:
10
(10 pixels)5.125
(5.125 pixels)10%
(10% of the available size; for example, 10% of the image width when used in the horizontal axis)
Check the struct source code for more insight into each argument.
To generate HTML documentation, run this against the project source:
cargo doc --bin random-art-generator --no-deps