What is a 9 patch
A 9 patch is an image which has been divided into a 3×3 grid making 9 patches. These 9 parts can then be used to create a scalable image by repeating/stretching certain patches. This 3×3 grid create 4 corners, 4 walls and a center image. The corner images will not be stretched or repeated and will be placed at the corner once placed in its scaled form. The 4 walls will be placed between each of the corners, the ones placed at the top will be stretched/repeated horizontally and the edge walls will be stretched/repeated vertically. This will make a box in the scaled form. The center image will be stretched both vertically and horizontally to fill the void creating a full scaled image.
Making a 9 patch
In order to make a nine patch you need to indicate where the image needs to be split for both horizontal and vertical points. This is done using the alpha layer and a 1 pixel margin around the image. From left to right on the top 1 pixel margin will be transparent for the first section, then fully opaque for the middle section then transparent for the 3rd section. The same for the right border, from top to bottom transparent for first section, opaque for second and transparent again for third.
Any image can be turned into a 9 patch by simply opening the image adding a 1 pixel border then adding the transparent/opaque markers. Then all you have to do is export/save it as a png with the .9.png suffix. However I recommend using a tool such as this NinePatchEditor from weblookandfeel.com.
Creating a 9 patches in libg gdx using a normal image.
In LibGDX a nine patch is stored in the NinePatch class which takes and image and four integers as arguments. The four integers are used to define the patches of the 9 patch. The first value is the width of the patches on the left. The second value is the width of the patches on the right. The next value is the top and the final value is the bottom. With these four values LibGDX is able to create a 9 patch object. To load a nine patch directly into your application uses the following code.
1 |
NinePatch npimage = new NinePatch(new Texture(Gdx.files.internal("image.png")), 10, 10, 10, 10); |
The above code will open the image.png image and define the 9 patches using the 4 integers. Note: if you use a nine patch image with this method you will be able to see the 1px margin which defines the patches.
Using a 9 patch with the asset manager
Instead of loading the NinePatch image manually by creating the image and setting the patch points, you can use the Asset Manager to load .9.png images. This is the recommended method for loading images as they will be loaded and disposed of by the asset manager. The first thing you will need to do is to pack the image using a texture packer. The Texture packer will pack multiple images into a larger image file which will help reduced memory use. The Texture packer is available from www.aurelienribon.com as well as some other useful tools.
After packing the images for your project into an atlas, add them to your project’s asset folder so you can access them from your app. Now you have the images in your project its time to create an asset manager which will load the images.
1 2 3 4 5 6 7 8 9 10 11 |
public class MyAssetManager { public final AssetManager manager = new AssetManager(); // Textures public final String imagesPack = "images/images.pack"; public void loadImages(){ manager.load(imagesPack, TextureAtlas.class); } } |
The code above creates an AssetManager called MyAssetManager and has a string with the location of the image.pack file. It also has one method called loadImages which will as suspected load the images.
In the class you want to use your 9 patch image in add the following code to add the asset manager
1 2 |
// create the asset manager public MyAssetManager assMan = new MyAssetManager(); |
Now the asset manager is loaded in the class you can use it to load the images.
1 2 3 4 5 6 7 8 |
// load the atlas(which contains your ninepatch) atlas = assMan.manager.get("images/images.pack"); // create a nine patch image (btn_norm is from the filename btn_norm.9.png) NinePatch np = atlas.createPatch("btn_norm"); //create a nine patch drawable ( used in textButtonStyles for buttons ) NinePatchDrawable npn = new NinePatchDrawable(atlas.createPatch("btn_norm")); |
Using a 9 patch on a stage for a button
Now you have a nine patch image in your code you can add it to anything you want. If like me you want to add it to a button you can use the following code.
1 2 3 4 5 6 7 8 9 10 11 12 |
NinePatchDrawable npn = new NinePatchDrawable(atlas.createPatch("btn_norm")); NinePatchDrawable npo = new NinePatchDrawable(atlas.createPatch("btn_over")); NinePatchDrawable npd = new NinePatchDrawable(atlas.createPatch("btn_down")); textButtonStyle = new TextButtonStyle(); textButtonStyle.up = npn; textButtonStyle.down = npd; textButtonStyle.over = npo; textButtonStyle.checked = npd; textButtonStyle.font = parent.assMan.manager.get("font/visitor.fnt", BitmapFont.class); button = new TextButton("Start", textButtonStyle); |
Here we have loaded 3 nine patch images using the asset manager and assigned them to NinePatchDrawable variables. We then create a new TextButtonStyle and set the up, down, over and checked images for the button as well as the font which is also loaded from the asset manager.
Finally we create a new TextButton with teh text Start and the TextButtonStyle we just created.