Overview
Skip forward to the Download section for instructions on downloading wad2image if you don't want or need to read any documentation.
wad2image is a command line utility that converts maps in Doom WAD files to images. There are many options to control how the images are created. wad2image can select multiple maps from multiple WAD files and create images for those maps. wad2image can create animated GIFs to illustrate the differences between revisions of a map. It's Python based and open source (GPLv2+ license).
This document has a few Examples to illustrate how wad2image works. For a more thorough explanation the Syntax and Concepts sections follow.
wad2image has a github page.
Requirements
wad2image was tested with Python 2.x and 3.x on Linux and Windows. The Pillow version of the python imaging library is needed. One Linux this can be accomplished by installing a package such as python2-pillow. On other operating systems pip can be used:
pip install Pillow
Optionally ImageMagick can be installed in order to show the images using the display and animate commands as demonstrated in the Examples.
The latest version of wad2image is here. All versions starting with the latest first:
Install
Once the wad2image has been downloaded as per the Download section expand the downloaded ZIP in your preferred location. If Python is properly configured it should be possible to run wad2image.py in the bin directory from the command line. This can be done either by having the bin directory in your path (... is command line arguments documented elsewhere):
wad2image.py ...
which works on Windows just by being in the bin directory. Alternatively the path to wad2image can be specified:
/opt/wad2image/bin/wad2image.py ...
If the above fails because Python is not found it may be that Python is not installed correctly. One workaround is to specify the Python executable, which may require a path, first:
python wad2image.py ...
Optionally on operating systems that support symlinks a symlink can be created to wad2image.py so that wad2image can be run without either specifying the path to it, or editing the PATH environment variable. Assuming wad2image is installed to /opt/wad2image as per the example above and that the symlinks are to be created in /usr/local/bin:
cd /usr/local/bin ln -s /opt/wad2image/bin/wad2image.py ln -s wad2image.py w2i
Once the above is done wad2image may be invoked either with wad2image.py or w2i.
Optionally on operating systems that do not support symlinks wad2image.py can be copied to a directory in the path combined with setting environment variable WAD2IMAGE_HOME with the install directory of wad2image. Assuming wadimage is installed to c:\wad2image and c:\bin is in the path:
copy c:\wad2image\bin\wad2image.py c:\bin set WAD2IMAGE_HOME=c:\wad2image
See this page for a discussion of the Python command line on Windows.
These examples should illustrate how to use wad2image, but also read the Concepts section for a deeper understanding.
The doom2.wad is used for many of these images, but Freedoom WAD files can be used as well.
Note that some of the examples contain special characters such as # or ! in their arguments. In this case the special characters are escaped with \ so that the example command is ready to be copied into a Linux Bash shell. The quoting may be different on Windows.
These examples often use the short version of command such as -n instead of --map-numbers. The Syntax section, which can be seen by -h has information that relates them.
Short (single letter) command line arguments can be combined. For example, example 4 has -v -c omg which could be combined as -vc omg.
The examples are:
This is a simple example to get things started. Generate one image for one map.
With Yadex style (-c yadex argument) create an image for MAP03 (-n 3 argument) for the IWAD found on the default WAD search path (doom2.wad in this case). The map rendered is taken from the IWAD used (iwad positional argument):
wad2image.py -c yadex -n 3 iwad
This is a more complex example with many arbitrary arguments. The end result is strange and arbitrary, but I wanted to illustrate how flexible wad2image is.
Verbosely (-v argument) using Yadex style (-c yadex argument) for an IWAD at a particular location (--iwad /tmp/doom2.wad argument) create images for maps MAP01 through MAP03 as well as MAP05 (-n 1-3,5 argument). Also flip it (--flip argument about the vertical axis and then rotate it 10 degrees clockwise (--rotation 10 argument). Add grid lines that are 200 apart in Doom space (--grid-step 200 argument). Set the margin to 10 pixels (-m 10 argument), but also shift everything down and to the right by 10 pixels (-x 10 and -y 10 arguments) so that the map touches the bottom and right side of the image. Lighten the background a bit from the default of black to a dark grey (-b #505050 argument). Circle (--circle-outline argument) each thing (-j sprite-and-circle argument) with a red circle (--circle-color #ff0000 argument) where each circle is 50% bigger than the thing it surrounds (--circle-scale 1.5 argument). Make lines around secret sectors extra thick (-l sector_secret=! argument). The default bang (!) thickness is 3, so make it even thicker (--thickness-bang 6 argument). Once the images have been created show them (-s argument). Rather than processing maps in the IWAD itself (iwad argument in the previous example) instead process maps in /tmp/mywad.wad. Only MAP03 is shown below.
wad2image.py -v -c yadex --iwad /tmp/doom2.wad -n 1-3,5 --flip --rotation 10 --grid-step 200 -m 10 -x 10 -y 10 -b \#505050 --circle-outline -j sprite-and-circle --circle-color \#ff0000 --circle-scale 1.5 -l sector_secret=\! --thickness-bang 6 -s /tmp/mywad.wad
This example shows creating an animated GIF in order to illustrate difference between two revisions of Freedoom's MAP05. In this case a tree was moved as well as a few lines.
Verbosely (-v argument) using Yadex style (-c yadex argument) for an IWAD at a particular location (--iwad freedoom2.wad argument) create GIFs when duplicate images are encountered (-d gif argument). Once the GIF is created it should be shown (-s argument) using a utility that can handle animation (--show-cmd animate). The two revisions of MAP05 are passed as positional arguments (/tmp/map05-old.wad and /tmp/map05-new.wad arguments).
wad2image.py -v -c yadex --iwad freedoom2.wad -d gif -s --show-cmd animate /tmp/map05-old.wad /tmp/map05-new.wad
This is similar to the previous example except instead of animation colors are used to illustrate the diff. The saturation of the original image (--colors-saturation argument) is reduced so that the diff colors stand out. Subtractions (exists in the old revision, but not the new) are red and additions (exists in the new revision, but not the old) are blue.
wad2image.py -v -c yadex --iwad freedoom2.wad -d colors -s --show-cmd animate /tmp/map05-old.wad /tmp/map05-new.wad
Example 5 - Color Coded Diff High Contrast
This is similar to the previous example except a high contrast black or white image is used. Pixels are either black or white depending on whether they exceed a configurable threshold (--colors-threshold argument). There are various ways that color coded images can be configured. See the colors prefixed arguments.
wad2image.py -v -c yadex --iwad freedoom2.wad -d colors --colors-images bw -s --show-cmd animate /tmp/map05-old.wad /tmp/map05-new.wad
Example 6 - Omgifol Style With Circles
This example shows creating an image using omg configuration instead of yadex configuration. It immitates the drawmaps.py demo from the Omgifol project.
Verbosely (-v argument) using Omgifol style (-c omg argument) for an IWAD at a particular location (--iwad freedoom2.wad argument) create an image for map MAP05 (-n 5 argument). Randomly but consistently use colored circles (-j circle argument). Display images once they are created (-s argument). The map rendered is taken from the IWAD used (iwad positional argument).
wad2image.py -v -c omg --iwad freedoom2.wad -n 5 -j circle -s iwad
wad2image.py in the bin directory is run on the command line. It takes WAD files as input and creates images in the images subdirectory by default. See the Examples section for examples.
usage: wad2image.py [-h] [-b BACKGROUND_COLOR] [-a CIRCLE_ALPHA] [--circle-color CIRCLE_COLOR] [--circle-outline] [-r CIRCLE_RADIUS] [--circle-scale CIRCLE_SCALE] [--colors-color-list COLORS_COLOR_LIST] [--colors-images {bw,first,last}] [--colors-on-color COLORS_ON_COLOR] [--colors-off-color COLORS_OFF_COLOR] [--colors-saturation COLORS_SATURATION] [--colors-threshold COLORS_THRESHOLD] [-c CONF] [--conf-spath CONF_SPATH] [-d {colors,colors-keep,gif,gif-keep,index,overwrite}] [--diff-only] [--flip] [-f FORMAT] [--game GAME] [--get-top-dir] [--gif-duration GIF_DURATION] [--gif-loop GIF_LOOP] [--grid-color GRID_COLOR] [-g GRID_STEP] [--height HEIGHT] [-i IWAD] [-k] [-l LINE_COLORS] [--line-default-color LINE_DEFAULT_COLOR] [-n MAP_NUMBERS] [-p MAP_PATTERN] [-m MARGIN] [-x OFFSET_X] [-y OFFSET_Y] [-o OUT_DIR] [--random-seed RANDOM_SEED] [--rotation ROTATION] [--scale SCALE] [-s] [--show-cmd SHOW_CMD] [--show-inter] [--spectre-color SPECTRE_COLOR] [-t THICKNESS] [--thickness-bang THICKNESS_BANG] [--thing-scale THING_SCALE] [-j {circle,none,sprite,sprite-and-circle,sprite-or-circle}] [-v] [--wad-spath WAD_SPATH] [-w WIDTH] [--yadex-spath YADEX_SPATH] WAD [WAD ...] Convert maps in Doom WAD files to images. positional arguments: WAD WADs to create images from. optional arguments: -h, --help show this help message and exit -b BACKGROUND_COLOR, --background-color BACKGROUND_COLOR Background color. Names or #RRGGBB. (default: black) -a CIRCLE_ALPHA, --circle-alpha CIRCLE_ALPHA The alpha (opacity) of circles. 0 (transparent) - 255 (opaque). (default: 255) --circle-color CIRCLE_COLOR Circle color. Names or #RRGGBB. "random" colors by default. (default: random) --circle-outline Use an outline for circles. (default: False) -r CIRCLE_RADIUS, --circle-radius CIRCLE_RADIUS Radius of circles in Doom space. 0 to use sprite radius. (default: 0) --circle-scale CIRCLE_SCALE Scale circles this amount. (default: 1.0) --colors-color-list COLORS_COLOR_LIST Colors to use for color diff images. Comma separated. (default: red,lime,blue) --colors-images {bw,first,last} Strategy for the images to generate. (default: last) --colors-on-color COLORS_ON_COLOR For BW mode the color for pixels that are on. (default: white) --colors-off-color COLORS_OFF_COLOR For BW mode the color for pixels that are off. (default: black) --colors-saturation COLORS_SATURATION Saturation color images this amount. (default: 0.4) --colors-threshold COLORS_THRESHOLD Pixels above this threshold are considered to be on. (default: 30) -c CONF, --conf CONF Configuration to use. (default: []) --conf-spath CONF_SPATH Search path to search for configuration files. Comma separated. (default: {top-dir}/conf,.) -d {colors,colors-keep,gif,gif-keep,index,overwrite}, --dup-images {colors,colors-keep,gif,gif-keep,index,overwrite} Strategy for duplicate image files (same map in multiple WADs). (default: index) --diff-only Only generate diff images. (default: False) --flip Flip the image by mirroring vertexes across the vertical axis. (default: False) -f FORMAT, --format FORMAT Image format to create. (default: PNG) --game GAME Game to use when reading Yadex files. (default: doom2) --get-top-dir Get the top directory ({top-dir} variable) and exit. (default: False) --gif-duration GIF_DURATION How long to display each frame. (default: 500) --gif-loop GIF_LOOP Number of times to loop. 0 for unlimited. (default: 0) --grid-color GRID_COLOR The color of grid lines. (default: grey) -g GRID_STEP, --grid-step GRID_STEP The distance between each grid line in Doom space. (default: None) --height HEIGHT The height of the images created. (default: None) -i IWAD, --iwad IWAD IWAD to load sprites from. Path or comma separated. (default: *doom2.wad,*doom.wad,*doom1.wad) -k, --keep-identical-images If the exact same image is created then keep both. (default: False) -l LINE_COLORS, --line-colors LINE_COLORS Comma separated list of line type colors. (default: ['two_sided=grey']) --line-default-color LINE_DEFAULT_COLOR The default line color. (default: white) -n MAP_NUMBERS, --map-numbers MAP_NUMBERS Comma separated list of allowed map numbers and rages. (default: None) -p MAP_PATTERN, --map-pattern MAP_PATTERN Only include maps that match. Case sensitive. (default: *) -m MARGIN, --margin MARGIN Margin of the image. (default: 4) -x OFFSET_X, --offset-x OFFSET_X Offset added to X pixel coordinate. (default: 0) -y OFFSET_Y, --offset-y OFFSET_Y Offset added to Y pixel coordinate. (default: 0) -o OUT_DIR, --out-dir OUT_DIR Directory to create output/image files. (default: {top-dir}/images) --random-seed RANDOM_SEED Seed for random number generation. (default: 0) --rotation ROTATION Rotate image this amount clockwise in degrees. (default: 0.0) --scale SCALE Scale image this amount. (default: None) -s, --show Show the images created with external command --show- cmd. (default: False) --show-cmd SHOW_CMD Command used by --show to show images. (default: display) --show-inter Show intermediate image files. (default: False) --spectre-color SPECTRE_COLOR The color of spectres. Names or #RRGGBB. (default: grey) -t THICKNESS, --thickness THICKNESS How thick the lines are. (default: 1) --thickness-bang THICKNESS_BANG Thickness of line types suffixed with '!' in --line- colors. (default: 3) --thing-scale THING_SCALE Scale things this amount. (default: 1.0) -j {circle,none,sprite,sprite-and-circle,sprite-or-circle}, --thing-type {circle,none,sprite,sprite-and-circle,sprite-or-circle} The type of thing. (default: sprite-or-circle) -v, --verbose Verbose output. (default: False) --wad-spath WAD_SPATH WAD search path. Comma separated. (default: {top- dir}/wads,.,/usr/share/doom,/usr/local/doom) -w WIDTH, --width WIDTH The width of the images created. (default: None) --yadex-spath YADEX_SPATH Search path to search for Yadex files. (default: {top- dir}/yadex,.,/usr/share/yadex/1.7.0)
The following sections explain various concepts in wad2image. This may be helpful if it's still not obvious after reading the Examples section. The sections after this point are in alphabetical order.
Image Diffs
wad2image has the ability to illustrate differences between revisions of the same map in multiple WAD files. The difference can be illustrated with animated GIFs or by color coded images. For example, let's say two WAD files are passed to wad2image both of which contain MAP05 and MAP05 is requested. The result is multiple map05.png files. As wad2image creates images in the output directory (images by default) it uses one of six strategies to handle duplicate image files. The strategies are:
The strategy is specified with the -d --dup-images argument which defaults to index. For GIFs it's possible to control the duration of each frame (--gif-duration argument) as well as the number of times the animation loops (--gif-loop argument). For color coded diff images it's possible to control the color saturation (--colors-saturation argument) as well as the colors used.
Scaling
Doom has it's own coordinate system with it's own unit of measure which this document sometimes refers to as "Doom space". One unit in Doom space becomes a certain number of pixels, which is the over all scale, or --scale argument. Normally you don't have to specify --scale directly - wad2image figures it out. By default images have a width of 1024 (-w argument) and a margin of 4 pixels (-m argument). The scale is calculated so that the entire maps fits given those parameters.
In addition to the overall scale it's possible to change the relative scale of things. The --thing-scale argument can used to change the size of things without changing the size of lines or sectors. The default value of 1.0 renders things with the correct size. On top of thing scaling is scaling that only applies to things that are rendered as circles, which is controlled by --circle-scale. The default value of 1.0 renders sprite things and circle things the same size. Values larger than 1.0, such as 1.5, can boost the size of circles as seen in example 2.
Search Paths
Search paths (-spath suffixed arguments) are used to search for files. For example, in the case of searching for WAD files --wad-spath is searched, which is {top-dir}/wads,.,/usr/share/doom,/usr/local/doom by default. Each directory in the comma separated list of path is searched until the requested file is found.
The requested file my itself be a comma separate list of file matching patterns, or globs, collectively referred to as patterns. For example, for IWAD files the default value for --iwad is *doom2.wad,*doom.wad,*doom1.wad. For a given directory in the search path each pattern in the list is tried. The shortest matching filename is used. So in the case of there being both not-doom2.wad and doom2.wad the later would be preferred.
If the requested filename contains a slash (/) or backslash (\) it's assumed that the requested filename is a path. In the case of a path the path is used directly and the search path is not searched.
The the default searching behavior does not find the desired file the file can be copied to one of the directories under the top directory. For example, the preferred IWAD can be copied to the wads directory. Or --iwad can be point to the exact IWAD to be used.
Specifying Maps
By default an image is created for every map in every WAD file specified, but it is possible to specify a subset of the maps two different ways.
File globbing like pattern matching can be done on the map name with the -p --map-pattern argument. For example, specifying MAP*7 would match maps MAP07, MAP17 and MAP27. Pattern MAP* could be used to match Doom 2 maps and E* could be used to match Doom 1 maps (barring more exotic non-standard names). Exact names without a * can be specified as well in which case only that exact map will be matched. Map patterns are case sensitive, and most map names are upper case.
The map number can be specified as well. The map number is the digits in the map name without any leading zeros. For example, for MAP05 the map number is 5. For E2M7 the map number is 27. Map numbers are specified with the -n --map-numbers argument comma separated. Map numbers can be specified as ranges where each endpoint is optional. For example -n -5,10,13,15-17,20- matches maps 5 and earlier, maps 10 and 13, maps 15 through 17 and maps 20 and later. Maps that have no digits in their name (which is non-standard) have a map number of zero.
If both map patterns and map numbers are specified then only maps that match both are processed.