2 releases

0.1.1 Nov 18, 2021
0.1.0 Oct 2, 2021

#839 in Images

MIT license

31KB
717 lines

Tatlap

A texture atlas packer library/CLI tool.
I know there are a lot of these out there, but I didn't find one that did everything I wanted it to:

  • Trim off transparent borders
  • Remove duplicates
  • Handle non-4-channel images

I also wanted a project to learn Rust with, and making a command-line tool was a perfect candidate.

Examples

Combine three images into a texture atlas:

$ tatlap sprite1.png sprite2.png sprite3.png

You can specify the output name (defaults to out):

$ tatlap --out sprites data/*.png

If you have a lot of images to pack you can put their names in a file:

$ tatlap --file list_of_sprites.txt

Or pass them through standard input:

$ echo 'sprite1.png sprite2.png sprite3.png' | tatlap --stdin

Actually I'm sure sure why I have the --file option anymore, since you could do this instead:

$ tatlap < list_of_sprites.txt

You can also load images from a texture atlas you created previously:

$ tatlap --atlas out newsprite.png

You can also remove duplicate images from the atlas:

$ tatlap *.png --dedup

Output

Tatlap will output an out.txt file, an out.bin file, and several outN.png files where N is the number of channels the image contains.

The .txt output file contains locations of the packed sprites.

For example:

4 459 638 45 37 69 53 192 192
  • 4 - This represent the number of color channels this image has.
  • 459 638 - These are the x and y pixel coordinates where the sprite was packed into the resulting texture atlas
  • 45 37 - This is the dimensions of the sprite after the transparent borders were trimmed off
  • 67 53 - This is how many pixels from the left and top were trimmed off
  • 192 192 - The dimensions of the image before it was trimmed

The .bin output file contains the same data as the .txt output, but contains the values in serialized in a binary file. The first value (bytes per pixel) is a single byte, but the others are 16-bit unsigned integers (in little endian), so each image takes 17 bytes.

How you use the .txt and .bin is up to you; I find the .bin more useful for loading the sprites. Here is an example of how to would load it in C:

FILE* fp = fopen("out.bin");
uint8_t bpp;
fread(&bpp 1, 1, fp);
uint16_t d[8];
fread(&xywh, 2, 8, fp); // Note that this won't work on big-endian systems

// Extract the sprite based on d[0-4]

// Calculate where to draw the sprite centered on `x` and `y`
// x - half uncropped width + cropped offset
int draw_x = x - d[6]/2 + d[4];
int draw_y = y - d[7]/2 + d[5];

Dependencies

~9.5MB
~148K SLoC