A detailed description of the possible sort parameters.
To run the script, use the command python pixelsort.py <image> -o <result>
to sort a given image
and store it in <result>
. Use the --log
flag to view progress for sorting particularly large images.
The other settings and options are described below.
For the example figures, the original image used is this:
The -i
or --max-interval
argument specified the length of individual intervals of pixels to sort.
By default, whole rows of the image are sorted at once. However, when -i <INTEGER>
is used,
pixels are sorted in consecutive groups of the given length.
With -i
omitted:
With -i 50
:
With -i 100
:
The -r
or --randomize
argument will cause pixel intervals to have random length between 1 and INTERVAL
pixels,
where INTERVAL
is the amount specified by the -i
flag. If the -i
flag is omitted, then -r
has no effect.
With -i 50
:
With -i 50 -r
:
The --progressive-amount <AMOUNT>
flag takes a floating point amount,
and increases the sorting interval by the given amount each row, as a fraction of the total interval.
For instance, with -i 100
and --progressive-amount 0.01
,
the sorting interval would increase by 1 pixel each row.
Since there are hundreds of rows in an image, values less than 0.001
usually work best.
With -i 100 -r
and no progressive sorting:
With -i 100 -r --progressive-amount 0.0001
:
(It is difficult to see, but the sorting intervals near the top rows are smaller than at the bottom.)
One can apply a custom function to pixels before they are sorted,
allowing one to sort by brightness, saturation, or some other metric.
This is done using the -s <KEY>
or --sortkey <KEY>
flag, where <KEY>
is one of a set of predefined function names.
By default, pixels are sorted simply using their numerical value.
Note that sorting is stable, so if pixels are mapped to the same value,
their relative position will be unchanged.
Default sorting method:
Using -s sum
will sort by the sum of the pixel's (R,G,B) values:
Using -s red|green|blue
will sort using only the given channel of each pixel.
Sorting with -s blue
is shown below.
Other sorting methods include:
chroma
hue
intensity
lightness
luma
random
saturation
value
Using the -R
or --reverse
flag will reverse the sorting order of the pixels:
With -i 50
:
With -i 50 -R
:
The -d
or --discretize <INTEGER>
flag will take pixel values,
divide them by the given amount, and cast to an integer.
This means that pixels with small variations will be binned into the same categories,
and not sorted relative to each other.
This allows one, for instance, to only move the "brightest" pixels while the other pixels stay in place.
With -s sum
and -d
omitted:
With -s sum -d 100
:
With -s sum -d 200
:
By default, all sorting is done in horizontal intervals through the image. However, several other sorting paths are available.
The -v
flag will sort the image vertically instead of horizontally.
Otherwise, one can explicitly specify what type of path to use with the -p
or --path
flag:
concentric
Instead of rows, sorts concentric rectangles around the image.
diagonal
Sorts in diagonal lines that move from the top left to the bottom right.
horizontal
: The default, sorts horizontally row by row
vertical
: Sorts vertically, column by column
Sorting paths are explained in detail in the paths documentation.
Several modifiers can be applied to individual intervals of pixels.
-
mirror
- The mirror modifier takes an interval of pixels, and moves each successive pixel to either the beginning or end of the interval. This makes intervals look symmetric, and borders between intervals are more continuous. This is especially useful for intervals that form loops, such as theconcentric
path. -
splice
- The splice modifier splits an interval of pixels at a certain position, and places the front half after the second half. The split position is given as a number between0
and1
, with0
reprsenting the start of the list and1
representing the end. -
splice-random
- Randomly splices each interval at a different position.
With -s luma -p concentric --splice-random
:
Edge detection allows one to break up sorting intervals are points of high contrast
(i.e. where there are edges in the image). This creates the effect of only sorting within low-contrast regions.
The -e <THRESHOLD>
or --edge-threshold <THRESHOLD>
flag can be used to specify a numerical threshold above
pixels are considered "edges". Intuitively, this means that low thresholds will cause images with very short sorting
intervals, while very high threholds will cause the image to be almost completely sorted, as if -e
had
not been specified at all. However, the exact effects depend on the image specified.
The original image:
Sorting with -e 50
:
Sorting with -e 100
:
Sorting with -e 200
:
Sorting without the -e
flag:
Note that with low -e
values, nearly the whole image is undisturbed,
since almost everything is considered an 'edge',
but with high -e
values everything is sorted except for the starkly-contrasted trees.
Image colors can also be used to determine sorting intervals. When --image-threshold <FLOAT>
is specified, pixels that are too dark or too bright are not sorted,
and delimit sorting intervals. The value given determines the thresholds for pixel brightness.
This value ranges from 0 (meaning all pixels are within the brightness threshold, and everything gets sorted),
to 1 (meaning all pixels are out of the brightness threshold, and nothing is sorted).
The original image:
Sorting with --image-threshold 0
:
Sorting with --image-threshold 0.6
:
Sorting with --image-threshold 1
:
One can also specify a custom image that will be used as a sort mask.
In this case, pixels that with a brightness of more than half will be used to delimit sort intervals,
while darker pixels will be ignored. This can be done with the --image-mask <FILENAME>
flag.
Note that the image mask must have exactly the same size
Sorting without --image-mask
and with -R
:
An image mask that can be applied to an image:
Sorting with --image-mask image-mask.jpg
and -R
:
The parts of the image corresponding to black pixels in the pixel mask are sorted, while the parts corresponding to white pixels are not.
One can also sort individual tiles in the image. With the --use-tiles
flag,
the image will be broken into a grid of recantgular tiles, and each tile will be sorted as if it were a separate image.
By default, tiles are 50 pixels on a size, but this can be changed with the --tile-x <INT>
and --tile-y <INT>
flags
Sorting with --use-tiles
and -p diagonal
Sorting with --use-tiles --tile-x 20 --tile-y 30
and -p diagonal
The --tile-density <FLOAT>
flag will only sort the given fraction of tiles. For instance, with --tile-density 0.5
,
only half of the tiles will be sorted, while the others are unmodified. By default, all tiles are sorted.
Also, if the density is less than 1, tiles are sorted uniformly across the image.
If the --randomize-tiles
flag is specified, then tiles will be randomly sorted,
with the probability given by --tile-density <FLOAT>
.
Sorting with --use-tiles --tile-x 20 --tile-y 20 --tile-density 0.5
and -p diagonal-single
Sorting with --use-tiles --tile-x 20 --tile-y 20 --tile-density 0.5 --randomize-tiles
and -p diagonal-single
It is also possible to sort individual channels of an RGB image, using the --channel {red,green,blue}
flag.
Sorting with --channel red
and -s sum -i 100 -r
This pixelsorting library also includes tools for creating and modifying animated gifs.
To change a certain parameter over time, on can use the --animate "PARAM START STOP N_STEPS"
flag.
For instance, to change the sorting interval from 10 to 100 over 15 frames, one could specify
--animage "max_interval 10 100 15"
.
Note that currently, this is only possible for parameters that have numerical values.
Also, only one parameter can be animated at a time.
Animated sort, with --animate "max_interval 2 30 15"
and -s sum -r
:
To save intermediate frames, use the --save-frames
flag.
One can also input animated gifs, and each frame of the gif will be modified according to the command line arguments.
If --animate "..."
is specified as well, the animated settings will be applied frame-by-frame to the gif.