Skip to content

Rainbow
Apps

Rainbow
Apps

Avoid pixelated images

Once I finished to develop the board game screen of Numbersion, when I deployed it on my own phone, what a disappointment to see that images were blurring.

By simplicity my images were just the exported image of my mockups on figma, made on a 360x640px screen, so it looks great on phone with the same density of pixels than my mockup. I was confronting of the same problem than the sizing of texture to fit every screens, the density of smarphone's screen does matter.

The problem

The problem of blurriness is really visible when looking rounded corners, numbers on the board and texts on the screen. Numbers were blurring because I chose for this images to put directly the text inside images unlike other part of the screen where the images were exported without texts.

You can really see these problems by clicking on this image:

Pixellated images and font on xxhdpi screenPixellated images and font on xxhdpi screen

My solution

Fix texts

To fix this problem, I decided to use Libgdx freetype with ttf font and generate a font on multiple size.

Let's see an example of how I do it for one size:

public class ScreenUtils {

    private static final int SCREEN_WIDTH = 360;
    private static final int SCREEN_HEIGHT = 640;

    private static boolean isRatioSuperiorToMockup() {
        float currentRatio = Gdx.graphics.getHeight() / Gdx.graphics.getWidth();

        return currentRatio > SCREEN_HEIGHT / SCREEN_WIDTH;
    }

    public static int getFontSize(int fontSize) {
        if (isRatioSuperiorToMockup()) {
            return getFontSizeFromWidth(fontSize);
        }
        return getFontSizeFromHeight(fontSize);
    }

    private static int getFontSizeFromWidth(int fontSize) {
        return (int) (fontSize * Gdx.graphics.getWidth() / SCREEN_WIDTH);
    }

    private static int getFontSizeFromHeight(int fontSize) {
        return (int) (fontSize * Gdx.graphics.getHeight() / SCREEN_HEIGHT);
    }
}
public class FontUtils {

    public static String BIG_FONT_NAME = "BigFont.ttf";

    public static FreetypeFontLoader.FreeTypeFontLoaderParameter getBigFontParameter() {
        FreeTypeFontGenerator.FreeTypeFontParameter parameterBig = new FreeTypeFontGenerator.FreeTypeFontParameter();
        // Define the right font size in function of the density of my screen
        parameterBig.size = ScreenUtils.getFontSize(45);
        parameterBig.magFilter = Texture.TextureFilter.Linear;
        parameterBig.minFilter = Texture.TextureFilter.Linear;

        FreetypeFontLoader.FreeTypeFontLoaderParameter bigFontLoaderParameter = new FreetypeFontLoader.FreeTypeFontLoaderParameter();
        bigFontLoaderParameter.fontParameters = parameterBig;
        bigFontLoaderParameter.fontFileName = "font/LinLibertine_R.ttf";

        return bigFontLoaderParameter;
    }

    public static BitmapFont getBigFont(AssetManager assetManager) {
        return assetManager.get(BIG_FONT_NAME);
    }
}
public interface AssetDescriptors {
    AssetDescriptor<BitmapFont> BIG_FONT = new AssetDescriptor<>(FontUtils.BIG_FONT_NAME, BitmapFont.class, FontUtils.getBigFontParameter());
}
public class NumbersionGame extends Game {

    private AssetManager assetManager;

    @Override
    public void create() {
        this.assetManager = new AssetManager();

        FreeTypeFontGenerator.setMaxTextureSize(FreeTypeFontGenerator.NO_MAXIMUM);
        InternalFileHandleResolver resolver = new InternalFileHandleResolver();
        assetManager.setLoader(FreeTypeFontGenerator.class, new FreeTypeFontGeneratorLoader(resolver));
        assetManager.setLoader(BitmapFont.class, ".ttf", new FreetypeFontLoader(resolver));

        assetManager.load(AssetDescriptors.BIG_FONT);
    }
}

You can see the code: FreeTypeFontGenerator.setMaxTextureSize(FreeTypeFontGenerator.NO_MAXIMUM); and ask yourself why do I need this?

Before using the configuration, I had sometimes some characters which were not generated/were missing. This setting has a default value which can be too small when generating font with big size. So if you have the same problem, you can fix this with this setting.

Fix images

I do not pretend that the solution I used is the best, but for my use case it works great without making the apk heavy. I just chosed to make images about 10 times bigger.

I also made a loading screen to load every pictures in memory, to prevent showing a blank/black screen on which users can ask himself: "What is going on?".

To summarize, the steps are:

  • Load assets and generate the font useful for the loading screen in the create function of the Game
  • Launch the loading screen and load every others textures and generate other fonts
  • Let's get started :)

Final result

An image is more efficient than a long text (do not hesitate to click on the image):

Non pixellated images and font on xxhdpi screenNon pixellated images and font on xxhdpi screen
10-21-2020

Rainbow Apps

Get it on Google Play

© Copyright 2021 Rainbow Apps. All rights reserved.

Rainbow Apps

© Copyright 2021 Rainbow Apps.
All rights reserved.

Get Numbersion app

Get it on Google Play

Follow me