Monday, September 23, 2013

LibGDX Tutorial 9: Nine Patch Images

The Android Developers defines 9 Patch at their site http://developer.android.com/reference/android/graphics/NinePatch.html. Basically it is just an image in which the corners do not scale but only the rectangular middle regions. You can see this by looking at the image at the bottom of this page. Nine patch images are important for GUI widgets. Another Androids developers website also describes their tool (Draw 9 Patch). It is the (android dir)/sdk/tools folder.

Starting this tool gives


I have already drawn button1.png. It is just a blue button with slightly rounded corners. You can load any image into this utility and make the black borders where you want the image to scale.


Saving the image from the Draw 9 Patch will save it as .9.png (there are two periods - one before and one after 9).

My directory with the images  (say ImageTest)  contains 2 files - one is normal, other is the 9 patch,

Next I run Texture Packer (see last tutorial). Remember to uncheck the aliases option.

Then you will have four files

The buttons.pack is a text file containing the details of the two images:
From this you can see that button2 is indeed recognized as nine patch. See the split field is added, and the size is 64, 64 (same as button 1) so image will not show the black borders. Thus in the Java code we will refer to it as button2 and not button2.9, etc.

I created a simple Java program to test the nine patch image.

Create the project





Once the projects are imported into Eclipse, we can make changes to the main Java class

MyPatch9Image.java
package com.tutorials.myPatch9Image;

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.NinePatch;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.graphics.g2d.TextureRegion;

public class MyPatch9Image implements ApplicationListener {
    private OrthographicCamera camera;
    private SpriteBatch batch;
    private TextureAtlas buttonsAtlas; //** Holds the entire image **//
    private TextureRegion button1; //** Will Point to button1 (a TextureRegion) **//
    private NinePatch button2; //** Will Point to button2 (a NinePatch) **//
    private BitmapFont font;
       
    @Override
    public void create() {       
       
        camera = new OrthographicCamera();
        camera.setToOrtho(false, 800, 480); //** w/h ratio = 1.66 **//
       
        batch = new SpriteBatch();
        buttonsAtlas = new TextureAtlas("buttons.pack"); //** buttonsAtlas has both buttons **//
        button1 = buttonsAtlas.findRegion("button1"); //** button1 - not 9 patch **//
        button2 = buttonsAtlas.createPatch("button2"); //** button2 - 9 patch **//
        font = new BitmapFont(); //** default font **//
        font.setColor(0, 0, 1, 1); //** blue font **//
        font.setScale(2); //** 2 times size **//
    }

    @Override
    public void dispose() {
        batch.dispose();
        buttonsAtlas.dispose();
        font.dispose();
    }

    @Override
    public void render() {       
        Gdx.gl.glClearColor(1, 1, 1, 1);
        Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
       
       
        batch.setProjectionMatrix(camera.combined);
        batch.begin();
        batch.draw(button1, 50, 0, 100, 100); //** not a nine patch **//
        font.draw(batch, "Not a nine patch", 180, 80);
        button2.draw(batch, 50, 200, 100, 100); //** is a nine patch **//
        font.draw(batch, "Nine patch", 180, 280);
        batch.end();
    }

    @Override
    public void resize(int width, int height) {
    }

    @Override
    public void pause() {
    }

    @Override
    public void resume() {
    }
}


This is the image rendered



2 comments: