I had a little bit of time today to implement something i should have implemented a long time ago. It’s an image packer which will takes a bunch of images and pack them tightly into a single output image. I first wanted to come up with my own method but eventually decided that i was to lazy to mess with kd-trees and searched all mighty Google. I found that great article by Blackpawn at http://www.blackpawn.com/texts/lightmaps/default.html which i’ve read a couple of years ago already when i wanted to code my own lightmapper, a recurring theme of mine…
I extended the basic packing functionality with padding and border duplication so you can savely use that for pixel perfect drawing in OpenGL without seams or other nasty artifacts. The code is pure Java and uses the Java 2D API so it should be pretty portable. The basic operation of the little thing:
- put images with names in
- get output image plus the info where each original image is located in the atlas
Here’s 100 generated images packed into a single 512×512 atlas with padding and border duplication (which are not very obvious given the nature of the generated images :p).
Here’s how you’d use it:
// create the packer and insert a couple of images
ImagePacker packer = new ImagePacker( 512, 512, 1, true );
packer.insertImage( "first image", ImageIO.read( new File( "numero1.png" ) ) );
packer.insertImage( "second image", ImageIO.read( new File( "numero2.png" ) ) );
// Get the texture atlas image and the
// map holding image name/rectangle pairs
BufferedImage atlas = packer.getImage();
Map<String, Rectangle> rects = packer.getRects();
// get the position of the image "first image" in the
// texture atlas.
Rectangle rect = rects.get( "first image" );
I plan adding JSON export to the packer which will be the basis for a neat new TextureAtlas class in libgdx.
You can find the source code over at the libgdx SVN repository. It’s a single self-contained class, steal it!
Fun trivia: the image packer is a heuristic approach to an instance of the set of packing problems. The problem at hand is actually NP-complete and closely related to… Tetris. Yes, Alexey Pajitnov, the guy who invented Tetris was originally working on a very similar packing problem. One of the side products was Tetris the game. Here’s a fun read discussing the complexity of Tetris.