1

I had an issue lately Android: Rotation of image around the center which was solved by the help of Unconn.

However, it turns out, that the solution - as well as it is working - does have a much worse performance, than the RotateAnimation stuff.

What I have so far: 1) FrameLayout with two ImageViews, on on top of each other 2) SensorEventHandler, which moves the lower view around according to the heading measured. This works acceptable if I use RotateAnimation

I wanted to speed it up and to smooth the animation a bit, but failed dramatically. Here is the current solution: 1) SurfaceView with separate thread, controlling the drawing of the layers 2) Without performing the code below, the thread could reach around 50 fps. 3) With the code below the frame rate goes down to 5ps and less, so it is no longer something very smooth...

Here is the code:

mRadar: Bitmap showing a "radar", loaded from ressource earlier mHeading: The current heading taken from the sensors in degrees mRadarW,mRadarH: Initial width/height of the image, determined on creation

        Matrix m = new Matrix();
        m.setRotate(mHeading, mRadarW/2, mRadarH/2);
        Bitmap rotated_radar = Bitmap.createBitmap(mRadar, 0, 0, mRadarW, mRadarH, m, true);
        canvas.drawBitmap(rotated_radar, (mRadarW - rotated_radar.getWidth())/2, (mRadarH - rotated_radar.getHeight())/2, null);
        canvas.drawBitmap(mRadar, 0, 0, null);

Is the Matrix/drawBitmap stuff known to perform not that good, in fact worse than the RotateAnimation? If there is no chance to use this: What options could you propose? Although the RotateAnimation would work for now, I would need to compose a much more complex image, before I would have to go for RotateAnimation, so I fear, I will loose again with drawBitmap and friends...

Oh, I miss CALayers :)

Community
  • 1
  • 1
decades
  • 827
  • 17
  • 25

1 Answers1

2

This one is very fast:

canvas.save(); //save the position of the canvas
canvas.rotate(angle, X + (ballW / 2), Y + (ballH / 2)); //rotate the canvas
canvas.drawBitmap(ball, X, Y, null); //draw the ball on the rotated canvas
canvas.restore(); //"rotate" the canvas back so that it looks like the ball has rotated   

I use a nice 32-bit png image, hence don't need any filter or anti-alias Paint... what kind of image do you use for this sprite?

Lumis
  • 21,517
  • 8
  • 63
  • 67
  • Ah, good point. 207x207 72 dpi PNG with alpha channel, color-depth "8" (whatever this means). I think the problem I found with your solution was the terrible aliasing effects... Thanks – decades Mar 04 '11 at 00:05
  • With color-depth 8, in order to improve it you need to dither or filter it etc, which requires more proccessing. Lower depth image works well as a background. If you want perfect and fast rendering then you could create an image for each frame and load it into an array and draw one image per certain number of frames. – Lumis Mar 04 '11 at 00:29
  • So, ImageMagick told me, that I have 8 bit for every channel, so I suppose I already have a 32 bit PNG. The information given by the Apple Preview was misleading... – decades Mar 04 '11 at 10:30
  • Cool, man. I gave your code a new try. As I said I had that already, but I wasn't very happy with the image quality. But it is really fast - 30 - 50 fps while drawing two layers. Thanks for the good hint. – decades Mar 04 '11 at 10:48
  • Have you tried to use this Paint paint = new Paint(Paint.DITHER_FLAG); on drawBitmap? I create PNGs in Photoshop 24bit or in Fireworks 32bit. Fireworks is really great to quickly experiment with images and graphic effects. – Lumis Mar 04 '11 at 12:30
  • I tried one 8bit png week ago and it did look bad when rotating. Rotating is always hard on bitmap images because they are made of square pixels. Once when you rotate it is not always certain which square pixel will be placed into which square slot, hence degradation. If you create each frame individually and resize them, then they are optimised by a superior algoritham of a program like Photoshop. – Lumis Mar 04 '11 at 17:59
  • OK, possible. But than you should have a look on how CALayer does this... No aliasing at all, clear shapes, even if it is rotating with high framerate... I'm rather disappointed about what Android is able to produce here (at least using the easy way). – decades Mar 04 '11 at 18:05
  • On the other hand: My iPhone 4 has 330 dpi... Hard to see just one pixel there :) The Android device is a G1, BTW: – decades Mar 04 '11 at 18:15
  • I am now having the same problem, simply canvas.rotate does not have a very fine algorithm to rotate bitmaps! Have you found a good quality solution? I think I'll have to look into creating my own bitmap rotating algorithm and search for possible libraries. I don't need a fast one this would be used only when I want to save a screnn graphics effect to the SD card. – Lumis Apr 24 '11 at 11:47
  • Finally, I found that paint.setFilterBitmap(true); much improves the quality of renedered image. – Lumis Apr 25 '11 at 10:01