1

in my app I scale an image dynamically to 50% of its original size. When scaled it shows some sort of tiling (look image below). There are square parts of the image that ware brighter than neighbouring tiles that should have the same colour. It is barely noticeable but it is which is not good enough for my app. The size of the square depends on the scaling factor. So at a factor of 75% size the tiles a smaller.

Example:

enter image description here

My drawing code (is called in onDraw of my custom View):

private void drawImage(Bitmap bitmap, float scaling,
        Canvas canvas, float offset)
{

    Matrix p = new Matrix();
    Matrix m = new Matrix();
    Matrix y = new Matrix();
    Matrix o = new Matrix();

    p.setTranslate(-bitmap.getWidth() / 2, -bitmap.getHeight() / 2);

    // translation to views center (minus half height of image
    // so that the bottom of the picture is in the views center.
    y.setTranslate(getWidth() / 2, getHeight() / 2);
    // offset translation.
    o.setTranslate(offset, 0);

    m.setScale(scaling, scaling);
    m.preConcat(p);
    m.postConcat(y);
    m.postConcat(o);

    // draw image
    canvas.drawBitmap(bitmap, m, null);
}

Does anyone know how to prevent this tiling?

js-
  • 1,632
  • 1
  • 14
  • 18
  • You could try to prescale the bitmap using `Bitmap.createScaledBitmap()` instead of scaling it on the go and see if that helps. – Jave Jan 03 '12 at 10:40
  • 1
    Have you tried `canvas.drawBitmap(bitmap, m, new Paint(Paint.FILTER_BITMAP_FLAG))` as seen [here](http://stackoverflow.com/a/7468636/662732) – fab Jan 03 '12 at 10:42
  • @Jave: Since the images are scaled dynamically between 100% and 50% of its original size prescaling is useless for me. – js- Jan 03 '12 at 10:49
  • @fab: That was a bit of a help. Now you cannot see clear borders between the tiles, but the image still looks a bit dithered. It doubled the drawing time though (from 6ms to 13ms). – js- Jan 03 '12 at 10:51
  • You could try having several images of different sizes, so you don't have to scale as much, i.e. one at 50% and one at 100%, maybe also one at 75% if you have enough memory. Also, try scaling up instead of scaling down, as these artefacts are caused by downsizing. – Jave Jan 03 '12 at 10:55
  • I do not have much memory left. My app uses many images so that I am always struggling to not get OOM exceptions on low memory devices. Scaling images up will cause the images to appear a bit blurry wouldn't it? – js- Jan 03 '12 at 11:06
  • @fab: My colleagues say that using your solution the problem is solved sufficiently. So I would accept your answer if you reposted it as an answer. :) – js- Jan 03 '12 at 11:27

2 Answers2

1

Are you seeing it on a device or also in the emulator? Because on a device some low quality GPUs can introduce a "dithering"-like effect which devices that lack a GPU or the emulator don't produce.

The solution is to pre-scale the image in Photoshop or with the Bitmap API.

P Varga
  • 19,174
  • 12
  • 70
  • 108
  • I am running on an Acer A500 tablet. Since the images are scaled dynamically between 100% and 50% of its original size prescaling is useless for me. – js- Jan 03 '12 at 10:46
1

Have you tried canvas.drawBitmap(bitmap, m, new Paint(Paint.FILTER_BITMAP_FLAG)) as seen here.

Community
  • 1
  • 1
fab
  • 1,839
  • 15
  • 21