Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Loading nine-patch image as a Libgdx Scene2d Button background looks awful

I'm trying to use a Nine Patch as a background for a Libgdx Scene2d UI button. It is loading, buts it is really ugly. I can see the "meta-data" pixels, and its being stretched as if it were just a regular image (the text on the button is "Continue"):

ugly image of a nine-patch button

I'm loading the .9.png files directly into a (libgdx) NinePatchDrawable via a (libgdx) NinePatch like this:

this.dialogButtonUp = new NinePatchDrawable(
   new NinePatch(new Texture(Gdx.files.internal("data/button-round.9.png"))));
this.dialogButtonDown  = new NinePatchDrawable(
   new NinePatch(new Texture(Gdx.files.internal("data/button-round-down.9.png"))));

Then I make a TextButtonStyle that describes the button, and references the two NinePatch drawables:

TextButton.TextButtonStyle buttonStyle = new TextButton.TextButtonStyle();
buttonStyle.font =  aValidFontReally;
buttonStyle.fontColor = Color.BLACK;
buttonStyle.up = this.dialogButtonUp;
buttonStyle.down = this.dialogButtonDown;
buttonStyle.pressedOffsetX = -2;

I'm building the button indirectly, via a Dialog box:

new Dialog( ... ).button("Continue", null, buttonStyle);

I've checked the .9.png files to make sure that:

  • that the asset files were refreshed in Eclipse
  • that the meta-data border pixels are either fully-invisible or fully-visible-black
  • that the Android draw9patch tool can load the images and verify them

Any other suggestions on what to check or change?

like image 549
P.T. Avatar asked Mar 12 '13 07:03

P.T.


1 Answers

Thanks to some pointers from @RodHyde, it looks like the libgdx NinePatch class is designed to accept a "post-processed" nine patch texture (i.e., with separate integer values that describe how to cut the single texture into patches). This "processing" usually happens as a side-effect of packing a ".9.png" file into a TextureAtlas (see https://github.com/libgdx/libgdx/wiki/Texture-packer#ninePatches). A texture atlas is a really good idea (especially when your UI includes a bunch of different texture elements), so this makes sense, but is a bit surprising when developing and trying to get something running.

To work-around this so I can directly include ".9.png" files I wrote this:

private static NinePatch processNinePatchFile(String fname) {
    final Texture t = new Texture(Gdx.files.internal(fname));
    final int width = t.getWidth() - 2;
    final int height = t.getHeight() - 2;
    return new NinePatch(new TextureRegion(t, 1, 1, width, height), 3, 3, 3, 3);
}

This loads the texture, creates a sub-region that trims off the 1-pixel meta-data border, and then just guesses that the nine-patch border elements are 3 pixels wide/tall. (Computing that correctly by mucking about in the texture data seems possible, but not worth the effort -- just put the texture in an atlas in that case.)

like image 128
P.T. Avatar answered Nov 03 '22 09:11

P.T.