A spritesheet packer for games.
This simple utility will pack images into a larger spritesheet, suitable for game development. It uses the 'maxrects' algorithm as described here.
(ql:quickload :patchwork)
A spritesheet is created from a collection of smaller files. To tell this library which files you would like packed, you can do this one of three ways:
- Automatically scan for files in the current directory, and add them to a spritesheet:
(make-atlas-from-directory "/home/user/sprites"
:out-file #p"/tmp/spritesheet.png"
:width 1024
:height 1024)
- Automatically scan for files in the current directory recursively, and add them to a spritesheet:
(make-atlas-from-directory "/home/user/sprites"
:recursive t
:out-file #p"/tmp/spritesheet.png"
:width 1024
:height 1024)
- Manually specify the files to be added to a spritesheet:
To manually add files, you must construct a file-spec
, which is an association
list mapping absolute pathnames of files to their unique ID. The unique ID is
what will be written to the resulting metadata file. As an example, you can
create a list such as:
'((#p"/path/to/file1.png" . "bomb")
(#p"/path/to/file2.png" . "missile"))
Once you have a file-spec
, you can pass it to MAKE-ATLAS
as follows:
(make-atlas file-spec
:out-file #p"/tmp/spritesheet.png"
:width 1024
:height 1024)
The above three methods will write an image to disk, as well as a metadata file of the same name with the extension ".spec". The metadata file is a list of property lists, specifying the ID's of the images and their positions and sizes in the spritesheet. An example metadata file looks like the following:
((:ID "ship01" :X 1316 :Y 1060 :W 140 :H 140)
(:ID "ship02" :X 3770 :Y 1944 :W 268 :H 178)
(:ID "ship03" :X 3502 :Y 1944 :W 268 :H 185)
(:ID "ship04" :X 2823 :Y 3089 :W 266 :H 118)
(:ID "ship05" :X 3234 :Y 2134 :W 268 :H 164)
(:ID "ship06" :X 1751 :Y 3849 :W 268 :H 198)
(:ID "ship07" :X 1584 :Y 932 :W 140 :H 88)
(:ID "ship08" :X 3089 :Y 3129 :W 263 :H 168)
(:ID "ship09" :X 3868 :Y 2886 :W 192 :H 184)
(:ID "ship10" :X 3600 :Y 2453 :W 147 :H 136)
(:ID "ship11" :X 3868 :Y 2598 :W 211 :H 146)
(:ID "ship12" :X 2823 :Y 3207 :W 260 :H 194)
(:ID "ship13" :X 1189 :Y 1577 :W 130 :H 128)
(:ID "ship14" :X 3868 :Y 2744 :W 197 :H 142)
(:ID "ship15" :X 1436 :Y 2113 :W 183 :H 110)
(:ID "ship16" :X 3083 :Y 3297 :W 137 :H 137))
For the first two automatic generation methods above, IDs are automatically generated based on the filename without the extension, and the path relative to the root directory starting point. This disambiguates files of the same name located in different directories.
You can also supply the :normalize
argument to make-atlas
or
make-atlas-from-directory
to map pixels to the [0..1] domain when writing the
resulting metadata file. This is useful for use with OpenGL texture coordinates.
You can optionally supply the :flip-y
argument to make-atlas
or
make-atlas-from-directory
to flip the Y axis when writing coordinates to the
metadata file. This is useful when using OpenGL which assumes the origin is at
the bottom-left.
Lastly, you can also supply the :padding
argument to make-atlas
or
make-atlas-from-directory
to specify the amount of padding in pixels
separating each sprite in the atlas.
You can perform the reverse operation, and reconstruct the original individual sprite images given a spritesheet's image and metadata files.
(unpack-atlas #p"/tmp/spritesheet.png"
:out-path #p"/tmp/sprites/")
This will unpack all the sprites in /tmp/spritesheet.png
to the directory
/tmp/sprites/
, assuming the metadata file /tmp/spritesheet.spec
exists.
Copyright © 2017 Michael Fiano.
Licensed under the MIT License.