Spreet is a command-line tool that creates a spritesheet (aka texture atlas) from a directory of SVG images. You'll need this when you create MapLibre or Mapbox vector web maps, where cartographic stylesheets require that icons be loaded from a spritesheet.
Compared to other tools for creating spritesheets from SVGs, Spreet:
- outputs smaller spritesheets (both fewer pixels and fewer bytes)
- is a self-contained ~2.2 MB binary
- is faster
Spreet (also spreit, spret, sprit) is the Scots word for a sprite, the fairy-like creature from Western folklore.
You can install Spreet using Homebrew, cargo install
, by downloading pre-built binaries, or by building from source.
If you use Homebrew on MacOS or Linux you can install Spreet from the command-line:
brew install flother/taps/spreet
(You can review the code run by the formula before you install.)
Rust's cargo install
command lets you install a binary crate locally. You can install the latest published version of Spreet with:
cargo install spreet
Pre-built binaries are provided for MacOS, Linux, and Windows. The MacOS and Linux binaries are built for both Intel and ARM CPUs. Visit the releases page to download the latest version of Spreet.
You'll need a recent version of the Rust toolchain (try Rustup if you don't have it already). With that, you can check out this repository:
git clone https://github.com/flother/spreet
cd spreet
And then build a release:
cargo build --release
Once finished, the built binary will be available as ./target/release/spreet
.
When you're making your own style for a vector map, you'll have icons that you want to appear on top of the map. Symbols for roads or icons for hospitals and schools — that sort of thing. You'll have a directory of SVGs (like the icons
directory in the osm-bright-gl-style) and you'll want to convert them into a single raster image (like the spritesheet from osm-bright-gl-style).
Let's say you have a directory of SVGs named icons
and you want to create a spritesheet named my_style.png
. Run Spreet like this:
spreet icons my_style
Spreet will also create an index file named my_style.json
that contains a description of the dimensions and location of each image contained in the spritesheet.
If you want to create a "retina" version of the spritesheet named my_style@2x.png
, use the --retina
option:
spreet --retina icons my_style@2x
You might have multiple copies of the same icon — for example, you might use the same "open book" icon for both libraries (library.svg
) and bookshops (bookshop.svg
). If you pass the --unique
option, Spreet will include only the icon once in the spritesheet, but reference it twice from the index file. This helps reduce the size of your spritesheet.
spreet --retina --unique icons my_style@2x
By default the JSON index file is pretty-printed, but you can minify it with the --minify-index-file
option:
spreet --retina --unique --minify-index-file icons my_style@2x
When you create a spritesheet for your production environment, use --unique --minify-index-file
for best results.
$ spreet --help
Create a spritesheet from a set of SVG images
Usage: spreet [OPTIONS] <INPUT> <OUTPUT>
Arguments:
<INPUT> A directory of SVGs to include in the spritesheet
<OUTPUT> Name of the file in which to save the spritesheet
Options:
-r, --ratio <RATIO> Set the output pixel ratio [default: 1]
--retina Set the pixel ratio to 2 (equivalent to `--ratio=2`)
--unique Store only unique images in the spritesheet, and map them to multiple names
--recursive Include images in sub-directories
-m, --minify-index-file Remove whitespace from the JSON index file
--sdf Output a spritesheet using a signed distance field for each sprite
-h, --help Print help
-V, --version Print version
The main purpose of Spreet is to be command-line tool, but you can also use it as a library in your own Rust code. To add Spreet as a dependency, include this in your Cargo.toml
:
spreet = { version = "0.11.0", default-features = false }
To learn how to build your spritesheets programmatically, see the Spreet crate docs on docs.rs and have a look at the spritesheet tests.
To compare the output from spritezero and Spreet, benchmarks are run against SVG sprite sets from four diverse map styles: osm-bright-gl-style, openstreetmap-americana, mapbox-gl-styles (basic), and mapbox-gl-whaam-style. Unique, retina spritesheets are output (--unique --retina
), and Spreet also uses --minify-index-file
(spritezero doesn't have that option).
Map style | Spritezero pixels | Spreet pixels | Change |
---|---|---|---|
osm-bright-gl-style | 208,810 | 130,048 | -38% |
openstreetmap-americana | 577,548 | 389,640 | -33% |
mapbox-gl-styles (basic) | 271,488 | 258,064 | -5% |
mapbox-gl-whaam-style] | 90,944 | 59,136 | -35% |
Map style | Spritezero file size | Spreet file size | Change |
---|---|---|---|
osm-bright-gl-style | 43,860 | 24,588 | -44% |
openstreetmap-americana | 140,401 | 78,617 | -44% |
mapbox-gl-styles (basic) | 76,383 | 30,771 | -60% |
mapbox-gl-whaam-style | 17,342 | 5,037 | -71% |
Map style | Spritezero file size | Spreet file size | Change |
---|---|---|---|
osm-bright-gl-style | 10,695 | 6,957 | -35% |
openstreetmap-americana | 20,142 | 13,574 | -33% |
mapbox-gl-styles (basic) | 17,013 | 11,101 | -35% |
mapbox-gl-whaam-style | 553 | 372 | -33% |