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. FIRSTNMOST 2.1.7. LASTNMOST 2.1.8. 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. Caveats 3.1. Parallax motion 3.2. Flashes, fog and other transparent layers 4. Usage 5. Copying 6. Requirements 7. See also 8. Downloading |
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…)
![]() |
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.
What follows below, is a list of the pixel methods supported
by animmerger,
The
|
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).
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
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
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
Most common of first 4:
Most common of first 10:
Most common of first 16:
First uncommon:
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
Most common of last 10:
Last uncommon:
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
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
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)
Exteriors, i.e. content outside the "current" viewport of the animation
are colored as in the "most used" 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.
Blur length 1:
Blur length 4:
Blur length 20:
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
-l
option
to set the loop length in frames.
30 frames (94895 bytes):
10 frames (66738 bytes):
4 frames (40372 bytes):
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).
-l
option to set the loop length in frames.
30 frames (file size depends on selected palette size):
10 frames:
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.
Loop length 30 frames, blur length 20:
Loop length 30 frames, blur length 20, with YUV calculations:
Loop length 10 frames, blur length 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
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 | |
Average | Static | Yes | Yes | 16 | |
Tinyaverage | Static | Yes | No | 8 | |
ActionAvg | Static | Yes | Yes | As MostUsed | |
ChangeLog | Animated (movie) | If blur | For blur | 12…16 + 8*number of content changes | Animations |
LoopingLog | Animated (loop) | If blur | For 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.
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. | |
![]() |
![]() |
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; |
# 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.
Example:
TODO: Add successful Super Metroid animation
TODO: Add example of how image alignment suffers when using the power bomb in Super Metroid
animmerger v1.4.1 - Copyright (C) 2010 Joel Yliluoma (http://iki.fi/bisqwit/) Usage: animmerger [<options>] <imagefile> [<...>] Merges animation frames together with motion shifting. --help, -h This help --mask, -m <defs> Define a mask, see instructions below --method, -p <mode> Select pixel type, see below --bgmethod, -b <mode> Select pixel type for alignment tests --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 --version, -V Displays version information --yuv, -y Sets YUV mode for average-color calculations Affects AVERAGE, ACTIONAVG and LOOPINGAVG. --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. --gif, -g Save GIF frames instead of PNG frames --verbose, -v Increase verbosity animmerger will always output PNG files into the current working directory, with the filename pattern tile-####.png where #### is a sequential number beginning from 0000. 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. 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) 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 immobile while characters move. Parallax animation is bad; If possible, please fix all background layers so that they scroll at even rate.
Additionally, the most recent source code (bleeding edge) for animmerger can also be downloaded by cloning the Git repository by:
git clone git://bisqwit.iki.fi/animmerger.git
git checkout origin/release -b release
git checkout origin/master -b master
Generated from
progdesc.php (last updated: Wed, 18 Aug 2010 01:09:14 +0300)
with docmaker.php (last updated: Wed, 18 Aug 2010 01:09:13 +0300)
at Wed, 18 Aug 2010 01:09:14 +0300