J4K Tools

While prototyping different ideas for J4K, I’ve written a couple of code generators that some might find useful.

Image Encoding Tool
This tool generates Java code that contains a String-encoded sprite sheet. It generates simple GIF/PNG output for ImageIO, but also includes a slightly more optimal means of encoding strings, especially if you are handling images yourself without BufferedImages.

Below is an input, where our “sprites” folder (in our class-path) contains a series of equal size images. It will compile a color table of all the images, but for the sake of optimization you should try to use the same colors among many sprites.

Keep your total number of colors less than 95 for indexed colors to work.

ImageTool.create(ImageTool.dir("/res/sprites/"));

You can see the output below, which gives us a couple different ways of encoding our data (indexed color, or simple ImageIO string):
http://www.java-gaming.org/?action=pastebin&id=365

You simply copy + paste the generated code (printed to System.out) into your game, and then you can render images like so:

//Filenames are transformed into constants
//e.g. "res/sprites/pirate2_attack.png" --> SPRITE_PIRATE2_ATTACK
g.drawImage(SPRITES[SPRITE_PIRATE2_ATTACK], 
					50, 50,
					null);

Testing a 128x128 opaque sprite sheet, then JShrink -> pack200:
GIF Encoding: 2,875 bytes
Indexed Color Tables: 2,630 bytes

Testing six 11x9 transparent sprites, then JShrink -> pack200:
PNG Encoding: 1,931 bytes
Indexed Color Tables: 1,816 bytes
Without BufferedImages: 1,689 bytes (i.e. for tiled map data)

The files don’t have any dependencies, and each should be self-contained.
ImageTool.java (excuse the messy code)
ImageToolTest.java (test case, shows proper usage)

Here is an example 4K applet template using the resulting output:
T.java

I have another little tool I’ll post about later. If you’ve got any 4K tools of your own, post 'em here. :slight_smile:

I don’t quite understand. So basically it turns your image file (gif/png) into String?

Nice little tool!
I tested with my images from my game Plants 4k Zombies (26 16x16 images) it did compact well, altough it didn’t beat my method by just a little:

mine:
1.846 bytes

yours:
1.873 bytes

but your method definately is faster than what I do.

congrats and thanks for the tool!

With j4k, images are represented as Strings to save space, but it would still take up too much space if we stored the String with all colors as possibilities. So thus we index the colors and make a color table so that in the string, a = blue, b = red, etc. so each pixel only takes one character.

teletubo - what is your technique if you don’t mind sharing?

I use 16 bits to encode one color, one operation, and a counter
9 bits = R,G,B
1 bit = operation (point or rectangle)
6 bits = number N of pionts/rectangles that will use this color

the following N*16 bits store the points/rectangles:

if point, it will store 2 pixels per 16 bits:
4 bits for the x1 coordinate
4 bits for the y1 coordinate
4 bits for the x2 coordinate
4 bits for the y2 coordinate

if a rectangle, it will store one rectangle per 16 bits:
4 bits for the x1 coordinate
4 bits for the y1 coordinate
4 bits for the width
4 bits for the height

the image must be exactly 16x16, and the color 255,0,255 means transparency.

I made my converter to output one framefor each step it took to build a particular image. Each frame means 2 bytes, and a P means the next operation will be points (of that color), and an R rectangles:

http://imageshack.us/a/img22/50/jalapenomanualsteps.png

http://imageshack.us/a/img594/8366/flowemanualsteps.png

http://imageshack.us/a/img854/368/peashootermanualsteps.png

I hoped it would be a great compression method compared to a index color palette and never really had a chance to benchmark it until now, and I must confess I’m a little disappointed to see that the gain is so small :slight_smile:
It was fun to develop it anyway :slight_smile:

@teletubo did you benchmark how big your decompression code is?

Thanks. Sounds neat. :slight_smile:

My indexed colour technique isn’t that fancy, but it compresses well. I’ve tried some other things, like packing images into a 32-bit int, or encoding only non-transparent pixels, or grouping repeating pixels. Although they all result in smaller strings, they don’t compress as well, and require more lines to decode.

I didn’t, but by looking it seems slightly larger.
Anyway for my next 4k games I’ll try both methods to see which one yields better results for the given spritesheet.

I have taken another approach for minimising the byte count for storing and reading sprites… I have converted my PNG Sprite sheet into an “Uncompressed” PNG using deflate mode 0, adding it as a resource in the JAR , then using ImageIO to read it in.

The tool can be found here: http://pastebin.java-gaming.org/19df7886132

I converted your example 4K applet to use this uncompressed PNG: http://pastebin.java-gaming.org/9df78916237 and after jshrink and pack200 it saved a further 8 bytes over your method (but that is noise level so I am not sure that it will win in most/ all circumstances)

I used PNGGauntlet to optimise the PNG before using my tool.

Unmodified example source jarred->jshrink->pack200 : http://kiwi6.com/file/6relfsr330
UncompressedPN example jarred->jshrink->pack200 : http://kiwi6.com/file/kq499tmh28