Texture atlas tool

Started by
11 comments, last by Kylotan 7 years, 6 months ago
I tried Blender method and after 1 hour found that I really need drag and drop tool with layout export facilities (like UV for each image) + command line support to integrate it to my pipeline.

Yea it's a bit hard, no one will blame you for not sticking to it, if you do have time spend some learning Blender; it's a great tool for general art.

If someone could suggest better free tool, I would appreciate it.

Unfortunately it doesn't get any better than TexturePacker, I doubt you will find something of this level for free, because software of this level takes a long time to make.

Search along the lines of "Sprite sheet generator" and such to find tools, don't include "free" in the search as it will just mostly provide trail software.

It would be nice of someone could try the sprite sheet tools and provide some feedback on the best ones.

Advertisement
I once wrote a script to build a texture atlas from a set of images. The details can be found here: http://www.gamedev.net/blog/863/entry-2261127-automatically-generating-sprites-for-a-space-shooter/.

The script used the binpacking library pack the sprites tightly, and then used gm and imagemagick to composite the sprites into the final image.

It’s trivial to wrap the binpacker into a simple command line program:
// binpack.js
var readline   = require('readline');
var binpacking = require('binpacking');

var boxes = [];

readline.createInterface({
	input:  process.stdin,
})
.on('line', (line) => {
	// transform lines from stdin into boxes
	var arr = /^(\d+)\s+(\d+)\s+(.+?)$/.exec(line);
	if ( arr ) {
		boxes.push({
			w:   +arr[1],
			h:   +arr[2],
			tag:  arr[3],
		});
	}
	else {
		process.stderr.write("Failed to process: '"+line+"'\n");
	}
})
.on('close', () => {
	// sort boxes, largest to smallest widths then heights.
	boxes.sort((a,b) => {
		if ( a.w < b.w )  return  1;
		if ( a.w > b.w )  return -1;
		if ( a.h < b.h )  return  1;
		if ( a.h > b.h )  return -1;
		return 0;
	});

	// bin-pack!
	var packer = new binpacking.GrowingPacker;
	packer.fit(boxes);

	// output final atlas size and sprite locations
	process.stdout.write(packer.root.w+'\t'+packer.root.h+'\n');
	boxes.forEach((box) => {
		var f = box.fit;
		process.stdout.write([f.x, f.y, f.w, f.h, box.tag].join('\t')+'\n');
	});
});
Then try it out:
> # generate a set of twenty random images:
> $set = 1..20 |% {
  $rand = new-object Random;
  $gen = {$rand.Next(64,256);};
} {
  "$(&$gen) $(&$gen) path/to/image$_.png"
}

> # width height and image
> $set
127 221 path/to/image1.png
166 238 path/to/image2.png
204 69 path/to/image3.png
197 83 path/to/image4.png
100 115 path/to/image5.png
236 192 path/to/image6.png
97 139 path/to/image7.png
122 74 path/to/image8.png
127 168 path/to/image9.png
203 94 path/to/image10.png
80 212 path/to/image11.png
168 161 path/to/image12.png
64 79 path/to/image13.png
253 179 path/to/image14.png
129 253 path/to/image15.png
180 114 path/to/image16.png
250 208 path/to/image17.png
223 110 path/to/image18.png
247 102 path/to/image19.png
243 225 path/to/image20.png

> # (assuming script has npm dependencies installed)
> # feed into the script
> $set | node binpack.js
1001	848
0	0	253	179	path/to/image14.png
0	179	253	208	path/to/image17.png
253	0	247	387	path/to/image19.png
253	102	247	285	path/to/image20.png
500	0	236	387	path/to/image6.png
500	192	236	195	path/to/image18.png
500	302	236	85	path/to/image3.png
0	387	736	94	path/to/image10.png
203	387	533	94	path/to/image4.png
0	481	736	114	path/to/image16.png
736	0	168	595	path/to/image12.png
736	161	168	434	path/to/image2.png
0	595	904	253	path/to/image15.png
129	595	775	253	path/to/image1.png
736	399	168	196	path/to/image9.png
400	387	336	83	path/to/image8.png
256	595	648	221	path/to/image5.png
904	0	97	848	path/to/image7.png
904	139	97	709	path/to/image11.png
904	351	97	497	path/to/image13.png
The output here could then be fed into imagemagick to render the atlas.

But of course you're using the 'require' function, which means you need to be running it in some other context like Node.js, because Javascript doesn't have any proper module or package system. I could go on a rant about how broken the Javascript ecosystem is here, but I'll save it...

This topic is closed to new replies.

Advertisement