4

I'm sorry if this topic has been brought before, but all my searches on the web and google groups did not help me.

I'm currently developing a little game with the Android SDK, and use hi-res bitmaps that I resize accordingly to match the device's resolution (letting the system do it for me is not "crisp" enough).

I use a SurfaceView, on which I paint in one pass a canvas filling the whole surface. The paint uses setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)) to allow masking. Beforehand, I retrieve various bitmaps -- which are resized at initialization with createScaledBitmap() and put in a cache -- and I apply the bitmaps with a paint on this canvas, before drawing this canvas on the SurfaceView.

My problem is, whatever I try, whatever paint settings I use (dithering, antialias, etc..), the resized bitmaps are not antialiased and the drawing present jagged edges. I tried everything. The only little success I had was using inSampleSize to approach the desired scaled size and force a first pass of antialiasing, before invoking createScaledBitmap on the retrieved hi-res bitmap, but it is not beautiful enough. I just can't allow to create multitudes of pre-sized bitmaps for every combination of resolution. What did I miss ?

Thanks a lot in advance

altesseFReDD
  • 121
  • 3
  • 7

3 Answers3

1

First when you load your bitmap you make sure that you don't lose any image quality by settings options to argb_8888:

Options options = new Options();    
options.inScaled = false; 
options.inPreferredConfig = Bitmap.Config.ARGB_8888; 
Bitmap pic = BitmapFactory.decodeResource(getResources(), R.id.pic, options);

When you scale the bitmap turn on the filter:

pic = Bitmap.createScaledBitmap(pic, screenW, screenH, true);

However if one streaches the image too much inevitably it degrades in quality.

When you use paint you can improve quality but lose on speed with turning on ditherig and filtering:

Paint paint = new Paint(); 
paint.setFlags(Paint.DITHER_FLAG);
paint.setFilterBitmap(true);

Finally the entire activity window could be set on argb_4444 instead on argb_8888 (OS < 2.3). You can chage this if you instert this line before setContentView:

getWindow().setFormat(PixelFormat.RGBA_8888); 
Lumis
  • 21,517
  • 8
  • 63
  • 67
  • I'm sorry but I'm doing this already. I can't post a picture here but the result is aliased as hell and I clearly don't understand why, it's as if the resizing provided by Android was very basic, à la MS-Paint. Sizing down my bitmaps with Gimp at the same scale produces beautiful, antialiased bitmaps (note: I'm scaling the bitmaps down, not up, so there's no stretching). – altesseFReDD May 22 '11 at 17:32
  • After closer expection of one of my application I think you are right. Scaling down does not produce good anti-aliased images and I cannot improve it too. You may need to take this up on Google-android support forum. Before you do that you better make a simple but clear example. In my case I am using small preview images, so I can live with this, for now... good luck! – Lumis May 22 '11 at 20:12
  • Ah, thanks, I'm relieved to see I'm not the only one experiencing this. I already took the problem to the android dev google group, but you're right, I need to refine my example. Thanks – altesseFReDD May 23 '11 at 07:39
0

you may clear canvas buffer by youself! such as follows:

canvas.drawColor(Color.TRANSPARENT, android.graphics.PorterDuff.Mode.CLEAR);
Thirumalai murugan
  • 5,698
  • 8
  • 32
  • 54
0

If it comes down to it, you can manually antialias without too much trouble. Just apply a simple lowpass filter (something like an NxN average) to the pixel data before asking the bitmap object to rescale itself.