Sprite sheet generator

Sprite sheet generator

Postby bzt » 01 May 2022, 09:45

Hi,

I've created a FOSS tool to generate sprite sheets (optionally from multiple image files), maybe it's going to be useful to you too.

https://gitlab.com/bztsrc/sprsheet

It is called sprsheet because I primarily wrote it to mass convert existing LPC assets to make them LPC Revised compatible, however there's nothing LPC-specific hardcoded in it. The sheet definition is read from a plain simple CSV file, which means it is fully configurable and can work with any sprite sheet layout.

If you don't want to write these CSV files by hand, then I've also provided a small web helper tool. Replace guidelines.png with your desired sprite sheet format, and you're good to go. With this tool, you can intuitively create the CSV files, using drag'n'drop (but if you prefer Excel, gnumeric or your favourite text editor, that works too).

CSV generator webtool

Licensed under MIT, in the hope that it will be useful.

The code is written in ANSI C and dependency-free, meaning it should compile on any POSIX-compliant systems as-is without any trouble (just run make), but I've also provided pre-compiled portable executables for Linux and Windows (no .so/.dll required, no installation necessary, just download and use).

Cheers,
bzt

Edit: renamed repo, updated links.
Last edited by bzt on 01 Jun 2022, 10:46, edited 1 time in total.
User avatar
bzt
 
Posts: 332
Joined: 23 May 2021, 21:46

Re: Sprite sheet generator

Postby bzt » 12 May 2022, 21:20

Hi,

I've updated the tool, it just got a lot more useful.

Up until now you could describe areas on the source images and paste that on the destination sheet. With this update, you can now describe a series of operations on that area before it's pasted:
  • apply alpha blending when pasting or replace area on destination sprite sheet
  • rotate clockwise or counter clockwise 90 degrees
  • flip horizontally or vertically
  • resize to double
You can of course concatenate these operators, for example, you can select an area, rotate it clockwise, then flip it vertically. With the alpha blending feature you can now construct a final sheet from multiple layers as well.

Hope it's going to be useful to you!

Cheers,
bzt
User avatar
bzt
 
Posts: 332
Joined: 23 May 2021, 21:46

Re: Sprite sheet generator

Postby bzt » 15 May 2022, 19:23

More more goodies!!!

  • Force colors: you can make the output to match the colors of another image file (using the smallest sRGB distance, like make all similar brown colors to be a specific one)
  • Replace colors: in the parameter image file, first row is the "to" colors, others are the "from" colors (like replace a complete green gradient with a complete brown gradient)
  • Color variations: de-colorize and add palette variations to the output (to be used with the "recolor" feature described here)
  • Now the saved output is a lot smaller and more faster to decode (using the same indexing trick as for example https://tinypng.com/)
With all these new palette features in place, I can now convert LPC assets using this tool only, without even touching GIMP! (GIMP is slow, difficult to use, not automatable, and can't save alpha channel into indexed PNGs *.)

Cheers,
bzt

ps: * - did you know that PNG palettes can't store alpha channel at all? You'd need another, special "tRNS" chunk for that, and that's what GIMP lacks (or at least I wasn't able to figure out how to enable this).
User avatar
bzt
 
Posts: 332
Joined: 23 May 2021, 21:46

Re: Sprite sheet generator

Postby deca9 » 16 May 2022, 13:14

Hi, I'm trying to understand what your project does.

The key words "sprite sheets" and "generate" caught my attention but I'm not really sure if your tool does it in the way I expect.

There are examples of .csv files but you don't provide one example with input and output, in order to figure out what your project exactly does.

There is one image, but I'm not sure if it's an input or an output, or anything else (like some expected standard where you expect someone to put pieces of elements in a sheet).

Your .csv files is want I would like as an output for a sprite/tiles sheet generator. I'm looking for a tool to take as input a list of sprites/tiles like this https://opengameart.org/content/deep-space-ships and puts everything in one sigle sheet, and generates me the coordinates of every sprite or tile from the sheet in ASCII.

I've started to use these ships in a mini-shmup demo http://decapode314.free.fr/games/shmup_ds/shmup_ds.html you can see that there are about 50 ships each in its own file. I'm a beginner with html5's canvas and I would like to try to see if I get better results if I put all these 50 sprites in one single sheet. Every image has a different width and heigth, this is why I would like a tool to generate the coordinates from the result sheet.

Is it something I can do with this tool? If not, is there another tool I could use?

> Just download, no dependencies, no install, portable executables.
Then compile for 32bits, it will be even more portable :) :p
(I don't mind to run make, it's just a comment because you claim that your binary is portable, so I expected it is, but it's not for 32bit OS)

I did a quick check in Gimp, it seems that if you convert to indexed colors, the values in the palette are RGB (not RGBA), but you can still have one transparent value, just like in GIF. This kind of png was made to replace GIF in the past, when gif was still patented and that it was an issue.

You can even make a dithering of transparency when you convert to indexed, and the result is good.

Why is it an issue for you? If you want full alpha value ranges, just don't use indexed, and use plain RGBA, if you want indexed just to reduce the number of colors, so that your program can find some specific values, you can also do it without indexed.

If you want a "suckless" image file format, just take the old P7 and compress it with lzma. You will get something really suckless, you will even be surprised how you will get something with far smaller file size, at no complexity cost!

SDL2 users could also use a .bmp compressed with lzma, and they will get something better than a PNG. If your project is 100M in size for the assets, you will get something like 60M or 70M in size after.

Modzilla could also provide an alternative for .PNG which is just something like a .bmp or a Netpbm compressed with lzma. This would help reducing band-width on a website for people that care about it.
deca9
 
Posts: 18
Joined: 16 May 2022, 01:22

Re: Sprite sheet generator

Postby bzt » 17 May 2022, 12:03

And finally, a little teaser, because I wasn't converting those sprite sheets for nothing ;-) Now I have enough input data to make a screenshot of the sprite generator!

Image

Even with this limited set (less than 100 sheets in total), the number of possible combinations are astronomical. There are male and female sprites, each in 9 different color variations, etc. etc. etc. If anybody interested, the sheets are CC-BY-SA-4.0 licensed, and available here.

Advantages over LPC:
  • Standardized, compatible and compact layout
  • Standardized head and hands positions for all base body types
  • Multiple color variations within the same image
  • Additional animations to LPC: push, carry, climb
  • Portraits!

Known issues:
  • Some (less than 5) assets lacks proper push and carry animations (because I'm a programmer, not a pixel artist)
  • Except for the base body types, no asset supports running and jumping (no matter what people on OGA say, those simply aren't exists in LPC)
  • The slash animation in down and right direction is left handed... (a known LPC issue)
Bonus generator features: sheet dependencies (for example the dress is only shown if female body is chosen), layers are fully customizable, multiple non-human bases (for example there's a spider base too with 6 color variations and optional stripes in 2 different colors). It saves in PNG files, results are usable in any engine. The generator itself is GPL licensed, btw.

Cheers,
bzt
User avatar
bzt
 
Posts: 332
Joined: 23 May 2021, 21:46

Re: Sprite sheet generator

Postby bzt » 17 May 2022, 19:42

deca9 {l Wrote}:There are examples of .csv files but you don't provide one example with input and output, in order to figure out what your project exactly does.
Inputs for example could be LPC assets (they are in various formats, if you're lucky then they have a so called "Universal" sheet). Output examples are here.

But remember, these are just examples, any input image can be used and any output layout can be produced with this tool.

deca9 {l Wrote}:There is one image, but I'm not sure if it's an input or an output, or anything else (like some expected standard where you expect someone to put pieces of elements in a sheet).
Let's go with something else. It's a guideline to help you create the CSV files. You can replace it with your sheet layout, and it is only needed by the web helper. The lpcsheet tool does not need it.

deca9 {l Wrote}:Your .csv files is want I would like as an output for a sprite/tiles sheet generator.
Interesting. I want a sheet generator to produce sheets :-) But no worries, the web helper outputs CSV files. It is a single index.html file, you can download it to your computer and run it locally in your browser. It has absolutely no dependencies (no jQuery, no cdn nothing).

deca9 {l Wrote}:I'm looking for a tool to take as input a list of sprites/tiles like this https://opengameart.org/content/deep-space-ships and puts everything in one sigle sheet, and generates me the coordinates of every sprite or tile from the sheet in ASCII.
Use the web helper to generate a text file with the coordinates. Then use the lpcsheet command line tool to create sheet images of any number of source images using those coordinates.

The difference between a sprite atlas generator and lpcsheet is, that an arbitrary atlas generator takes the images and places them in the way it seems fit. Different images result in different output layout. This tool on the other hand makes sure of it, that a certain frame of a certain animation is always positioned at the same offsets on the output, no matter the inputs.

deca9 {l Wrote}:Is it something I can do with this tool?
Definitely! I've designed it just for that: lots of input images in various formats, but I need a single sheet instead.

deca9 {l Wrote}:> Just download, no dependencies, no install, portable executables.
Then compile for 32bits, it will be even more portable :) :p
(I don't mind to run make, it's just a comment because you claim that your binary is portable, so I expected it is, but it's not for 32bit OS)
You misunderstood. The source is portable (compiles under Linux, Win, 32 bit, 64 bit etc.), but the phrase "portable executable" means no installation required. Just download and use.

deca9 {l Wrote}:I did a quick check in Gimp, it seems that if you convert to indexed colors, the values in the palette are RGB (not RGBA)
Yes, that's my problem. GIMP can't do that, but luckily lpcsheet outputs RGBA palettes (or with the -t flag, RGBA pixels).

deca9 {l Wrote}:Why is it an issue for you? If you want full alpha value ranges, just don't use indexed, and use plain RGBA
Because indexed images are a LOT smaller and faster to load. But don't you worry, as I've said, the output is indexed and contains alpha.

deca9 {l Wrote}:If you want a "suckless" image file format, just take the old P7 and compress it with lzma.
Can I open those files with GIMP or with Photoshop? I've choosen PNG because of its wide adoptation, it has the best chance to get interoperability among pixel artists and developers using lots of different tools.

You can always convert PNG images to your engine's specific format as the last step, but it is not advised to use custom format for collaboration.

Cheers,
bzt
User avatar
bzt
 
Posts: 332
Joined: 23 May 2021, 21:46

Re: Sprite sheet generator

Postby deca9 » 18 May 2022, 01:04

bzt {l Wrote}:
deca9 {l Wrote}:If you want a "suckless" image file format, just take the old P7 and compress it with lzma.

Can I open those files with GIMP or with Photoshop? I've choosen PNG because of its wide adoptation, it has the best chance to get interoperability among pixel artists and developers using lots of different tools.


We can open compressed files with Gimp since a while, .xcf.gz is even the default file format for Gimp.
lzma not yet, but .gz and .bz2 are OK.

Also it's only a final step at the end, in order to provide something small for the user/player.
deca9
 
Posts: 18
Joined: 16 May 2022, 01:22

Re: Sprite sheet generator

Postby deca9 » 18 May 2022, 02:02

Hi,
I'm looking for a tool that is able to create a sprite sheet from 50 .png images.
All these 50 .png images have different dimensions.
I would like to get the coordinates of every sprites in an ASCII format.

I've found 2 websites that do this.
Javascript is too slow to input 50 input sprites, but it's able to manage something like 20 sprites, so I packed the 50 ships in 3 sheets.
Another problem with these 2 online sprite sheet generators is that they don't put all the sprites on the sheet in a very clever way, only a very basic way. They just align the sprites on a line, and on the next line they just align on a line that is the highest sprite from the previous line.

See the result here:
http://decapode314.free.fr/tmp/spritesheet1.png
http://decapode314.free.fr/tmp/spritesheet2.png
http://decapode314.free.fr/tmp/spritesheet3.png
http://decapode314.free.fr/tmp/spritesheet4.png

The output for the coordinates is fine:
http://decapode314.free.fr/tmp/spritesheet1.json
http://decapode314.free.fr/tmp/spritesheet2.json
http://decapode314.free.fr/tmp/spritesheet3.json
http://decapode314.free.fr/tmp/spritesheet4.json

But there is a lot of lost space in these sprite-sheets.

Do you know if there is an open-source tool to make the same thing?
deca9
 
Posts: 18
Joined: 16 May 2022, 01:22

Re: Sprite sheet generator

Postby bzt » 18 May 2022, 07:04

Ah, ok, now I see why are you troubled. You've confused two generally different concepts. Granted, both stores multiple sprites within a single image file, but their purpose is entirely different.

The most important feature of sprite sheets that you can overlay them. What's essential is that every sprite has a fixed place on the image, therefore it usually has lots of empty spaces, mostly for padding. Here's an example sprite sheet:
Image
(This sprites' positions match the sprites on the chain armour sheet for example.)

Sprite atlases on the other hand are all about compactness, to minimize the empty spaces, therefore they are not layerable. Here's an example sprite atlas of the same sprite sheet:

Image
(This does not match the corresponding chain armour atlas at all, so not interchangeable.)

Creating atlases can be easy if you're lazy and happy with a "good enough" solution, but it is extremely difficult to get it right. Look up rectangle packing algorithms. I believe one of the most commonly used solution is Sean Barrett's stb_rect_pack.h, which is not necessarily the best, but a compromise between complexity and ease of use (this does not care about images, it just receives a bunch of rectangle sizes and an atlas size, and returns x,y coordinates where those rectangles should be placed on the atlas. It is entirely up to you to copy the images using the returned coordinates, so this works with SDL_Image, libgd, Allegro, SFML, whatever).

The FlareRPG game (from where I get those examples above) uses this tool btw. (Quite complex, there's a C++ tool and also some python scripts to parameterize it correctly, and it outputs in a custom format text file.)

If you aim at something simpler and insist on having JSON output, then here's a tutorial for a complete packing tool with example C code using SDL. This uses a very naive algorithm for packing, but in return you can easily adapt it to other languages or libraries (in most cases, this is a typical good enough solution). On the bright side, this tool generates JSON out-of-the-box and exactly in a way you want it to.

Finally, my own solution is spr.c. Again, not the best solution, just one that's good enough for me. It does quite some heuristics and de-duplicates as well. It uses a modified best fit algorithm.

Hope this helps,
bzt
User avatar
bzt
 
Posts: 332
Joined: 23 May 2021, 21:46

Re: Sprite sheet generator

Postby deca9 » 23 May 2022, 16:37

Hi, thanks a lot to take time to reply and give me these links!

I'm trying to use stb_rect_pack, as you can see below. Currently I only get a segfault.
Maybe someone knows how to use it?

{l Code}: {l Select All Code}
#define STB_RECT_PACK_IMPLEMENTATION
#include "stb_rect_pack.h"

int main()
{
  struct stbrp_context context =
    {
       .width = 800,
       .height = 600,
       /*
       int init_mode;
       int heuristic;
       */
       .num_nodes = 3,
    };

  int allow_out_of_mem = 1;
  stbrp_setup_allow_out_of_mem(&context, allow_out_of_mem);

  int heuristic = STBRP_HEURISTIC_Skyline_BL_sortHeight;
  //int heuristic = STBRP_HEURISTIC_Skyline_BF_sortHeight;
  stbrp_setup_heuristic(&context, heuristic);

  int num_rects = 3;
  stbrp_rect rects[] = {
    {
      .id = 0,
      .w = 30, .h = 40,  // input
      .x = 0, .y = 0,    // output
      .was_packed = 0,   // non-zero if valid packing
    },
    {
      .id = 1,
      .w = 20, .h = 30,  // input
      .x = 0, .y = 0,    // output
      .was_packed = 0,   // non-zero if valid packing
    },
    {
      .id = 2,
      .w = 25, .h = 38,  // input
      .x = 0, .y = 0,    // output
      .was_packed = 0,   // non-zero if valid packing
    },
  };

  int r = stbrp_pack_rects(
      &context,
      rects,
      num_rects);

  return 0;
}
deca9
 
Posts: 18
Joined: 16 May 2022, 01:22

Re: Sprite sheet generator

Postby bzt » 24 May 2022, 00:00

deca9 {l Wrote}:Hi, thanks a lot to take time to reply and give me these links!
You're welcome!

deca9 {l Wrote}:I'm trying to use stb_rect_pack, as you can see below. Currently I only get a segfault.
No wonder, you haven't read the documentation on how to use it :-D You haven't called the "init" function and you haven't provided a node list to store the free areas.

deca9 {l Wrote}:Maybe someone knows how to use it?
Yep, here is a working solution. It saves the atlas info in JSON format into the PNG file (so you won't lost it for sure). The tool can list sprites in the atlas (spratlas -l), but examples on how to extract that JSON also provided for multiple libraries: libpng, lodepng, stb_image, choose whichever you prefer (other libs should work too as long as they can return comments in PNGs).

Cheers,
bzt
User avatar
bzt
 
Posts: 332
Joined: 23 May 2021, 21:46

Re: Sprite sheet generator

Postby deca9 » 24 May 2022, 00:21

Hi, I finally got a minimal example running:
{l Code}: {l Select All Code}
#include <stdio.h>
#define STB_RECT_PACK_IMPLEMENTATION
#include "stb_rect_pack.h"

int main()
{
  int width = 400;
  int height = 300;

  int num_nodes = width;

  struct stbrp_context context =
    {
       .width = width,
       .height = height,
       .init_mode = STBRP__INIT_skyline,
       .num_nodes = num_nodes,
    };

  int allow_out_of_mem = 1;
  stbrp_setup_allow_out_of_mem(&context, allow_out_of_mem);

  int heuristic = STBRP_HEURISTIC_Skyline_BL_sortHeight;
  //int heuristic = STBRP_HEURISTIC_Skyline_BF_sortHeight;
  stbrp_setup_heuristic(&context, heuristic);

  stbrp_node nodes[num_nodes];
  stbrp_init_target(&context, width, height, nodes, num_nodes);

  int num_rects = 4;
  stbrp_rect rects[] = {
    {
      .id = 0,
      .w = 60, .h = 80,  // input
      .x = 0, .y = 0,    // output
      .was_packed = 0,   // non-zero if valid packing
    },
    {
      .id = 1,
      .w = 40, .h = 60,  // input
      .x = 0, .y = 0,    // output
      .was_packed = 0,   // non-zero if valid packing
    },
    {
      .id = 2,
      .w = 35, .h = 48,  // input
      .x = 0, .y = 0,    // output
      .was_packed = 0,   // non-zero if valid packing
    },
    {
      .id = 3,
      .w = 45, .h = 58,  // input
      .x = 0, .y = 0,    // output
      .was_packed = 0,   // non-zero if valid packing
    },
  };

  int r = stbrp_pack_rects(
      &context,
      rects,
      num_rects);

  printf("rectangles successfully packed: %s\n", r ? "yes" : "no");

  int i;
  for (i = 0; i < num_rects; i++) {
    printf("[%d]: x:%d y:%d w:%d h:%d\n", i,
          rects[i].x, rects[i].y,
          rects[i].w, rects[i].h);
  }

  return 0;
}

I will try now with the real sprites to see if the result is better than the javascript tool.
deca9
 
Posts: 18
Joined: 16 May 2022, 01:22

Re: Sprite sheet generator

Postby deca9 » 24 May 2022, 00:59

Hi, I finally got something running at the same time, but your post goes far more far than that, it look like a complete cli tool for the task!
Thanks a lot, I didn't expected that much :)
And I see that you uploaded it just 1 hour ago :) this is really kind from you :)
I thought a free cli tool already exists for that, if not I bet a lot of people will be happy with it here and at OGA!
From one link you gave on WP they say that even for a website it gives better result to pack images in a single sheet, than a lot of separated images. Reading this makes me stay motivated for my mini-game to try to pack all the 50 ships from Commander@OGA.
deca9
 
Posts: 18
Joined: 16 May 2022, 01:22

Who is online

Users browsing this forum: No registered users and 1 guest