Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scaling issue on Android - why is picture so clumsy?

I have no 2D graphics and gaming experience. I taught myself by hundreds of mistakes and tens of lost hours. I started with simple Dress Up game. I used Nexus 5x for development where a screen looked OK. When I finished one milestone I tried game on big Lenovo tablet and tiny Samsung Mini phone. It looked horribly.

enter image description here

An original vector PSD file looks perfect, PNG export does not have any issues either. But when I scale the picture it is bumpy. I know it is bitmap. But there is another picture I scale in other place and it looks fine (both pictures are 32 bit):

enter image description here

When I play some game from Google Play they never have scaling issues. How are they implemented? Do they use vectors? Is there some trick?

I put everything into assets folder and though it took 1 MB. I decompiled some apk and they do not have set of variants for each resolution. Though they scale pictures nicely.

Some source code snippets:

protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);

    this.w = w;
    this.h = h;
    canvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
    drawCanvas = new Canvas(canvasBitmap);
}

protected void onDraw(Canvas canvas) {
    if (baseBitmap != null) {
        double scale = Math.min((double) w / (double) figure.getW(), (double) h / (double) figure.getH());
        figure.setScaleRatio(scale);
        int sw = (int) (scale * figure.getW());
        int x = ((w - sw) >> 1);
        figure.setX(x);

        paintDressPart(canvas, figure, figure.getMain());
        if (displayedParts != null) {
            for (DressPart dressPart : figure.getParts()) {
                if (displayedParts.contains(dressPart.getId())) {
                    paintDressPart(canvas, figure, dressPart);
                }
            }
        }
    }
}

private void paintDressPart(Canvas canvas, Figure figure, DressPart part) {
    double scale = figure.getScaleRatio();
    int sh = (int) (scale * part.getH());
    int sw = (int) (scale * part.getW());
    int sdx = (int) (scale * part.getDestX());
    int sdy = (int) (scale * part.getDestY());
    scaledRect.set(figure.getX() + sdx, sdy, figure.getX() + sw + sdx, sh + sdy);
    Rect partRect = part.getRect();
    canvas.drawBitmap(baseBitmap, partRect, scaledRect, canvasPaint);
}

And if you want to see it yourself I preparred complete project on GitHub so you can download it and run it yourself:

https://github.com/literakl/DressUp

Update

Downscaling sucks as well. But thanks to Paavnet's comment I realized that Paint matters. See difference on a picture:

enter image description here

I ran demo app on 3,2" AVD image. The picture 278x786 is scaled to 107x303.

October Update

I rewrote the app to use resource folder instead of assets. Android scales pictures and then I rescale it again. Though it looks better than when I do not use Android resources scaling. Resources scaled picture looks usually better than unscaled nodpi / assets picture.

I found that mdpi works best. I even had xxhdpi pictures and it looked worse than mdpi. I think that even on xxhdpi device! But it may be a trouble of the picture that it was not painted well. Android resource scaling may smooth edges on lines.

like image 932
Leos Literak Avatar asked Sep 04 '16 13:09

Leos Literak


1 Answers

I faced same issue .. that scaling not that smooth .. best standard method

Bitmap resized = Bitmap.createScaledBitmap(yourBitmap, newWidth, newHeight, true);

You can find more optimized size-convertor in web .. but actually best solution I ended with use :

1st. Use Vector SVG resource .. this is 100% working with perfect quality. just be sure that SVG elements are compatible with android ( see : https://developer.android.com/studio/write/vector-asset-studio.html )

pros:

  • best quality
  • efficient size
  • editable easily

cons:

  • not all elements are supported.

Or

2nd. provide high resolution image (one is enough in xxxhdpi )

pros:

  • good quality

cons:

  • might lead to performance issue

I hope that may help,'.

like image 68
Maher Abuthraa Avatar answered Oct 20 '22 10:10

Maher Abuthraa