Animation merger

0. Contents

This is the documentation of animmerger-1.6.0.3.
   1. Purpose
   2. Pixel methods
      2.1. Static methods
         2.1.1. AVERAGE
         2.1.2. ACTIONAVG
         2.1.3. MOSTUSED
         2.1.4. LAST
         2.1.5. FIRST
         2.1.6. SOLID
         2.1.7. FIRSTNMOST
         2.1.8. LASTNMOST
         2.1.9. LEASTUSED
      2.2. Animated methods
         2.2.1. CHANGELOG
            2.2.1.1. Motion blur
         2.2.2. LOOPINGLOG
         2.2.3. LOOPINGAVG
            2.2.3.1. Motion blur
      2.3. Summary
   3. Masking methods
      3.1. BLACK/BLANK/CENSOR
      3.2. HOLE/ALPHA/TRANSPARENT
      3.3. DELOGO/BLUR/INTERPOLATE
      3.4. PATTERN/EXTRAPOLATE
   4. Color quantization methods
      4.1. Median-cut (aka. Heckbert)
      4.2. Diversity
      4.3. Blend-diversity
      4.4. NeuQuant
   5. Dithering
      5.1. Gamma correction
      5.2. Example
         5.2.1. Dither error spread factor
         5.2.2. Dither matrix size
         5.2.3. Dither candidate count
         5.2.4. Dither contrast limiter
   6. Color compare methods
      6.1. RGB
      6.2. CIE76
      6.3. CIE94
      6.4. CIEDE2000
      6.5. CMC l:c
      6.6. BFD l:c
      6.7. Illuminants
   7. Transformation
   8. Caveats
      8.1. Parallax motion
      8.2. Flashes, fog and other transparent layers
   9. Usage
   10. Copying
   11. Requirements
   12. See also
   13. Downloading

1. Purpose

Animmerger stitches 2D images together into either a static image or an animation, while attempting to preserve a global frame of reference (static background).
That is, for a movie that follows an actor around (and the background scrolls to follow them), it creates a movie that has a fixed background, and the camera moves around in the scene.

It does this with a motion detection algorithm, a set of different pixel methods, and a simulated infinite 2D canvas — a 2D canvas that extends infinitely to all four directions (well, as infinite as 32-bit integers can get…)

2. Pixel methods

Original animation As a sample, here is the original animation (712100 bytes).

The animation was created literally by taking a screenshot from the NES emulator every frame.
(I hacked the emulator to automatically produce a screenshot after every frame.)

What follows below, is a list of the pixel methods supported by animmerger,
along with example images demonstrating what that pixel method does.

The -m0,8,256,16,020202,A64010,D09030,006E84,511800,FFFFFF
parameter was given to animmerger to remove the HUD that is 256x16 wide
and begins at 0,8. The hexadecimal numbers listed are these colors:
020202 A64010 D09030 006E84 511800 FFFFFF
This removes the text (white) as well as the blinking coin.


The graphics material comes from Super Mario Bros.
Mario, Super Mario Bros., and The Nintendo Entertainment System (NES) are registered trademarks of Nintendo of America Inc. But you knew that, right?

2.1. Static methods

2.1.1. AVERAGE

The "average" method produces a "motion blur" effect of the entire input, reducing it into a single frame.

Average

You can see a faint trace of all animated actors that appeared in the animation. Mario moved very fast so his trace is quite difficult to spot.

Produced with commandline:
# animmerger -pa snaps/*.png -m0,8,256,16,020202,A64010,D09030,006E84,511800,FFFFFF
# mv tile-0000.png demo/method-a.png

An alternative implementation of "average" is also provided: "tinyaverage" (option -A). It requires less memory to store, but is less accurate to calculate.

If you want the color averages to be calculated through the YUV colorspace rather than the RGB colorspace, add the --yuv option (not supported by tinyaverage).

2.1.2. ACTIONAVG

The "actionavg" method attempts to fix the faintness problem with "average" method by keeping track separately of the background (using the "mostused" method) and adding it only once to the average of moving actors.

Action average

Produced with commandline:
# animmerger -pt snaps/*.png -m0,8,256,16,020202,A64010,D09030,006E84,511800,FFFFFF
# mv tile-0000.png demo/method-t.png

If you want the color averages to be calculated through the YUV colorspace rather than the RGB colorspace, add the --yuv option.

2.1.3. MOSTUSED

The "most used" method produces what might be the background image for the entire animation.

Most used

Note: If there is an actor that sits in a certain location for a long time, it is also recorded.
In this example, there were none though.
This mode does not thus remove all actors, but it does remove anything that wanders around.

Produced with commandline:
# animmerger -pm snaps/*.png -m0,8,256,16,020202,A64010,D09030,006E84,511800,FFFFFF
# mv tile-0000.png demo/method-m.png

2.1.4. LAST

The "last" method is a simpler implementation of the MostUsed method, simply recording the last pixel value in any location.

Last

Produced with commandline:
# animmerger -pl snaps/*.png -m0,8,256,16,020202,A64010,D09030,006E84,511800,FFFFFF
# mv tile-0000.png demo/method-l.png

2.1.5. FIRST

The "first" method is analogous to "last". It shows whatever first appeared in a particular pixel location.

First

The turtles are distorted, because they moved while the screen scrolled.
It is the same effect as if you move the paper in a desktop scanner during the scanning.

Produced with commandline:
# animmerger -pf snaps/*.png -m0,8,256,16,020202,A64010,D09030,006E84,511800,FFFFFF
# mv tile-0000.png demo/method-f.png

2.1.6. SOLID

The "solid" method is an experimental light-weight replacement to the "mostused" method. It simply ignores anything that moves and retains whatever stays still for the longest time.
Unlike "mostused", it does not sum separate appearances together; it only finds the maximum length of consecutive sameness.

Solid

As seen here, it has shortcomings, too.

Produced with commandline:
# animmerger -pO snaps/*.png -m0,8,256,16,020202,A64010,D09030,006E84,511800,FFFFFF
# mv tile-0000.png demo/method-O.png

2.1.7. FIRSTNMOST

The "firstnmost" method is analogous to "first" and "mostused"; it chooses the most common pixel of first N pixel values. Set N with the --firstlast (-f) option.
If N is 0, instead gets last uncommon pixel.
If N is negative, using least common values rather than most common.

Most common of first 4:
Most common of first 4

Most common of first 10:
Most common of first 10

Most common of first 16:
Most common of first 16

First uncommon:
First uncommon

Least common of first 10:
Least common of first 10

Produced with commandline:
# for f in 4 10 -10 16 0; do
#   animmerger -pF -f$f snaps/*.png -m0,8,256,16,020202,A64010,D09030,006E84,511800,FFFFFF
#   mv tile-0000.png demo/method-Ff$f.png
# done

2.1.8. LASTNMOST

The "lastnmost" method is analogous to "last" and "mostused"; it chooses the most common pixel of last N pixel values. Set N with the --firstlast (-f) option.
If N is 0, instead gets last uncommon pixel.
If N is negative, using least common values rather than most common.

Most common of last 10:
Most common of last 10

Last uncommon:
Last uncommon

Least common of last 10:
Least common of last 10

Produced with commandline:
# for f in 4 10 -10 16 0; do
#   animmerger -pL -f$f snaps/*.png -m0,8,256,16,020202,A64010,D09030,006E84,511800,FFFFFF
#   mv tile-0000.png demo/method-Lf$f.png
# done

2.1.9. LEASTUSED

The "least used" method is analogous to "most used".
It can be used to find graphical artifacts and teleporting actors, but for the most part, the output is not very useful.

Least used

Produced with commandline:
# animmerger -pe snaps/*.png -m0,8,256,16,020202,A64010,D09030,006E84,511800,FFFFFF
# mv tile-0000.png demo/method-e.png

2.2. Animated methods

2.2.1. CHANGELOG

The "changelog" method records the entire animation (121995 bytes in this example).
It takes considerably less disk space (and is faster to load) than the original animation, because now the background does not scroll.

Changelog

You see some artifacts in the turtle and in Mario when they appear near the top of the screen. This is because they were behind the HUD (the text "WORLD 8-2" for instance), which was removed.
In the case of the turtle, the turtle's white pixels were also removed, because the HUD removal was based on color as well as coordinates.
Horizontal disappearance of the actors is because of the viewport scrolling past them. They do not exist outside those parameters in the original animation either.

Here is how the animation looks like, if the HUD is not removed. (246643 bytes)

Changelog, with HUD intact

Exteriors, i.e. content outside the "current" viewport of the animation are colored as in the MostUsed pixel method.
This is evident in the trails left by the HUD as it scrolls by at different speeds.

Produced with commandline:
# rm tile-*.png tile-*.gif
# animmerger --gif -pc snaps/*.png -m0,8,256,16,020202,A64010,D09030,006E84,511800,FFFFFF
# gifsicle -O2 -o demo/method-c.gif -l0 -d3 tile-*.gif

The version with HUD intact was created with the same commandline, except with the -m option removed.

The background for ChangeLog is normally generated with the MostUsed method, but it can be explicitly controlled with the --bgmethod0 and --bgmethod1 options.
Here is how the above animation (HUD-less) looks like with --bgmethod0 first --bgmethod1 last:

Changelog with first&last
Note that the --bgmethod0 and --bgmethod1 options only affect the ChangeLog method, and only when motion blur is not used.

2.2.1.1. Motion blur
The changelog method also supports motion blur. Use the --motionblur (-B) option to set it. Value 0 disables motion blur (default: 0).

Blur length 1:
Changelog, blur 1

Blur length 4:
Changelog, blur 4

Blur length 20:
Changelog, blur 1

Produced with commandline:
# for b in 1 4 20;do
#   rm tile-*.png tile-*.gif
#   animmerger --gif -B$b -pc snaps/*.png -m0,8,256,16,020202,A64010,D09030,006E84,511800,FFFFFF
#   gifsicle -O2 -o demo/method-cB"$b".gif -l0 -d3 tile-*.gif
# done

2.2.2. LOOPINGLOG

The "loopinglog" method records the entire animation, but reuses existing frames. Use the -l option to set the loop length in frames.
The smaller value you use, the shorter the animation is in the number of frames, but the more pronounced is the "lemmings" effect.

30 frames (94895 bytes):
Loop, 30 frames

10 frames (66738 bytes):
Loop, 10 frames

4 frames (40372 bytes):
Loop, 4 frames

Produced with commandline:
# for l in 4 10 30; do
#   rm tile-*.png tile-*.gif
#   animmerger --gif -l$l -po snaps/*.png -m0,8,256,16,020202,A64010,D09030,006E84,511800,FFFFFF
#   gifsicle -O2 -o demo/method-sl"$l".gif -l0 -d3 tile-*.gif
# done

It is also called "loopinglast" mode (option -s) to differentiate from "loopingavg".

The loopinglog method also supports motion blur. Use the --motionblur (-B) option to set it. Value 0 disables motion blur (default: 0).

2.2.3. LOOPINGAVG

The "loopingavg" method combines the "loopinglog" and "actionavg" methods. Use the -l option to set the loop length in frames.
The most important difference to "loopinglog" is that overlapping action is averaged rather than explicitly choosing one of the acting pixels.
It looks slightly better, but may require GIF palette reduction.
In comparison, "loopinglog" only uses pixel colors present in the original images.

30 frames (file size depends on selected palette size):
Loop, 30 frames

10 frames:
Loop, 10 frames

4 frames:
Loop, 4 frames

Produced with commandline:
# for l in 4 10 30 80; do
#   rm tile-*.png tile-*.gif
#   animmerger --gif -l$l -pv snaps/*.png -m0,8,256,16,020202,A64010,D09030,006E84,511800,FFFFFF
#   gifsicle -O2 -k128 -o demo/method-ov"$l".gif -l0 -d3 tile-*.gif
# done

If you want the color averages to be calculated through the YUV colorspace rather than the RGB colorspace, add the --yuv option.
In most cases, the difference is neglible though.

2.2.3.1. Motion blur
The loopingavg method also supports motion blur. Use the --motionblur (-B) option to set it. Value 0 disables motion blur (default: 0).

Loop length 30 frames, blur length 20:
Loop-Avg 30, blur 8

Loop length 30 frames, blur length 20, with YUV calculations:
Loop-Avg 30 through YUV, blur 8

Loop length 30 frames, blur length 20, with YUV calculations, and diversity-quantized palette of 16 colors:
Loop-Avg 30 through YUV, blur 8, 16 colors

Loop length 10 frames, blur length 4:
Loop-Avg 10, blur 4

Produced with commandline:
# for b in 4 8 20;do
#   for l in 10 30;do
#     rm tile-*.png tile-*.gif
#     animmerger --gif -B$b -l$l -pl snaps/*.png -m0,8,256,16,020202,A64010,D09030,006E84,511800,FFFFFF
#     gifsicle -O2 -o demo/method-vl"$l"B"$b".gif -l0 -d3 tile-*.gif
#   done
# done

2.3. Summary

Method name Static or
animated
Composes
new colors
Obeys YUV
option
Memory size per pixel* Primary
use
First Static No No 4 Maps
Last Static No No 4
FirstNMost Static No No As ChangeLog
· FirstUncommon Static No No As ChangeLog
· FirstNLeast Static No No As ChangeLog
LastNMost Static No No As ChangeLog
· LastUncommon Static No No As ChangeLog
· LastNLeast Static No No As ChangeLog
MostUsed Static No No 12…16 + 6×number of unique colors Maps
LeastUsed Static No No As MostUsed
Solid Static No No 12 Maps
Average Static Yes Yes 16
Tinyaverage Static Yes No 8
ActionAvg Static Yes Yes As MostUsed
ChangeLog Animated (movie) If blurFor blur 12…16 + 8×number of content changes Animations
LoopingLog Animated (loop) If blurFor blur As ChangeLog
LoopingAvg Animated (loop) Yes Yes As ChangeLog Fun

*) These numbers are estimates. Actual memory size per pixel depends on the exact selection of pixel methods requested and the memory allocation overhead. Animmerger strives to always select the smallest combination of pixel methods (memoryconsumptionwise) that can implement all the requested methods.

3. Masking methods

Masked areas can be removed with a number of different methods. To best demonstrate them, I added an extra huge mask in the middle of the image.
It is best seen in the "black" masking, below.

These images were produced with this commandline:
# for method in censor hole interpolate extrapolate; do
#   rm *-*.gif *-*.png
#   ./animmerger -r4,4 --mvrange 0,0,4,0 --bgmethod0=first --bgmethod1=last \
#   -u$method -p* snaps/*.png \
#   -m0,8,256,16,020202,A64010,D09030,006E84,511800,FFFFFF \
#   -m3,128,250,72 -m0,73,256,2
#   gifsicle -O2 -o demo/mask-$method.gif -l0 -d3 ChangeLog-*.gif
#   cp -p Average-0000.png demo/mask-$method.png
# done

3.1. BLACK/BLANK/CENSOR

This method shows clearly which areas were affected by the mask. Specifically, the HUD, and a huge rectangle, and a narrower line extending from the very left edge to the very right edge of the screen at all times, effectively blocking the contents of the entire scanline from ever being seen.

Animation:
Masked with CENSOR, animation
Averaged:
Masked with CENSOR, average

3.2. HOLE/ALPHA/TRANSPARENT

This method is what animmerger does by default. The transparent regions are simply treated as holes; there is no content on the affected areas. If the hidden content becomes available when the camera moves, then those pixels are recorded.

Animation:
Masked with HOLE, animation
Averaged:
Masked with HOLE, average

3.3. DELOGO/BLUR/INTERPOLATE

This method removes the content with a circular blur pattern. The method is almost identical to the delogo filter that can be used in MPlayer to remove a tv station logo from video. Content that coindices with the removed part is replaced with interpolated surrounding pixels; original pixels of the affected area are not sampled.

Animation (palette-reduced and dithered with -Qd,16 in order to make the 1.5 MB GIF file smaller):
Masked with DELOGO, animation
Averaged:
Masked with DELOGO, average

3.4. PATTERN/EXTRAPOLATE

The extrapolate filter tries to extrapolate the content of the masked areas by detecting repeating tile patterns outside the masked area, and extrapolating those patterns over the masked area. The results of this method vary a lot from frame to frame, so it is not very suitable to be used over large unknown areas. For small areas, it works nicely.

Note that this algorithm is rather slow on large areas like this.

Animation:
Masked with PATTERN, animation
Averaged:
Masked with PATTERN, average

4. Color quantization methods

Animmerger can create its output files in GIF or PNG format, regardless of whether you are creating an animation or not.
GIF files however are limited to a palette of 256 colors, while it is possible that animmerger creates images with more colors than 256. Therefore, the colormap must be reduced before the GIF image can be generated. animmerger supports a number of different color reduction methods, which are listed below.
If no method is chosen, whatever is libGD default will be used.

The images in this section were generated by making a 30-frame LoopingAvg animation with blur length of 20, rendering it with different palettization parameters and picking the 11th frame.

The exact commandline to produce the images was:
# for m in m d b o q; do
#  for q in 2 4 8 16 32 64 128; do
#   rm tile-*.png tile-*.gif
#   dither="-Dy2 --dr 2 --dc 16"
#   if [ $q -gt 16 ]; then dither="-Dy1i --dr 1.2 --dc 16"; fi
#   animmerger --gamma 2.2 $dither \
#           --gif -Q"$m",$q -B20 -l30 -pv snaps/*.png \
#           -m0,8,256,16,020202,A64010,D09030,006E84,511800,FFFFFF
#   gifsicle -O2 -k128 -o demo/method-vl30yB20Q"$m"$q.gif -l0 -d3 tile-*.gif
#   convert tile-0010.gif -quality 100 demo/quant-"$m"$q.png
#  done
# done

Palette reduction methods can be chained in order to take benefits of the differently-appearing strengths of the different methods, but in this test set, each method was used alone.

When palette reduction methods have been explicitly selected, animmerger always uses an ordered-dithering method (crosshatch artifacts) to optimize the rendering. This is better for animation than other methods such as Floyd-Steinberg are, because the dithering patterns do not jitter between frames.

4.1. Median-cut (aka. Heckbert)

Heckbert median-cut quantization method repeatedly splits the palette into two roughly equal-proportion sections ("low" and "high" part in any of red/green/blue channels) until the desired number of sections have been generated; the palette is generated by averaging the values in each section together.
It is good at generating relevant palettes, but at smallest palette sizes, it suffers from a blurring problem.

4 colors:
Heckbert quantization, 4 colors
8 colors:
Heckbert quantization, 8 colors
16 colors:
Heckbert quantization, 8 colors
32 colors:
Heckbert quantization, 32 colors

4.2. Diversity

Diversity quantization method alternates between choosing the most popular remaining color in the image for a "seed" and choosing of the remaining colors the one that is most distant to any colors selected so far.
The result is generally a very good representation of the original image's colors.
At the smallest palette sizes, the colors are of course off, but the contrast is still sharp.

4 colors:
Diversity quantization, 4 colors
8 colors:
Diversity quantization, 8 colors
16 colors:
Diversity quantization, 16 colors
32 colors:
Diversity quantization, 32 colors

4.3. Blend-diversity

The blend-diversity method is a variation to the diversity method; after the colors have been chosen, they are merged together with the remaining colors that are most similar to the chosen one.

4 colors:
Blend-diversity quantization, 4 colors
8 colors:
Blend-diversity quantization, 8 colors
16 colors:
Blend-diversity quantization, 16 colors
32 colors:
Blend-diversity quantization, 32 colors

4.4. NeuQuant

The NeuQuant method, developed by Anthony Dekker in 1994, uses a Kohonen self-balancing neural network to quickly come up with an optimized palette. It is especially powerful with optimizing smooth gradients, such as the motion-blur trails in this pictureset.

4 colors:
NeuQuant quantization, 4 colors
8 colors:
NeuQuant quantization, 8 colors
16 colors:
NeuQuant quantization, 16 colors
32 colors:
NeuQuant quantization, 32 colors

5. Dithering

Dithering is a technique by which the human eye can be tricked into perceiving more colors than there actually is, by putting different-colored pixels adjacent next to each others in varying proportions.

Animmerger knows a number of different dithering algorithms, including a set of dithering algorithms devised by Joel Yliluoma. These algorithms are categorised as an ordered, positional, patterned dithering method that is very well suited for animations, and often even more eye-pleasing than the random noise patterns generated by error diffusion dithers.

Animmerger's dithering can be controlled with the following parameters:

--ditherror, --de <float>
Color error spectrum factor is a parameter that controls how strongly the ditherer will attempt to find the next color value to mix with the previous ones. A value of 0 will effectively disable dithering, and a value of 1 is the algorithm working at full power. Values in the between have effect that depends on the particular palette.
--dithmatrix, --dm <x>,<y>[,<time>]
Bayer matrix dimensions define very straightforwardly the visual appearance of the dithering. A small matrix appears very regular and a larger matrix looks more random. The matrix dimensions should generally be powers of two in both directions, though this is not required.
An additional third dimension can be specified: This dimension is time. If dithering along the time axis (temporal dithering) is requested, then flickering will be used to achieve the desired average colortone over time rather than over spatial distance. The value is the number of frames over which to extend the dithering. A negative value can be given; in this case, the dithering will be performed from the higher-order bits (most prominent) rather than the lowest-order bits (least prominent).
--dithcount, --dc <int>
Sets the maximum number of palette colors to mix when attempting to reproduce a color. Value should be at least 1 (1 disables dithering) and at most the size of the dithering matrix.
--dithcombine, --dr <float>[,<combinationlimit>[,<changeslimit>]]]
The contrast parameter is used to control how palette colors are pre-mixed as candidates for the in-render color chooser to use. A larger value will produce more pre-mixed candidates (with a coarser appearance), a smaller value will inhibit these candidates.

5.1. Gamma correction

Generated with:
# for gamma in 0.1 0.2 0.5 1.0 1.5 2.0 2.2 2.5 3.0 10.0; do
#   animmerger gamma_in.png -Q../cga0-pal.gif --dm 8x8 --dc 64 --gamma $gamma
#   mv tile-0000.png demo/gamma-$gamma.png
# done

With normal-intensity CGA palette:
(Palette entries: #000, #0A0, #A00, #A50)
Gamma test
Gamma 0.1 --gamma=0.1
Gamma test
Gamma 0.2 --gamma=0.2
Gamma test
Gamma 0.5 --gamma=0.5
Gamma test
Gamma 1.0 --gamma=1.0
Gamma test
Gamma 1.5 --gamma=1.5
Gamma test
Gamma 2.0 --gamma=2.0
Gamma test
Gamma 2.2 --gamma=2.2
Gamma test
Gamma 2.5 --gamma=2.5
Gamma test
Gamma 3.0 --gamma=3.0
Gamma test
Gamma 10.0 --gamma=10.0
With EGA palette:
(Relevant palette entries: #000, #555, #AAA, #FFF)
Gamma test
Gamma 0.1 --gamma=0.1
Gamma test
Gamma 0.2 --gamma=0.2
Gamma test
Gamma 0.5 --gamma=0.5
Gamma test
Gamma 1.0 --gamma=1.0
Gamma test
Gamma 1.5 --gamma=1.5
Gamma test
Gamma 2.0 --gamma=2.0
Gamma test
Gamma 2.2 --gamma=2.2
Gamma test
Gamma 2.5 --gamma=2.5
Gamma test
Gamma 3.0 --gamma=3.0
Gamma test
Gamma 10.0 --gamma=10.0

Note that animmerger's gamma correction algorithm is somewhat disputable. For instance, although the former example looks good, if we try the same with the EGA palette, where mid-gradient values (0%, 33%, 66% and 100% white) actually exist in the palette, we get the latter, odd-looking result.

Conclusion: Your mileage may vary.

5.2. Example

To demonstrate dithering, let us consider this example picture. It has been assigned a customized palette to go with it.

Base picture for dithering Palette to go with the dithering demo

It is a subset (cropped portion) of a larger picture seen on the page where the algorithm is explained in detail, hence the odd inclusion of blue in it.

5.2.1. Dither error spread factor

Adjusting --ditherror option. Adjusting --ditherror option.
Adjusting --ditherror option. Adjusting --ditherror option.

The error spread factor provides a very fine-grained control over the final appearance of the dithered image. Though the upper limit of the value is 1.0, higher values can be used for artistic purposes.

5.2.2. Dither matrix size

Adjusting --dithmatrix option.
Adjusting --dithmatrix option.

The matrix shape directly controls the manner in which the different-color spots are dispersed. The temporal dithering option can be used for improving the perceived quality of colors (at the cost of flickering), and for artistics effects.

Unless the --dithcount (--dc) option was given manually, setting the matrix size also sets the former. (To the size of matrix, or 32, whichever is smaller.)

Note that when making GIF animations, you usually do not want flickering, because it will inflate the file sizes at a very high rate. With H.264, it is perfectly fine, especially if you use the frameref setting. (No, Animmerger does not have H.264 output. I was just referring to the hypothetical scenario that you would use animmerger to create a video that will be encoded in H.264.)

5.2.3. Dither candidate count

Adjusting --dithcount option.
Adjusting --dithcount option.

The candidate count option directly controls how colors are mixed together in the dithering process. A higher value always results in higher quality, however, there is no sense in making the value larger than the matrix size is. Also, a combination of a large matrix and a small count can be used to simulate a small dithering matrix.

Also note that the rendering speed is directly proportional to the number of dither color candidates generated. (It also depends on the size of the palette of both input and output images, and on the dither contrast limiter.)

5.2.4. Dither contrast limiter

Adjusting --dithcontrast option.
Adjusting --dithcontrast option.

Specifying 0 for the contrast usually works nicely, especially if the palette is good, but sometimes you will have to put a higher value there. Such situations may happen if the palette contains a combination of colors that produces the exact color required in the input picture when mixed, but also a closeby color that is not exact. Without the aid of the contrast option, the ditherer will not find the combination and will just use the closerby color that might not look as good. Overdoing it, however, will result in a lot of overly sharp local contrast, which looks mostly bad. Animation is shown in the last frame for the sake of demonstration, because it improves the spatial color resolution.

Note that using nonzero --dr with --gamma that differs from 1.0 is currently broken. Please avoid that combination.

6. Color compare methods

In dithering, a color compare algorithm is used. The same algorithm is also used in the diversity and blend-diversity quantization options. Animmerger supports a few different algorithms for comparing colors.

Here are two example truecolor* pictures, and the web-safe palette.
Color scales at various luminosity and saturation. A faux testcard for God's Learning Channel Palette to go with the color compare demo.

I quantized it using the websafe palette and dithered using --dm 1x1 --dc 1 --dr 0 (i.e. no dithering), and varied the color compare method using the --deltae option.

These tests intend to show how each color-compare method identifies colors that most closely match the original. Note: I used gamma correction for these images. Consequently, I disabled the --dr option because these do not mix well together.

Produced with commandline:
# for e in rgb cie76 cie94 cmc ciede2000 bfd; do
#   # Render the chroma&luma test image without dithering:
#   animmerger deltae_base.png -Qdeltae_pal.png -vv \
                  --dm=1x1 --dc=1 --dr=0 --deltae=$e --gamma 2.0
#   mv tile-0000.png demo/deltae_$e.png
#
#   # Create four-frame temporal-dithered animation of the testcard:
#   animmerger tksmall{,,,}.png --noalign -Qdeltae_pal.png -vv \
                  --dm 1x1,-4 --dc 4 --deltae=$e -pc --gif --gamma 2.0
#   gifsicle -O2 -o demo/tk-$e.gif -l0 -d4 tile-000[0-3].gif
#
#   # Create an average of those four frames:
#   animmerger tile-000[0-3].gif -pa --noalign
#   mv tile-0000.png tk-a4-$e.png
# done

*) It is truecolor, but it is also dithered. I found 24-bit RGB inadequate for this picture in preventing hard edges in smooth gradients, so I dithered it for this webpage. The input to these tests was undithered.

6.1. RGB

Three pictures are shown: The two testcases rendered with this color filter, and the third is a four-frame average of the preceding picture, showing exactly which average color perception the dithering was getting at.

Colors compared in RGB Colors compared in RGB 4-frame average
RGB. Calculated as a simple euclidean difference: √(ΔR² + ΔG² + ΔB²)

It is very fast and does not usually cause any nasty surprises. However, in dithering, it usually is overly conservative and fails to account for psychovisuals, i.e. when some color is "close enough", and consequently, fails to achieve a pleasing result.

6.2. CIE76

Colors compared in CIE76 Colors compared in CIE76 4-frame average
CIE L*a*b*, where delta-E calculated as a simple euclidean difference: √(ΔL² + Δa² + Δb²)

It is fast and very often an improvement to RGB.

6.3. CIE94

Colors compared in CIE94 Colors compared in CIE94 4-frame average
CIE L*a*b* with Cab=√(a²+b²),
where delta-E calculated using a much more refined formula (CIE94):
√(ΔL² + ΔCab²÷SC² + ΔH÷Sh²)
with ΔH = (Δa² + Δb² − ΔCab²),
and SC = (1 + 0.048×√(C1ab×C2ab)),
and Sh = (1 + 0.014×√(C1ab×C2ab)).

Note: Animmerger uses the deltaE squared rather than the deltaE itself, which is why the formula may seem different to what it is in reference material. (There may still be genuine errors though.)

6.4. CIEDE2000

Colors compared in CIEDE2000 Colors compared in CIEDE2000 4-frame average
CIE L*a*b* based extremely complicated formula called CIEDE2000.

6.5. CMC l:c

Colors compared in CMC Colors compared in CMC 4-frame average

CIE L*a*b* based quite complicated formula called CMC l:c, with l=1.5 and c=1.0.

Interestingly, this operator seemed to have a huge issue with black colors; animmerger has a special workaround for that problem, though the darker green region looks weird too. In general, this has the appearance of being the weakest of all of these operators. Use it only if you are looking for a specific type of special effect.

6.6. BFD l:c

Colors compared in BFD Colors compared in BFD 4-frame average
CIE L*a*b* based extremely complicated formula called BFD l:c, with l=1.5 and c=1.0.

6.7. Illuminants

RGB to LAB conversions are subject to a lot of perception based science. A concept of "illuminant matrix" plays a significant role here.

Animmerger knows three illuminant matrices:
CIE E illuminant:
0.488718, 0.176204,  0.000000
0.310680, 0.812985,  0.0102048
0.200602, 0.0108109, 0.989795
Adobe D65 illuminant:
0.576700, 0.297361,  0.0270328
0.185556, 0.627355,  0.0706879
0.188212, 0.0752847, 0.99124
Unidentified D65-based illuminant, found in Imagemagick:
0.412453, 0.357580, 0.180423
0.212671, 0.715160, 0.072169
0.019334, 0.119193, 0.950227

Animmerger uses illuminant #3 for CIE76, and illuminant #1 for all other CIE based compare methods, because illuminants #2 and #3 have serious issues with blue and purple tones when any other compare method than CIE76 is used (specifically, they suggest that black is the overwhelmingly best substitute for those colors).

Animmerger converts a RGB value into CIE L*a*b* and CIE L*C*h* using the following formula:
X = (i0 × R + i3 × G + i6 × B) ÷ 255 ÷ (i0+i1+i2)
Y = (i1 × G + i4 × G + i7 × B) ÷ 255 ÷ (i3+i4+i5)
Z = (i2 × B + i5 × G + i8 × B) ÷ 255 ÷ (i6+i7+i8)
f(v) = v ≤ 6329−3 ? 4÷29 + v × 2926−23−1 : v1÷3
L = 4×29 × f(Y) - 42
a = 500 × (f(X) - f(Y))
b = 200 × (f(Y) - f(Z))
C = √(a² + b²)
h = atan2(b, a)

Where i0…i8 are the values from the illuminant matrix.

7. Transformation

Mathematical transformations can be applied to individual pixels of the resulting image, using the --transform option.

In this example, the overall color tone of the image was changed and a lens flare effect was added:
Transformed with a flare effect

Produced with:
# ./animmerger --gif snaps/*.png -m0,8,256,16,020202,A64010,D09030,006E84,511800,FFFFFF \
#         -pv -l25 --deltae=2000 -Qq,36 -Qd,32 --dr 0 --dm 8x8 --dc 32 -Dky -vv \
#         --transform "luma:=r*.299+g*.587+b*.114; px:=238;py:=135;" \
#         --transform "xy:=(abs(x-px)*abs(y-py)/200^2);" \
#         --transform "rad:=hypot(x-px,y-py)^1.3/(1.8+0.02*cos(((frameno/25+.5)%1)^2*-2*pi));" \
#         --transform "v:=luma+(300-min(300,rad))+(200-min(300,(xy+1e-6)^0.6*7e3));" \
#         --transform r="r*v/(255*0.299*2.2)" \
#         --transform g="g*pow(v,1.2)/(255*0.587*3.1)" \
#         --transform b="b*v/(255*0.114*1.7)+50*(1.35+cos(1+(y+x*.2)*pi/100))"
# gifsicle -O2 -o demo/trans.gif -d3 -l0 tile-????.gif

8. Caveats

8.1. Parallax motion

Parallax motion is bad. When animating video game content, please ensure that all background layers are synchronized. Note that this will likely require you to hack the emulator that is used to produce the video frames.

If different background layers are moving at different speeds with respect to the camera, animmerger will sync into one of them (probably the one that occupies the largest screen area), and the rest will appear to be moving with respect to the chosen background.

Example:
This scene is from Super Mario World. The HUD layer is disabled, but otherwise it is an intact animation. The palette was reduced and fps halved to make the file slightly smaller for web distribution.
Super Mario World with parallax motion Super Mario World with parallax fix
You can easily see the problem with parallax motion: Sometimes the image alignment syncs to the platforms, sometimes it syncs to the stalactite background. When it syncs to the platforms, the other background can be seeing moving as a distinct layer. In this version, the background layers move in unison with respect to the camera. As such, the image alignment is perfect.
This was achieved with the following patch to snes9x:
--- ppu.cpp~    2010-08-17 23:46:11.022843689 +0300
+++ ppu.cpp     2010-08-17 22:34:52.000000000 +0300
@@ -416,2 +416,3 @@
                        PPU.BG[0].HOffset = (Byte<<8) | PPU.BGnxOFSbyte;
+                       PPU.BG[1].HOffset = (Byte<<8) | PPU.BGnxOFSbyte;
                        PPU.BGnxOFSbyte = Byte;
@@ -423,2 +424,3 @@
                        PPU.BG[0].VOffset = (Byte<<8) | PPU.BGnxOFSbyte;
+                       PPU.BG[1].VOffset = (Byte<<8) | PPU.BGnxOFSbyte;
                        PPU.BGnxOFSbyte = Byte;
@@ -429,3 +431,3 @@
                  case 0x210F:
-                       PPU.BG[1].HOffset = (Byte<<8) | PPU.BGnxOFSbyte;
+                       //PPU.BG[1].HOffset = (Byte<<8) | PPU.BGnxOFSbyte;
                        PPU.BGnxOFSbyte = Byte;
@@ -436,3 +438,3 @@
                  case 0x2110:
-                       PPU.BG[1].VOffset = (Byte<<8) | PPU.BGnxOFSbyte;
+                       //PPU.BG[1].VOffset = (Byte<<8) | PPU.BGnxOFSbyte;
                        PPU.BGnxOFSbyte = Byte;
The commands used to produce these animations were:
# rm tile-*.gif; animmerger -v -r12x12 -bl -pc -a -4,-3,6,9 pano5/*.png
# rm tile-???[13579].gif # Delete 50% of frames to reduce fps in half
# gifsicle -O2 -o demo/pano5-cl.gif --crop 8,8+480x400 --use-colormap smwpalette.gif -l0 -d6 tile-????.gif
# rm tile-*.gif; animmerger -v -r12x12 -bl -pc -a -4,-3,6,9 pano5b/*.png
# rm tile-???[13579].gif # Delete 50% of frames to reduce fps in half
# gifsicle -O2 -o demo/pano5-fl.gif --crop 8,8+480x400 --use-colormap smwpalette.gif -l0 -d6 tile-????.gif

The palette file was customized by hand, by taking a representative snapshot of the movie, and then progressively merging near-identical entries in the colormap in GIMP manually until only the minimal set of unique colors/tones remain.

8.2. Flashes, fog and other transparent layers

The image aligning engine is confused by anything that globally changes the screen brightness. This includes any pain-red-tinting, white-explosion flashes, fog clouds, etc. Please try to avoid them.

Example:
TODO: Add successful Super Metroid animation

TODO: Add example of how image alignment suffers when using the power bomb in Super Metroid

9. Usage

animmerger v1.5.0 - Copyright (C) 2010 Joel Yliluoma (http://iki.fi/bisqwit/)

Usage: animmerger [<options>] <imagefile> [<...>]

Merges animation frames together with motion shifting.

General options:
 --help, -h
     This help
 --version, -V
     Displays version information
 --verbose, -v
     Increase verbosity

Canvas affecting options:
 --mask, -m <defs>
     Define a mask, see instructions below
 --maskmethod, -u <value>
     Specify how the masked content will be hidden, see instructions below
 --method, -p <mode>
     Select pixel type, see below
 --bgmethod, -b <mode>
     Select pixel type for alignment tests
 --bgmethod0 <mode>
     Explicit pixel mode for ChangeLog background before camera comes
 --bgmethod1 <mode>
     Explicit pixel mode for ChangeLog background after camera leaves
 --looplength, -l <int>
     Set loop length for the LOOPINGxx modes
 --motionblur, -B <int>
     Set motion blur length for animated modes
 --firstlast, -f <int>
     Set threshold for xxNMOST modes
 --yuv, -y
     Specifies that average-colors are to be calculated in the YUV
     colorspace rather than the default RGB colorspace.

Image aligning options:
 --bgmethod, -b <mode>
     Select pixel type for alignment tests
 --refscale, -r <x>,<y>
     Change the grid size that controls
     how many samples are taken from the background image
     for comparing with the input image, for image alignment.
     Smaller grid = more accurate but slower aligning.
     Default: -r32,32
     Set to e.g. -r8,8 if you experience misalignment problems.
 --mvrange, -a <xmin>,<ymin>,<xmax>,<ymax>
     Change the limits of motion vectors.
     Default: -9999,-9999,9999,9999
     Example: --mvrange -4,0,4,0 specifies that the screen may
     only scroll horizontally and by 4 pixels at most per frame.
 --noalign
     Disable automatic image aligner

Output options:
 --gif, -g [=always|=never|=auto]
     Control how GIF files are saved. Always/never/auto.
     In automatic mode (default), GIF is selected for animations
     if quantization was configured, PNG otherwise.
     Default: auto. --gif without parameter defaults to always.
     See below on details on when and how GIF files are written
     depending on this option.
 --quantize <method>,<num_colors>
     Reduce palette, see instructions below
 --quantize <file>
     Load palette from the given file (PNG or GIF, must be paletted)
 --dithmethod, -D <method>[,<method>]
     Select dithering method (see below)
 --ditherror, --de <float>
     Set error multiplication value for the dithering algorithm.
     0.0 = disable dithering. 1.0 = full dithering.
     Usable values lie somewhere in between. Default: 1.0
 --dithmatrix, --dm <x>,<y>[<,time>]
     Set the Bayer matrix size to be used in dithering.
     Common values include 2x2, 4x4 and 8x8. Default: 8x8x1.
 --dithcount, --dc <int>
     Set maximum number of palette colors to use in dithering
     of an uniform color area of the source picture.
     Value 1 disables dithering.
     This number should not be made larger than x*y*time.
     Default: 32 or x*y*time, whichever is smaller.
 --dithcombine, --dr <float>[,<combinationlimit>[,<changeslimit>]]]
     Set the maximum contrast between two or more color items
     that are pre-selected for combined candidates for dithering.
     The value must be in range 0..3. Default value: 1.
     See details below.
 --deltae, --cie [=<type>|=<formula>]
     Select color comparison method, see details below.
 --gamma [=<value>]
     Select gamma to use in dithering. Default: 1.0
 --transform { r= | g= | b= }<function>
     Transform red, green and blue color channel values according
     to the given mathematical function. See details below.

animmerger will always output files into the current
working directory, with the filename pattern tile-####.png
where #### is a sequential number beginning from 0000.
The file name can be also .gif (see details below).
If multiple output methods are specified, then the filename is
method-####.png, such as Average-0000.png or ChangeLog-0155.gif.

AVAILABLE PIXEL TYPES

  AVERAGE, long option: --method=average , short option: -pa
     Produces a single image. Each pixel
     is the average of all frames addressing that pixel.
  TINYAVERAGE, long option: --method=tinyaverage , short option: -pA
     A less accurate but more space-efficient version of "average".
  LAST, long option: --method=last , short option: -pl
     Produces a single image. Each pixel
     records the latest color addressing that pixel.
  FIRST, long option: --method=first , short option: -pf
     Produces a single image. Each pixel
     records whatever first appeared in that spot.
  SOLID, long option:: --method=solid , short option: -pO
     Produces a single image. Changing pixels are
     made transparent until something unchanging appears.
  MOSTUSED, long option: --method=mostused, short option: -pm
     Produces a single image. Each pixel
     records the color that most often occured in that location.
     Use this option for making maps!
  LEASTUSED, long option: --method=leastused, short option: -pe
     Produces a single image. Each pixel
     records the color that least commonly occured in that location.
  LASTNMOST, long option: --method=lastnmost, short option: -pL
     Combines "mostused" and "last". Set threshold using
     the -f option. Example: -f16 -pL = most used of last 16 pixels.
     If -f0, then selects the last not-common pixel value.
     If -f value is negative, uses leastused instead of mostused.
  FIRSTNMOST, long option: --method=firstnmost, short option: -pF
     Combines "mostused" and "first". Set threshold using
     the -f option. Example: -f16 -pF = most used of first 16 pixels.
     If -f0, then selects the first not-common pixel value.
     If -f value is negative, uses leastused instead of mostused.
  ACTIONAVG, long option: --method=actionavg, short option: -pt
     Similar to average, except that blurring of actors
     over the background is avoided.
  CHANGELOG, long option: --method=changelog, short option: -pc
     Produces an animation. Also supports motion blur.
  LOOPINGLOG, long option: --methods=loopinglog, short option: -po
     Produces a time-restricted animation.
     Also called, "lemmings mode".
     Use the -l option to set loop length in frames. Supports motion blur.
  LOOPINGAVG, long option: --methods=loopingavg, short option: -pv
     A combination of loopinglog and actionavg, also supports motion blur.

DEFINING MASKS

  You can use masks to block out HUD / splitscreens
  so that it will not intervene with the animation.
  To define mask, use the --mask option, or -m for short.
  Mask syntax: x1,y1,width,height,colors

  Examples:

    -m0,0,256,32
       Mask out a 256x32 wide section at the top of screen

    -m0,0,256,32,FFFFFF
       From the 256x32 wide section at the top of screen,
       mask out those pixels whose color is white (#FFFFFF)

    -m16,16,8,40,000000,483D8B
       From the 8x40 wide section at coordinates 16x16,
       mask out those pixels whose color is either
       black (#000000) or dark slate blue (#483D8B)

  The masking method option --maskmethod, or -u for short,
  can be used to control how masks are handled.

     --maskmethod=hole or -uhole (default)
         Make the masked areas entirely transparent. It will be as
         if there was a hole in the image where the masked part was.
         Alias: hole, alpha, transparent

     --maskmethod=delogo or -ublur
         Hide masked areas by blurring them with circular interpolation.
         Alias: delogo, blur, interpolate

     --maskmethod=pattern or -upattern
         Hide masked areas by extrapolating a surrounding
         pattern over the masked areas.
         Alias: pattern, extrapolate

     --maskmethod=blank or -ublack
         Replace the masked areas with black pixels, "censoring" them.
         Alias: blank, black, censor

REDUCING PALETTE

  GIF files are restricted to 256 colors, but regardless of whether
  you use GIF or PNG for the output format, you can use the --quantize
  option to reduce your images to a particular number of colors.
  The following quantization methods are defined:

    Median cut ( example: --quantize=mediancut,32  or -Qm,32 )
      Heckbert quantization. Progressively bisects the colorspace
      into roughly equal sizes per population until the number of
      sections matches the required size. Then chooses the weighted
      average of each section.

    Diversity ( example: --quantize=diversity,10 or -Qd,10 )
      XV's modified diversity algorithm. Tries to choose the
      most diverse set of the original colors.

    Blend-diversity ( example: --quantize=blenddiversity,64 or -Qb,64 )
      Same as diversity, but sometimes makes up new colors by blending.

    Merging ( example: --quantize=merging,4 or -Qg,4 )
      A last-resort method which progressively finds two most similar
      colors in the remaining colormap and averages them together.
      Very slow, thus not recommended.

    Octree ( example: --quantize=octree,4 or -Qo,4 )
      Currently broken, don't use

    NeuQuant ( example: --quantize=neuquant,16 or -Qq,16 )
      A self-balancing Kohonen neural network is used to generate
      an optimal palette for the imageset. Fast and very high quality.
      Especially good with color gradients. Not useful for smallest palettes.

    Load from file ( example: --quantize=test.gif )
      Animmerger will attempt to open the named file, read the
      palette from it and append its colors to the current palette
      (or replace with loaded palette if was the first -Q option).

  Multiple quantization phases can be performed in a sequence.
  For example, -Qb,32 -Qd,16 first reduces with "blend-diversity"
  to 32 colors, then reduces the remaining set with "diversity" to 16 colors.
  It is not an error to reduce to a larger set than 256 colors.
  If you are creating a GIF file and the last explicitly chosen quantization
  method yields more than 256 colors, the colormap will be implicitly reduced
  with a method that picks the 256 most-used colors.
  If necessary, the image will be dithered using a positional dithering method.
  If you are making a GIF file and you do not specify any quantization options
  at all, animmerger will use whatever method GD graphics library happens to use.
  Note that the blending quantization methods are subject to the YUV selection.

DITHERING

  Dithering methods
     The following dithering methods are defined:
      FULL NAME            SHORT NAME    Suitable for animation
       Yliluoma1            y1            Yes (positional)
       Yliluoma2            y2            Yes (positional)
       Yliluoma3            y3            Yes (positional)
       Yliluoma1Iterative   y1i / ky      Yes (positional)
       Floyd-Steinberg      fs / floyd    No (diffuses +4 pixels)
       Jarvis-Judice-Ninke  jjn           No (diffuses +12 pixels)
       Stucki               s             No (diffuses +12 pixels)
       Burkes               b             No (diffuses +7 pixels)
       Sierra-3             s3            No (diffuses +10 pixels)
       Sierra-2             s2            No (diffuses +7 pixels)
       Sierra-2-4A          s24a          No (diffuses +3 pixels)
       Stevenson-Arce       sa            No (diffuses +12 pixels)
       Atkinson             a             No (diffuses +6 pixels, though only 75%)
     To set the dithering method, use the --dithmethod or -D option.
     Examples:
       -Dy1i or --dithmethod=ky (default)
       -Dfloyd-steinberg
       -Ds24a,y2 --dr=2 --dc=4 --dm 8x8

  Dithering matrix size
     You can use an uneven ratio such as 8x2 to produce images
     that are displayed on a device where pixels are not square.
     The values should be powers of two, but it is not required.
     A non-poweroftwo dimension will produce uneven dithering.
     The third dimension, time, can be specified in order to
     use temporal dithering, which will appear as flickering.
     For example, 2x2x2 will use a 2x2 matrix plus 2 frames of
     flickering to produce the average color. By default, temporal
     dithering is done from the LSB of the color error, so as to minimize
     the flicker with cost to spatial accuracy. By specifying a negative time
     value, such as 2x2x-2, it will be done from the MSB, causing much more
     prominent flickering, while improving the spatial accuracy.

  Dithering combine control (--dithcombine)
     The contrast is specified as a sliding scale where
       0 means that no combinations are loaded.
       1 represents the average luma difference between
         two successive colors in luma-sorted palette,
       2 represents the maximum luma difference between two
         two successive colors in luma-sorted palette,
       3 represents the maximum luma coverage of the
         palette, in practice allowing all combinations.
     In general, a higher number will produce more ugly dithering
     and will slow down the dithering algorithm a great deal too,
     so animmerger tries to choose a reasonable (low) default value.
     If you have lots of time and you're rendering a high-resolution
     picture, you can try 3. Otherwise, less than 1.3 is a safe bet.
     Note that a low value of dithcount can make this option useless.

     --dithcombine takes up to three parameters:
         <float>
            Contrast, as described above.
         <combinationlimit>
            Maximum number of colors to combine.
            This value defaults to DithCount, but it may be lower.
            Lower values are faster. It must be at least 1.
         <changeslimit>
            Maximum number of _different_ colors to combine.
            For example, depth 16 & changes 2 means that up to 16 colors
            are mixed, but the list can contain only 2 distinct colors.
            If you specify a negative value, it means that identical colors
            are not mixed together at all; all candidate components are distinct.
            It is the fastest option, though not best quality.
     Examples:
       --dithcombine 2,4,2
          Select all combinations of up to 4 palette colors where:
            - The difference between dimmest and brightest colors in the mix
              is equal or less than 100% of the maximum difference between
              consecutive elements in the luma-sorted palette
            - Only 2 distinct palette indices may occur in the mix
       --dithcombine 3,16,-1
          Select all combinations of up to 16 palette colors where:
            - All palette indices are distinct (same index does not appear twice)
            - No restrictions on how bright&dim colors are mixed together
       --dithcombine 0
          No precalculated mixes. For Yliluoma1 and Yliluoma3 dithers,
          this means that no dithering is done at all. For Yliluoma1Improved
          and Yliluoma2, this is the fastest possible option.

Ordered dithering method differences:

  Yliluoma1
     Completely reliant on --dithcombine to provide
     the selection of mix candidates.
     Ignores the --ditherror parameter.
     Ignores the --dithcount parameter (which still controls the defaults
                                        to --dithcombine though)
     Fastest. Depending on --dithcombine, quality may be good or bad.
  Yliluoma1Iterative
     Can be improved with --dithcombine, but does not depend on it at all.
     The only dither that uses --ditherror parameter.
     Fast. Quality adequate in most cases.
  Yliluoma2
     Can be improved with --dithcombine.
     Ignores the --ditherror parameter.
     Slow.
  Yliluoma3
     Only uses color combinations of 1 or 2 items.
     Ignores the --ditherror parameter.
     Slow.

COLOR TRANSFORMATION FUNCTION

  The option --transform can be used to transform the image's color.

  The following identifiers are defined for the function:
    r,g,b   Input color (0..255)
    frameno Frame number (0..n)
    x,y     Screen coordinates (x,y)

  Note that when animmerger counts color, it
  will pass bogus coordinates to the x,y values.
  The output value is expected to be in range 0..255, though not required.
  For a description of the accepted function syntax, see:
         http://iki.fi/warp/FunctionParser/

  Examples:
    --transform 'r=g=b=(r*0.299+g*0.587+b*0.114)'
        Renders grayscale rather than color.
    --transform 'r=0x80+(r/2)'
        Makes image considerably redder.
    --transform 'r=128+127*sin(frameno*.1+x/40+y/90)' \
    --transform 'g=128+127*cos(frameno*.1+x/40+y/90)' \
    --transform 'b=128+127*sin(frameno*.1+x/40+y/90+20)'
        Will make the screen cycle in colors.

  Note that rendering with a transformation function is much
  slower than rendering without it.

COLOR COMPARE METHODS

  For dithering purposes, animmerger has to compare colors
  and decide out of many options which combination represents
  the desired color best.

  The comparison algorithm can be selected from the following choices:

    default   = 0    = RGB                 e.g. --deltae=0 or --deltae=rgb
    CIE76     = 76   = CIE76 Delta E       e.g. --deltae or --deltae=76
    CIE94     = 94   = CIE94 Delta E       e.g. --deltae=94 or --deltae=cie94
    CIEDE2000 = 2000 = CIEDE2000 Delta E   e.g. --deltae=2000
    CMC              = CMC l:c Delta E     e.g. --deltae=cmc
    BFD              = BFD l:c Delta E     e.g. --deltae=bfd
    user-defined  (see below)

  When a CIE method is selected, colors are compared in the CIE L*a*b* colorspace.
  Animmerger converts RGB values into CIE using an Adobe D65 illuminant profile or
  a close equivalent.

  Performance:
     RGB and CIE76 are simple euclidean differences.
       Because animmerger will calculate the CIE L*a*b* value
       for each color regardless of whether you use RGB or not,
       there is no speed difference between these two.
     CIE94 includes more mathematics than RGB or CIE74.
     CMC   is complex, and not always very good.
     CIEDE2000 includes very complicated mathematics,
               and can be expected to be very slow.
     BFD   is very complex.

  It is also possible to use a homebrew color comparison formula.
  Examples:
    --deltae='(R1-R2)^2 + (G1-G2)^2 + (B1-B2)^2'
      This is equivalent to --deltae=RGB, though --deltae=RGB is faster.
      Note that it is not necessary to take the square root of the result,
      because animmerger only cares about whether a deltae value is larger
      or smaller than another, not about its exact value.
    --deltae='(L1-L2)^2 + (a1-a2)^2 + (b1-b2)^2'
      This is equivalent to --deltae=CIE76, though --deltae=CIE76 is faster.
    --deltae='abs(luma1-luma2)'
      This simply compares luminosity and disregards any color information.
    --deltae='hypot(a1-a2, b1-b2)'
      This simply compares chroma and disregards luminance.
  Variables supported in the color comparison formula:
    R1,G1,B1,A1     -- RGB+alpha value (0..1 range)
    L1,a1,b1,C1,h1  -- L*a*b* and L*C*h[ab] values (unspecified range)
                       Note that h is indicated in radians, not degrees
    luma1           -- Equivalent to R1*.299 + G1*.587 + B1*.114
    And the same for color 2 (replace 1 with 2)
    gamma           -- Configured gamma correction rate
  Functions supported in the color comparison formula:
    Standard fparser functions such as cos,atan2,asinh,log10
    g(x) is equivalent to x^gamma and ug(x) is equivalent to x^(1/gamma).

GIF VERSUS PNG AND WHAT ANIMMERGER CREATES
  GIF is capable of paletted images of 256 colors or less.
  PNG is capable of paletted images, as well as truecolor images.

  GIF selection  Quantization  Saves in format            Dithering used
  --auto         -Q was used   Animations=GIF, other=PNG  For GIF, unless disabled
  --auto         -Q NOT used   Always PNG                 Never
  --never        -Q was used   Always paletted PNG        Yes, unless disabled
  --never        -Q NOT used   Always trueclor PNG        Never
  --always       -Q was used   Always GIF                 Yes, unless disabled
  --always       -Q not used   Always GIF                 Never

TIPS

Converting a GIF animation into individual frame files:
   gifsicle -U -E animation.gif
   animmerger <...> animation.gif.*

To create images with multiple methods in succession,
you can use the multimode option. For example,
    --method average,last,mostused, or -pa,l,m
creates three images, corresponding to that if
you ran animmerger with -pa, -pl, -pm options
in succession. Note that all modes share the same
other parameters (firstlast, looplength).
The benefit in doing this is that the image alignment
phase needs only be done once.

Different combinations of pixel methods require different
amounts of memory. Use the -v option to see how much memory
is required per pixel when using different options.
animmerger always strives to choose the smallest pixel
implementation that provides all of the requested features.

When creating animations of video game content, please take
all necessary steps to ensure that background stays fixed
while characters move. Parallax animation is bad; If possible,
please fix all background layers so that they scroll at even
rate.

10. Copying

animmerger has been written by Joel Yliluoma, a.k.a. Bisqwit,
and is distributed under the terms of the General Public License (GPL).

11. Requirements

GNU make and C++ compiler is required to recompile the source code.
libgd is also required.

12. See also

13. Downloading

The official home page of animmerger is at http://iki.fi/bisqwit/source/animmerger.html.
Check there for new versions.

Additionally, the most recent source code (bleeding edge) for animmerger can also be downloaded by cloning the Git repository by:

Generated from progdesc.php (last updated: Tue, 31 Jul 2012 21:58:08 +0000)
with docmaker.php (last updated: Tue, 31 Jul 2012 21:58:08 +0000)
at Tue, 31 Jul 2012 21:58:08 +0000