Tuesday 15 November 2011

Damn you Android pixels!

In a week my progress is this: I can now draw pixels. <tired Monthy Python cheering>Yay</ tired Monthy Python cheering>... Naturally I could draw pixels from square one(arf arf) but the problem is that any attempt to draw into a Bitmap and get a 1:1 relation between the bitmap pixels and the physical screen pixels seemed to be beyond me. OK, I did not work for a week before solving this, it was more like 3 hours but as I had to leave the problem unsolved for a couple of days to get on with life, it kind of felt like a week.

So how hard can it be? Well it was a bit trickier than expected. What I wanted was to load a PNG containing some 16x16 tiles of mountains, lakes, plains and so on and to draw a map. But Android is very helpful and re-sizes stuff automatically to fit your screen size and your screen density. This is normally very helpful unless you want to do the exact thing I wanted. That is: complete control on the pixel level. So after a lot of googling I found that the following 2 things fixed my problems:
  1. In the manifest XML file, add the following:

    <supports-screens android:anyDensity="true" />

    (this is a really bad idea for most apps as it turns off a lot of automagic "under the hood" stuff that is designed to make your life simpler in most cases. Read the anyDensity documentation here)
  2. When loading the PNG (even from the "drawable-nodpi" folder) the Bitmap was scaled after load was completed(24x24 instead of the expected 16x16). To correct this I had to pass in an extra parameter to the BitmapFactory:

    BitmapFactory.Options opts = new BitmapFactory.Options();
    opts.inScaled = false;
    Bitmap tiles = BitmapFactory.decodeResource(res, R.raw.tiles, opts);
And so now my pixels are ending up where they're supposed to.

And before I create the "Pixel re-size" functionality, everything will be reeeeally small(this image on a recent phone is reeeeally small as the DPI is a lot higher than on a laptop/desktop computer).

1 comment: